一、在springmvc中,json数据里面的data参数里面必须用双引号,才能传到后台一json对象,而后才能被@RequestBody转成javabean对象,而且要在外面用单引号括起来(传json整个数据的时候)--在springmvc里面用的多------
若是不加单引号,传递过去的就是一个参数键值对,而不是一个完整的json对象
contentType:'application/json;charset=utf-8',
data:'{"name":"黑妹牙膏","price":"999"}',
二、传参数的时候,data参数是一个对象,{},外面若是加双引号或者单引号,会得不到数据(struts2)
1、内容回顾:
线程安全概念:
线程安全:屡次访问同一个对象/变量,获得同一个结果
线程不安全:屡次访问同一个对象/变量,获得不一样结果
一、springmvc是否线程安全
安全,springmvc底层是servlet,是单例
二、i++,++i是否线程安全
成员变量:线程不安全
public class A{
int i=9;
i++;
}
三、有了struts2,为何还须要使用springmvc?
①、底层实现机制:struts2:过滤器 springmvc:servlet
②、运行效率:struts2 :多例运行 很耗资源 springmvc:单例,比struts快
③、参数封装:struts2:基于属性进行封装 springmvc:基于方法进行封装---方法参数是局部变量,方法执行结束,方法变量内存释放。
2、springmvc相关注解
一、@RequestMapping注解的几种使用
* 1,@RequestMapping("itemsList")
* 2,@RequestMapping("/itemsList")
* 3,@RequestMapping("itemsList.do") --前提是web.xml里面配置的路径为 *.do
* 4,@RequestMapping(value="itemsList")
* 5,@RequestMapping(value="itemsList",method=RequestMethod.POST)
* 6,@RequestMapping(value="itemsList",method=RequestMethod.GET)
* 7,@RequestMapping(value="itemsList",method={RequestMethod.GET,RequestMethod.POST})
(href,直接经过浏览器发送都是get请求;form表单,ajax指定post,都是post)
二、@RequestParam注解:
* 1,设置默认值(若是页面传递值为null,自动设置为默认值) @RequestParam(defaultValue="2")
* 2,设置别名 (若是页面传递参数名称和方法接受参数名称不一致,设置别名) @RequestParam(value="ids")
* @RequestParam(defaultValue="2",value="ids")
三、商品更新
/** * 需求:根据id更新商品数据 * 请求:/item/updateSubmit * 参数:item * 返回值:重定向商品列表 */ @RequestMapping("/item/updateSubmit") public String updateSubmit(Item item){ itemService.updateItemByID(item); return "redirect:/itemsList.do"; }
<!-- 商品更新 --> <update id="updateItemByID" parameterType="item" > update items set name=#{name},price=#{price},detail=#{detail},pic=#{pic},createtime=#{createtime} where id=#{id} </update>
四、窄化请求映射
在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的全部方法请求url必须以请求前缀开头,经过此方法对url进行分类管理。
这种状况就会一个路径能够找到两个方法,产生错误
以下:
@RequestMapping放在类名上边,设置请求前缀
@Controller
@RequestMapping("/item")
方法名上边设置请求映射url:
@RequestMapping放在方法名上边,以下:
@RequestMapping("/queryItem ")
访问地址为:/item/queryItem
五、重定向和转发
①、重定向:
return "redirect:/itemsList.do" /在下面这种状况不能省略
@RequestMapping("/item/updateSubmit") public String updateSubmit(Item item){ itemService.updateItemByID(item); return "redirect:itemsList.do"; }
这种方式重定向的路径为 /item/itemList.do
若是两个方法的路径在同一级的话,那么 / 能够去掉(这是下面说的本类重定向)-----不是在同一个类里面也能够,同一级就行
* 需求:重定向
* 本类重定向:
* 1,return "redirect:list.html"
* 2,return "redirect:/red/list.html"
* 跨类重定向:
* 1,return "redirect:/itemsList.html" 必需要有 / 或者根路径
②、转发:
@Controller@RequestMapping("for")public class ForwardController { @RequestMapping("list") public String list(){ System.out.println("hhhhhh"); return null; } /** * 需求:转发 * 本类转发: * 语法: * 1,return "forward:list.html" * 2,return "forward:/red/list.html" * 跨类转发: * 1,return "forward:/itemsList.html" */ public String forward(){ //return "forward:/red/list.html"; //本类转发: //子路径 //return "forward:list.html"; //return "forward:/for/list.html"; //跨类转发: return "forward:/itemsList.do"; }}
六、json转换注解:
@RequestBody: 请求 把json格式请求参数转换为javabean
@ResponseBody: 响应 把javabean对象自动转换json对象,返回页面
注解支持:一、mvc注解驱动 二、Jackson包支持 三、请求json,返回json都是js操做
须要配置
<mvc:annotation-driven />
①、在springmvc中,json数据里面的data参数里面必须用双引号,而且要在外面用单引号括起来(传json整个数据的时候)--在springmvc里面用的多------
contentType:'application/json;charset=utf-8',
data:'{"name":"黑妹牙膏","price":"999"}',
②、传参数的时候,data参数是一个对象,{},外面若是加双引号或者单引号,会得不到数据(struts2)
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.js" ></script><script type="text/javascript"> function reqJson (){ $.ajax({ type:"post", url:'${pageContext.request.contextPath}/reqJson.do', contentType:'application/json;charset=utf-8', data:'{"name":"黑妹牙膏","price":"999"}', success:function(data){ //返回json对象 alert(data.name); } }) }</script><title>Insert title here</title></head><body> <button onclick="reqJson();" >请求json,返回json格式的数据</button></body></html>
@Controllerpublic class JsonController { /** * 需求:跳转传递参数页面 */ @RequestMapping("json") public String json(){ return "reqJson"; } /** * 需求:接受json格式参数,返回json对象 * @requestBody:接受json格式参数,自动把json格式参数自动转换对象 * @responseBody:自动把返回对象转换成json格式返回 */ @RequestMapping("reqJson") @ResponseBody public Item reqJson(@RequestBody Item item){ System.out.println(item); return item; }}
七、springmvc的异常处理:
①、定义一个可预期的异常类
public class CustomException extends Exception { //定义一个字符串变量,封装自定义异常信息 private String message; public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } //构造函数,封装异常信息 public CustomException(String message) { super(message); this.message=message; }}
②、建立异常处理器:
public class ExceptionResolve implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse res, Object obj, Exception ex) { CustomException ce=null; //判断异常信息是不是自定义异常 if (ex instanceof CustomException) { ce=(CustomException) ex; }else{ //运行时异常信息 ce = new CustomException("运行时异常,请联系管理员!"); } ModelAndView mv = new ModelAndView(); //设置异常数据 mv.addObject("ex", ce.getMessage()); mv.setViewName("error/error"); return mv; }}
③、在springmvc.xml里面配置异常处理器
<!-- 配置全局异常处理器 -->
<bean class="com.itcast.utils.ExceptionResolve" ></bean>
八、文件上传
①、方案:建立一个单独的服务器,单纯存储图片,两台服务器的交互,异步上传
②、需求:上传图片,页面不刷新,图片立马回显,存在另外一台服务器,跨服务器
③、技术:ajax jersy-io(跨服务器) commons-io、commons-fileupload(上传)
④、文件上传的环境
⑥、图片服务器搭建
建立新的服务器:
修改新的服务器的端口号:
修改服务器权限:
⑦、ajax异步上传:
jsp页面:
- </form>
<form id="itemForm" action="${pageContext.request.contextPath}/item/updateSubmit" method="post" >
<td> <!-- 图片回显 --> <img id="imgSize1ImgSrc" src="" height="100" width="100" > <!-- ajax异步上传函数 --> <input type="file" id="imgSize1File" name="imgSize1File" class="file" onchange="submitImgSize1Upload" > <!-- 保存数据库图片地址 --> <input type="hidden" id="imgSize1" name="pic" value="" reg="^.+$" tip="亲,您忘记上传图片了" > </td>
js代码:
为了使ajax提交的时候,request域中有文件的流对象,因此须要将表单
"异步"提交
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.js" ></script><script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.form.js" ></script><script type="text/javascript"> function submitImgSize1Upload(){ var option={ type:'post', url:'${pageContext.request.contextPath}/uploadPic.do', dataType:'text', data:{ fileName:'imgSize1File' }, success:function(data){ //把返回json格式字符串转换json对象 var obj = $.parseJSON(data); //图片立马回显 $("#imgSize1ImgSrc").attr("src",obj.fullPath); //图片保存数据地址 $("#imgSize1").val(obj.fullPath); } }; //使用ajax异步提交表单 $("#itemForm").ajaxSubmit(option); }</script>
也能够直接把dataType改为"json",在success函数中就不用转换了(本来是字符串转换为json对象)
⑧、后台代码:
新建一个UpLoadController类
* 需求:上传文件:avi,xls,doc,jpg
* 参数:String fileName,HttpServletRequest,PrintWriter
* 返回值:void
public class UploadController { /** * 需求:上传文件:avi,xls,doc,jpg * 参数:String fileName,HttpServletRequest,PrintWriter * 返回值:void */ @RequestMapping("/uploadPic") public void uploadPic(String fileName,HttpServletRequest request,PrintWriter out){ //把request转换多部件对象 MultipartHttpServletRequest mh = (MultipartHttpServletRequest) request; //获取文件对象 CommonsMultipartFile cm = (CommonsMultipartFile) mh.getFile(fileName); //获取文件扩展名 //a、获取文件名称 String originalFilename = cm.getOriginalFilename(); //b、截取文件扩展名 String extName = originalFilename.substring(originalFilename.lastIndexOf(".")); //使用uuid生成文件名称 String fName = UUID.randomUUID().toString(); //上传文件 jersey工具 Client create = Client.create(); //制定上传的服务器路径 WebResource resource = create.resource(Constants.IMAGE_ADDR+"upload/"+fName+extName); //上传 resource.put(String.class, cm.getBytes()); //图片回显,须要图片地址返回给ajax的回调函数 //返回json格式数据 String fullPath = Constants.IMAGE_ADDR+"upload/"+fName+extName; //构造一个json格式数据 String result="{\"fullPath\":\""+fullPath+"\"}"; //返回 out.print(result); }}
⑨、修改保存图片
直接提交就能够了
3、restfull软件设计
restfull是一种软件架构设计风格模式
特色:请求没有参数,没有扩展名
案例:http://geek.csdn.net/news/detail/
200288 (restfull风格请求)
优势:简洁,容易被搜索引擎系统收录
springmvc实现restfull风格软件架构
一、 springmvc URI模板映射
@RequestMapping("list/{ids}/{name}")
public String findAllItems(@Pathvariable("ids") int id,
@Pathvariable String name ,
Model
model
){
url中的{id}会自动映射到参数id上,{name}和参数中的name匹配,能够取别名
二、servlet拦截目录
<servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern><!-- 拦截全部,包括css,js,images --> </servlet-mapping>
三、配置springmvc不拦截静态资源
<!-- 放行资源文件 -->
<!--
<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
<mvc:resources location="/images/" mapping="/images/**"></mvc:resources>
-->
<!-- 简单写法 -->
<mvc:default-servlet-handler/>
若是不加这个注释(静态资源放行),那么能够直接用url在浏览器的地址栏访问jsp页面,可是不能访问html和image或者css、js文件
/ 不拦截jsp能够在url中直接访问jsp
/* 拦截jsp不能在url中直接访问jsp,return的结果视图也不行,因此不用
4、拦截器:
一、简单测试:
public class Interceptor1 implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("这是第一个拦截器的preHandle"); return true; } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println("这是第一个拦截器的postHandle"); } @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("这是第一个拦截器的afterCompletion"); }}
第二个拦截器同样,return false
preHandle:处理器映射器执行以前进行执行,拦截:return false;放行:return true;
postHandle:返回model和view以前执行
afterCompletion:返回model和view以后执行
在springmvc中配置拦截器:
<!-- 配置拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.itcast.interceptor.Interceptor1" ></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.itcast.interceptor.Interceptor2" ></bean> </mvc:interceptor> </mvc:interceptors>
按照上面的配置,先运行拦截器1,再运行2
①、若是第一个拦截器return false;第二个是false或者true,那么都返回:
这是第一个拦截器的preHandle
②、若是第一个拦截器return true ;第二个拦截器return false,那么返回:
这是第一个拦截器的afterCompletion
③、若是第一个和第二个拦截器都return true ,那么返回:
这是第一个拦截器的postHandle
这是第一个拦截器的afterCompletion
注意:若是preHandle拦截器返回true,那么afterCompletion必须执行
5、拦截器登陆案例
public class LoginInterceptor implements HandlerInterceptor{ //判断用户是否登陆 @Override public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj) throws Exception { //登陆页面,登陆请求放行 if (req.getRequestURI().contains("login")) { //放行 return true; } Object user = req.getSession().getAttribute("user"); if (user!=null) { return true; } //若是未登陆,跳转登陆页面 req.getRequestDispatcher("WEB-INF/jsp/login.jsp").forward(req, res); return false; }
<mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.itcast.interceptor.LoginInterceptor" ></bean> </mvc:interceptor>
@Controllerpublic class LoginController { @RequestMapping("login") public String login(String username,String password,HttpSession session){ session.setAttribute("user", username); return "redirect:/itemsList"; }}