@ControllerAdvice
定制ControllerAdvice
package cn.hncu.exception; import org.springframework.ui.Model; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.ModelAndView; /** * Created with IntelliJ IDEA. * User: 陈浩翔. * Date: 2017/2/21. * Time: 下午 6:04. * Explain:定制ControllerAdvice */ @ControllerAdvice //声明一个控制器建言,@ControllerAdvice组合了@Component注解,所以自动注册为 public class ExceptinHandlerAdvice { @ExceptionHandler(value = Exception.class) //@ExceptionHandler在此处定义全局处理,通过@ExceptionHandler的value属性可过滤拦截的条件,在此处我们可以看出我们拦截所有的Exception public ModelAndView exception(Exception e, WebRequest request){ ModelAndView modelAndView = new ModelAndView("error"); //error页面 modelAndView.addObject("errorMessage",e.getMessage()); return modelAndView; } @ModelAttribute //此处使用@ModelAttribute 注解将键值对添加到全局,所有注解@RequestMapping的方法可获得此键值对 public void addAttributes(Model model){ model.addAttribute("msg","额外信息"); } @InitBinder //通过@InitBinder 注解定制 WebDataBinder public void initBinder(WebDataBinder webDataBinder){ webDataBinder.setDisallowedFields("id"); //此处演示忽略request 参数的id } }
演示控制器
package cn.hncu.controller; import cn.hncu.model.DemoObj; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; /** * Created with IntelliJ IDEA. * User: 陈浩翔. * Date: 2017/2/21. * Time: 下午 8:08. * Explain:演示控制器 */ @Controller public class AdviceController { @RequestMapping("advice") public String getSomething(@ModelAttribute("msg") String msg , DemoObj obj){ System.out.println("id:"+obj.getId()+" , name:"+obj.getName()); //访问 http://localhost:8080/springMVC3/advice?id=1&name=chx //id:null , name:chx -因为id被过滤掉了! throw new IllegalArgumentException("非常抱歉,参数有误/"+"来自@ModelAttribute:"+msg); } }
异常展示页面
在src/main/resources/views下,新建error.jsp,内容如下:
<%-- Created by IntelliJ IDEA. User: 陈浩翔 Date: 2016/12/18 Time: 下午 12:45 To change this template use File | Settings | File Templates. --%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> <html> <head> <title>@ControllerAdvice Demo</title> </head> <body> <pre>Welcome to Spring MVC</pre> <br/> ${errorMessage} </body> </html>
运行
访问:http://localhost:8080/springMVC3/advice?id=1&name=chx
可以看到id被过滤掉了!
其他配置
快捷的ViewCOntroller
在前面我们配置页面转向的时候是这样写代码的:
@Controller @RequestMapping("index") public class Index { @RequestMapping("/") public String index(){ return "index"; } }
此处无任何业务处理,只是简单的页面转向,写了很多冗余代码,在实际开发中会涉及大量这样的页面转向,如果都这样写会很麻烦。
所以,我们可以通过在配置中重写addViewControllers来简化配置:
@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/inn").setViewName("/in"); //addViewController是访问的URL,setViewName是设置in.jsp }
这样实现的代码更简洁,管理更集中。
访问:http://localhost:8080/springMVC3/inn
在路径匹配参数配置
在Spring MVC中,路径参数如果带”.”的话,”.”后面的值都将被忽略,例如:
我们在AdviceController.java中增加代码:
@RequestMapping("pathvar/{str}") public @ResponseBody String pathvarDemo(@PathVariable String str){ return "str:"+str; }
接下来访问:http://localhost:8080/springMVC3/pathvar/chenhaoxiang.hncu
结果如下:
可以看到”.”后面的参数没有传过去
我们可以这样解决、通过重写configurePathMatch方法可不忽略”.”后面的参数,代码如下(写在Spring MVC配置类中):
@Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setUseSuffixPatternMatch(false);//不忽略 "."后面的参数 }
这个时候,我们重新运行在看,继续访问刚才的地址
本篇博客涉及到的源码链接: