注意:所有文章除特别说明外,转载请注明出处.
1.Spring 使用 HandlerExceptionResolver 实现全局异常捕获
首先实现的功能,我们在项目实现的过程中,项目会发生异常,但是我们并没有捕获这些异常,所以会经常出现bug等。在我们没有配置捕获全局异常时,容器会自动打印错误信息。但是如果我们在web.xml中配置,就会拦截错误,然后跳转到响应的处理错误页面。
//表示在web.xml中配置错误拦截,然后跳转到指定的错误处理界面
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
但是现在我们在项目中通过实现Spring的HandlerExceptionResolver接口是实现所有的异常的捕获。
方式一(通过实现HandlerExceptionResolver接口)使用步骤:
1.新建GlobalExceptionResolver
@Component //使用spring 利用 HandlerExceptionResolver实现全局异常捕获 public class GlobalHandleExceptionResolver implements HandlerExceptionResolver { private static Logger LOG = Logger.getLogger(GlobalHandleExceptionResolver.class); private static final int USER_EXCEPTION_CODE = 1; private static final int OTHER_EXCEPTION_CODE =2; //编写自己需要的类 public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex){ ModelAndView mv = new ModelAndView("error"); if(ex instanceof UserException){ mv.addObject("message", ex.getMessage()); mv.addObject("code",USER_EXCEPTION_CODE); LOG.error("用户异常:" +ex.getMessage(),ex); }else{ mv.addObject("message","未知异常"); mv.addObject("code",OTHER_EXCEPTION_CODE); LOG.error("未知异常:"+ ex.getMessage(),ex); } return mv; } }
2.在spring配置文件中配置新建的类
<!--全局异常捕捉 --> <bean class="com.ssm.exception.GlobalExceptionResolver" />
3.根据需求编写自己需要处理的方法
注意:在开发的过程中如果返回null,这样的话这个类如同不起作用。如果我们想返回错误页面,那么直接在ModleAndView里面写好即可。
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
return modelAndView;
方式二(通过使用注解)使用步骤:
1.创建GlobalExceptionResolver
//通过使用ControllerAdvice和ExceptionHandler这两个注解实现全局的异常捕获 @ControllerAdvice public class GlobalExceptionResolver { //这里的ServiceException是自定义的异常 @ExceptionHandler(value = ServiceException.class) public @ResponseBody String serviceCommonExceptionHandler(ServiceException e) { //对捕获的异常进行处理并打印日志等,之后返回json数据,方式与Controller相同 return "{'code':-1}"; } @ExceptionHandler(value = Exception.class) public ModelAndView exceptionHandler() { //当然也可以直接返回ModelAndView等类型,然后跳转相应的错误页面,这都根据实际的需要进行使用 return new ModelAndView(); } } //自定义异常: public class ServiceException extends RuntimeException{ //... }
注意:spring会根据@ExceptionHandler的value值进行匹配,如果我们项目中的一些异常没有被捕获,那么这里就会处理一些没有捕获的异常。
2.Spring MVC 之 HandlerMethodArgumentResolver
简言之,HandlerMethodArgumentResolver = HandlerMethod + Argument(参数) + Resolver(解析器),其实就是HandlerMethod方法的解析器, 将 HttpServletRequest(header + body 中的内容)解析为HandlerMethod方法的参数。
SpringMVC中的HandlerAdapter会对Controller层方法的参数执行HandlerMethodArgumentResolver(对参数的解析器)中的方法。
HandlerMethodArgumentResolver接口主要有两个方法:supportsParameter和resolveArgument
2.1 supportsParameter()方法
boolean supportsParameter(MethodParameter parameter);
此方法返回的类型是boolean类型,作用是判断Controller层中参数是否满足条件,满足则执行resolveArgument()方法,不满足则跳过。
一般地,在supportParameter中执行getParameterAnnotations来判断是否包含这样的注解类型。getParameterAnnotations()方法表示在参数列表中经常会有添加注解的情况,所以在这种情况下使用getParameterAnnotations()方法来获得这些注解。
//在下面这个方法中有四个参数,在参数上又有注解,所以可以通过这种方法来获得
public void testa(@TestAnnocation(pat = "5") String s,@TestAnnocation2 @TestAnnocation(pat = "6") String s1,String s3,@TestAnnocation(pat = "9") String s4) {
System.out.println("------------" + s);
}
2.2 resolveArgument()方法
此方法只会在supportsParameter()方法返回true的情况下才会调用,用于处理业务,将返回值赋值给Controller层中的参数。
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
//判断 HandlerMethodArgumentResolver 是否支持 MethodParameter(PS: 一般都是通过 参数上面的注解|参数的类型)
public interface HandlerMethodArgumentResolver {
//判断是否支持要转换的参数类型
boolean supportsParameter(MethodParameter var1);
//当支持后进行相应的转换
//此方法中包括四个参数
//MethodParameter parameter, M
//odelAndViewContainer mavContainer,
//NativeWebRequest webRequest,
//WebDataBinderFactory binderFactory
Object resolveArgument(MethodParameter var1, ModelAndViewContainer var2, NativeWebRequest var3, WebDataBinderFactory var4) throws Exception;
}
总结:我们清楚,HandlerMethodArgumentResolver是一个参数解析器,我们可以通过写一个类实现HandlerMethodArgumentResolver接口来实现对Controller层中方法参数的修改。