SpringMVC第二阶段

SpringMvc

[TOC]

高级参数绑定

批量删除(数组)

  • 从请求中接受参数,多个id<input type="checkbox" name="ids" value="${item.id}"/>

  • 可以在QuertVo定义一个int[] ids;这样在页面的 <input type="checkbox">中的name是ids,然后再controller中接受参数用QueryVo即可

批量修改(List集合)

  • QueryuVo中需要封装List<Items> itemList;
  • 页面上input框的name属性 : vo中的集合属性名称+[集合索引]+.泛型中对应的属性名称用来使controller中的方法,接收返回的List\
    • <input type="text" value="${item.name }" name="itemList[${status.index }].name">

@RequestMapping

  • 写在方法上:标记url到请求方法的映射,其实就是通过浏览器中的url找到对应的controller方法

  • 写在类上:窄化请求映射,其实就是为了防止你起的url跟你同事的起的url相同,请求错乱的情况在类上加了一层目录,访问的时候要在地址上加上这个参数

    • ,这样在访问的时候就需要在前面加一个item,localhost:8080/SpringMvc01/item/list.action
  • 限制请求的类型:get post,参数中加注解

    • @RequestMapping(value="/list",method=RequestMethod.POST)
    • 限制请求类型后必须是该类型的访问请求才能访问此方法,如果是其他访问类型报405
    • 默认是get类型

      controller方法返回值

请求转发:浏览器中的url不发生改变,request域中的数据能带入转发后的方法中
重定向:浏览器中的url发生改变,request域中的数据不能带入重定向后的方法中

String

  • 返回一个普通的页面: 就认为是页面地址

请求转发

  • 在SpringMvc中请求转发可以让controller方法返回值为String类型,那么返回的字符串以forword:开头的为请求转发,当然路劲也是url 路劲
1
2
3
4
5
//request.setAttribute("id", items.getId());
model.addAttribute("id", items.getId());
//在springMvc中请求转发可以让controller方法返回值为String类型, 那么返回的字符串以forward:开头的为请求转发,
//forward:字符串后面跟需要访问的url路径
return "forward:toEdit.action";

重定向

  • 在SpringMvc中请求转发可以让controller方法返回值为String类型,那么返回的字符串以`redirect:’的为重定向
1
2
3
model.addAttribute("id", items.getId());
//在springMvc中重定向, 返回的值以redirect:字符串开头, 后面跟需要重定向的url
return "redirect:toEdit.action";
model
  • model可以把数据带到重定向后的方法,因为model底层是request域而且对其做了扩展model.addAttribute("itemList", list);

    • 不管是转发还是重定向都能把model中的值带到抵达的方法中
    • 还有一种情况就是同时有model跟request向域中set值的时候,不管谁在前面,在转发的时候会把model里面的值在放入与里边一遍。所以在取出来的时候的值是model.addAttribute里边的值。
  • ModelAndView.addObject("itemList", list);如果想用这个类就必须返回值为ModelAndView类型的,同样也是存到了model中。

相对路径和绝对路径
  • springMvc中请求转发和重定向,后面的url路径以斜杠/开头为绝对路径,
  • 不以斜杠/开头的为相对路径

  • 相对路径: 相对路径是相对于当前路径
    • 最多只限于当前类下的url路径进行跳转使用
  • 绝对路径: 从项目名后开始算
    • 一般在从一个controller方法中一条转到另一个controller方法中使用
    • 但是所有路径都可以写成绝对路径, 是无敌的

void

  • 当返回值为void的时候,只能借助原生的request,response 这样就不走SpringMvc的视图解析了,相当于破坏了SpringMvc的体系结构,所以不推荐使用
1
2
3
4
5
6
//转发
public void update(Items items, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception{
itemsService.updateItemsById(items);
request.setAttribute("items", items);
request.getRequestDispatcher("/WEB-INF/jsp/editItem.jsp").forward(request, response);
}
  • 但是在ajax发送请求的时候,需要回掉函数返回数据的时候,可以使用这种原生的方法。

SpringMvc中的异常处理

  • 异常分类:
    • 运行时异常:
    • 自定义异常:

自定义异常:

  • 新建一个自定义异常的类继承Exception,里面有一个Message属性,实现get,set
1
2
public class CustomException extends Exception{
private String message;
  • 在自定义一个处理异常的类CustomGlobalExceptionReslover继承HandlerExceptionResolver,重写里面的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class CustomGlobalExceptionReslover implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object arg2,
Exception exce) {
String msg="";
if(exce instanceof CustomException){
msg=exce.getMessage();
}else{
msg="不好意思, 系统繁忙, 请联系管理员!";
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg",msg);
modelAndView.setViewName("error");
return modelAndView;
}
  • 然后再SpringMvc的配置文件中配置一下,把自定义异常的处理类交给Spring即可
    <bean class="com.zc.exception.CustomGlobalExceptionReslover" />

  • 测试

1
2
3
4
5
6
7
8
9
//测试运行时异常
//int i=1/0;
//测试自定义异常
if(true){
CustomException exception = new CustomException();
exception.setMessage("测试自定义异常");
throw exception;
}

图片上传

springMvc中对图片上传有接口的支持, 但是没有实现,所以需要第三方实现.

  • 用的是FileUpload,先导包,然后配置文件配置一下
1
2
3
4
5
6
7
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
  • 然后在form标签上设置enctype="multipart/form-data"

    • 文件上传项<input type="file" name="pictureFile"/>
  • 然后再controller中的参数中增加一个MultipartFile pictureFile用来接收文件上传项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RequestMapping("/update")
public String update(MultipartFile pictureFile,Items items, Model model) throws Exception{
//1. 获取图片的完整名称
String fileName = pictureFile.getOriginalFilename();
//2. 生成随机字符串+源文件的扩展名组成新文件名, 防止图片重名
String newFileName = UUID.randomUUID().toString() + fileName.substring(fileName.lastIndexOf("."));
//3. 将图片保存到硬盘中
pictureFile.transferTo(new File("E:\\image\\" + newFileName));
//4. 将图片名称保存到数据库中
items.setPic(newFileName);
itemsService.updateItemsById(items);
model.addAttribute("id", items.getId());
return "redirect:toEdit.action";
}

tomcat中有配置的图片服务器

  • 双击tomcat,打开底下第二个视图
  • 点击Add External Web Module...
    • 上面就是服务器存放图片的地址,把图片放入这个路径下,通过下面那个自定义的地址就能访问到
    • 例如:设置底下的路劲为pic则可以在服务器中访问,上面路劲下的图片http://localhost:8080/pic/aaa.jpg

json数据交互

让SpringMvc自动将接受的json格式字符串转换成java对象,将pojo对象转换成json串返回给页面

  • SpingMvc中对json的支持有接口但是无实现,所以需要第三方的实现,杰克逊的jar包,在企业中SpringMvc.xml配置注解驱动,那么这样的SpringMvc就跟杰克逊的jar包完美集成不用任何配置
    • @RequestBody 作用: 将接收到的json格式字符串自动转换成pojo对象, 要求json的key必须等于pojo中对应的属性名称
    • @ResponseBody作用: 将返回的pojo对象自动转换成json格式字符串返回
    • 如果想返回一个json的话,可以把想要转的实体返回,返回值也是他的类型只要加一个注解就行@ResponseBody
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$.ajax({
type:"post",
url:"${pageContext.request.contextPath }/items/sendJson",
contentType:"application/json;charset=utf-8",
data:'{"name":"测试商品","price":99.9}',
success:function(data){
alert(data);
}
});
@RequestMapping("/sendJson")
@ResponseBody
public Items sendJson(@RequestBody Items items) throws Exception{
System.out.println(items);
return items;
}

RESTful支持

  • 就是url的一个命名规范,要求url中只能是名词,没有动词,但是由于国内开发人员英文水平不太好,所以不严格要求, 但是要求url中没有问号传参
    • 例如:http://blog.csdn.net/beat_the_world/article/details/45621673

添加DispatcherServlet的rest配置

  • 当web.xml中配置url-partten为斜杠/的时候会拦截静态资源不放行
  • 可以在SpringMvc.xml放行dispathcerServlet中被拦截的静态资源

    • location:配置页面引用时放行的路径
    • mapping:放心的静态资源的位置
  • 例如:这样<mvc:resources location="/js/" mapping="/js/**"/>配置之后就能访问到引入的js了

URL 模板模式映射

  • 路劲:${pageContext.request.contextPath }/toEdit/${item.id}

  • @RequestMapping(value="/toEdit/{id}"):{×××}占位符,请求的URL可以是“/viewItems/1”或“/viewItems/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。

  • @PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。
1
2
3
4
5
6
7
8
@RequestMapping("/toEdit/{id}")
public String toEdit(@PathVariable("id") String id,Model model) throws Exception{
//现在id就能用了
//调用 service查询商品信息
Items items = itemsService.findItemsById(id);
model.addAttribute("item", items);
return "toEdit";
}
  • 当然也可以有多个参数:${pageContext.request.contextPath }/toEdit/${item.id}/${item.name}
    • 这样在接收的时候,后面跟两个占位符即可
1
2
@RequestMapping("/toEdit/{id}/{name}")
public String toEdit(@PathVariable("id") String id,@PathVariable("name") String name,Model model) throws Exception{

拦截器

作用: 拦截请求

  • 先创建一个拦截器的类interceptor实现HandlerInterceptor,重写里面的三那个方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Interceptor1 implements HandlerInterceptor {
//执行时机: controller方法已经执行, modelAndView已经返回
//使用场景: 可以记录日志信息
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("====Interceptor1=======afterCompletion===");
}
//执行时机: controller方法已经执行, modelAndview还没有返回
//使用场景: 可以在这里进行全局的数据的加工处理, 比如全局都需要一个天气信息, 就可以在这里加入, 全局都能取到天气的数据
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("====Interceptor1=======postHandle===");
}
//执行时机: controller方法没有执行, modelAndView还没有返回
//使用场景: 做权限校验的时候, 判断session中是否有用户的登录信息
//返回值是boolean类型, 返回true放行, 返回false拦截住不放行
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("====Interceptor1=======preHandle===");
return true;
}
}
  • 然后再配置文件配置一下
1
2
3
4
5
6
7
8
9
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截所有路径 -->
<mvc:mapping path="/**"/>
<!-- 不拦截某个路径 -->
<mvc:exclude-mapping path="/user/**"/>
<bean class="com.zc.interceptor.Interceptor01"></bean>
</mvc:interceptor>
</mvc:interceptors>
  • 然后每次请求中执行顺序:preCompletion , postCompletion , afterCompletion
  • 多个拦截器执行顺序:
    • 多个拦截器的执行顺序preCompletion等于springMvc.xml中配置拦截器的顺序
    • postCompletion , afterCompletionspringMvc.xml中配置拦截器的顺序相反
张冲 wechat
欢迎扫一扫上面的微信关注我,一起交流!
坚持原创技术分享,您的支持将鼓励我继续创,点击打赏!