前言
在编程过程中,我们总是会遇到各种各样的一样,受检异常和非受检异常,也可以对这些异常进行重写或者扩展,总而言之,这就涉及到一个处理异常的问题。
好的异常处理方式既容易配置又可以保持使用端的友好交互,更为重要的是在出现问题的时候快速的帮助我们定位问题。
事实上,对代码的理解很总要,这样你就知道什么时候应该抛出什么异常了,比如数组越界,文件过大,栈越界,连接超时这些标准异常,等等。当然,在什么时候抛出什么异常不是本文的重点,网上同类的文章很多,传送门Java 基础 积累-不断更新:异常分类:Error,Exception,RuntimeException以及其子类,其他异常
本文主要着重于异常的抛出方式和捕获方式。
再一个,对于以接口对外提供服务的项目与以页面对外提供服务的项目侧重点也是不一样的。前者需要在遇到异常时继续返回接口出参,只不过是内容有所不同,而以页面交互
的在出现异常时,则可能是跳转到了不同的页面并且给予提示信息。
最后,异常的处理包括异常的抛出和处理,抛出异常是一个,捕获异常和接下来的处理是另一个。
(1)抛出异常——捕获异常——跳转页面
(2)抛出异常——捕获异常——接口出参
代码
本文代码已经上传git:https://github.com/Bestcxy/Spring-fileup-interceptor-filter-Exception
基础工作
(1)自定义的异常类
- package com.bestcxx.stu.fileup.exception;
- /**
- * 自定义的异常类
- * @author WuJieJecket
- *
- */
- @SuppressWarnings("serial")
- public class MyException extends Exception {
- public MyException(String string) {
- super(string);
- }
- }
(2)页面等前端文件的位置-视图解析配置-关注页面基础位置WEB-INF/views
applicationContext-mvc.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:util="http://www.springframework.org/schema/util"
- xmlns:orm="http://www.springframework.org/schema/orm"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
- http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-4.3.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
- ">
- <!-- 配置注解驱动 -->
- <mvc:annotation-driven/>
- <!-- 定义默认访问 -->
- <mvc:view-controller path="/" view-name="forward:home"/>
- <!-- 处理静态资源 -->
- <mvc:resources location="/WEB-INF/css/" mapping="/css/**" />
- <mvc:resources location="/WEB-INF/js/" mapping="/js/**" />
- <!-- 配置视图解析器 -->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
- <property name="contentType" value="text/html"/>
- <property name="prefix" value="/WEB-INF/views/"/>
- <property name="suffix" value=".jsp"/>
- </bean>
- </beans>
开始了
异常的抛出
(1)局部方法抛出
- /**
- * 异常处理测试
- * @return
- */
- @GetMapping("exception")
- public String exception() throws Exception{
- if(true){
- throw new MyException("报错");
- }
- return "success";
- }
(2)拦截器抛出-类加配置文件
- package com.bestcxx.stu.fileup.intercepter;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
- import org.apache.commons.fileupload.servlet.ServletRequestContext;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
- import com.bestcxx.stu.fileup.exception.MyException;
- public class MyInterceptor implements HandlerInterceptor {
- private long maxSize;
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- System.out.println(this.getClass()+" preHandle开始:"+System.currentTimeMillis());
- System.out.println(this.getClass()+" 自定义拦截器访问前:"+maxSize);
- if(request!=null && ServletFileUpload.isMultipartContent(request)) {
- ServletRequestContext ctx = new ServletRequestContext(request);
- long requestSize = ctx.contentLength();
- if (requestSize > maxSize) {
- System.out.println(this.getClass()+" preHandle结束:"+System.currentTimeMillis()+" 文件太大主动抛出异常");
- //throw new MaxUploadSizeExceededException(maxSize);
- throw new MyException(maxSize+"文件太大超了");
- }
- }
- System.out.println(this.getClass()+" preHandle结束:"+System.currentTimeMillis());
- return true;
- }
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
- ModelAndView modelAndView) throws Exception {
- // TODO Auto-generated method stub
- System.out.println(this.getClass()+" postHandle开始:"+System.currentTimeMillis());
- System.out.println(this.getClass()+" 自定义拦截器访问中:"+maxSize);
- System.out.println(this.getClass()+" postHandle结束:"+System.currentTimeMillis());
- }
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- throws Exception {
- // TODO Auto-generated method stub
- System.out.println(this.getClass()+" afterCompletion开始:"+System.currentTimeMillis());
- System.out.println(this.getClass()+" 自定义拦截器访问后:"+maxSize);
- System.out.println(this.getClass()+" afterCompletion结束:"+System.currentTimeMillis());
- }
- public void setMaxSize(long maxSize) {
- this.maxSize = maxSize;
- }
- }
applicationContext-intercepter.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:util="http://www.springframework.org/schema/util"
- xmlns:orm="http://www.springframework.org/schema/orm"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
- http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-4.3.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
- ">
- <!-- 拦截器配置 -->
- <mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <bean class="com.bestcxx.stu.fileup.intercepter.MyInterceptor">
- <!-- <property name="maxSize" value="5242880"></property> --><!-- 5mb -->
- <property name="maxSize" value="5000"></property>
- </bean>
- </mvc:interceptor>
- </mvc:interceptors>
- </beans>
(3)过滤器抛出-类加web.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:util="http://www.springframework.org/schema/util"
- xmlns:orm="http://www.springframework.org/schema/orm"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
- http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-4.3.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
- ">
- <!--文件上传-->
- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <!-- <property name="maxUploadSize"><value>1</value></property> -->
- <!-- <property name="maxUploadSize"><value>5242880</value></property> --><!-- 设置上传文件的最大尺寸为 5mb=5*1024kb=5*1024*1024b -->
- <property name="maxInMemorySize"><value>1</value></property><!-- 小于该尺寸的文件不生成临时文件 -->
- <property name="defaultEncoding"><value>UTF-8</value></property><!-- 默认上传格式为utf-8 -->
- <property name="resolveLazily"><value>true</value></property><!-- 延迟处理异常-将异常交予 controller 处理 -->
- </bean>
- </beans>
异常的捕获
(1)局部方法捕获-与抛出异常的方法处于同一个controller类-可接口可页面
- /**
- * 捕获本类的异常
- * 优先级比全局异常高
- * 针对页面请求的异常处理,默认返回error.jsp
- * 一个类仅允许存在一个 @ExceptionHandler 标注的方法
- * @param ex
- * @param request
- * @return
- */
- @ExceptionHandler(Exception.class)
- public ModelAndView handlePageException(Exception ex, WebRequest request) {
- request.setAttribute("msg","异常捕获:"+this.getClass()+" "+ex.getMessage(), RequestAttributes.SCOPE_REQUEST);
- ModelAndView mav = new ModelAndView("error");
- mav.addObject("ex", ex);
- return mav;
- }
- /**
- * 异常处理测试
- * @return
- */
- @GetMapping("exception")
- public String exception() throws Exception{
- if(true){
- throw new MyException("报错");
- }
- return "success";
- }
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <%
- String path = request.getContextPath();
- String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
- %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>error.jsp</title>
- </head>
- <body>
- <h1> ${msg} </h1>
- <h1> ${ex} </h1>
- </body>
- </html>
- /**
- * 捕获本类的异常
- * 优先级比全局异常高
- * 针对接口调动的异常处理
- * 一个类仅允许存在一个 @ExceptionHandler 标注的方法
- * @param ex
- * @param request
- * @return
- */
- @ExceptionHandler(Exception.class)
- @ResponseBody
- public Object handleRestfulException(Exception ex, WebRequest request) {
- request.setAttribute("msg","异常捕获:"+this.getClass()+" "+ex.getMessage(), RequestAttributes.SCOPE_REQUEST);
- ModelAndView mav = new ModelAndView("error");
- mav.addObject("ex", ex);
- HashMap map=new HashMap();
- map.put("msg", "非 ModelAndView 的实体或者字符串");
- return map;
- }
(2)全局捕获
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:util="http://www.springframework.org/schema/util"
- xmlns:orm="http://www.springframework.org/schema/orm"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
- http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-4.3.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
- ">
- <!-- 方式一 -->
- <!-- 全局异常捕获-针对页面访问 -->
- <!-- <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
- 定义默认的异常处理页面
- <property name="defaultErrorView" value="error"/>
- 定义异常处理页面用来获取异常信息的变量名,也可不定义,默认名为exception
- <property name="exceptionAttribute" value="ex"/>
- 设置日志输出级别,不定义则默认不输出警告等错误日志信息
- <property name="warnLogCategory" value="WARN"></property>
- 默认HTTP状态码
- <property name="defaultStatusCode" value="200"></property>
- 对于需要特殊处理的异常
- <property name="exceptionMappings">
- <props>
- <prop key="java.lang.Exception">error</prop>
- <prop key="java.lang.Error">error</prop>
- </props>
- </property>
- <property name="statusCodes">
- <props>
- <prop key="error">500</prop>/views/error.jsp
- </props>
- </property>
- </bean> -->
- <!-- 方式二 -->
- <!-- Exception 类捕获-针对页面或者接口访问-->
- <!-- <context:component-scan base-package="com.bestcxx.stu.fileup.exception.ExceptionResolver"/> -->
- <!-- 方式三 -针对页面或者接口访问-->
- <!-- 全局异常处理器只要你实现了HandlerExceptionResolver接口,这个类就是一个全局异常处理器-->
- <bean class="com.bestcxx.stu.fileup.exception.GlobalExceptionResolver"></bean>
- </beans>
方式一是针对页面访问的
- package com.bestcxx.stu.fileup.exception;
- import org.springframework.web.bind.annotation.ControllerAdvice;
- import org.springframework.web.bind.annotation.ExceptionHandler;
- import org.springframework.web.multipart.MaxUploadSizeExceededException;
- import org.springframework.web.servlet.ModelAndView;
- /**
- * 全局异常配置
- * @author Administrator
- *
- */
- @ControllerAdvice
- public class ExceptionResolver {
- @ExceptionHandler(RuntimeException.class)
- public ModelAndView handlerRuntimeException(RuntimeException ex){
- if(ex instanceof MaxUploadSizeExceededException){
- return new ModelAndView("error").addObject("msg", "文件太大!");
- }
- return new ModelAndView("error").addObject("msg", "未知错误:"+ex);
- }
- @ExceptionHandler(Exception.class)
- public ModelAndView handlerMaxUploadSizeExceededException(Exception ex){
- if(ex instanceof Exception){
- return new ModelAndView("error").addObject("msg", ex);
- }
- return new ModelAndView("error").addObject("msg", "未知错误:"+ex);
- }
- }
方式三GlobalExceptionResolver.java
- package com.bestcxx.stu.fileup.exception;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.web.multipart.MaxUploadSizeExceededException;
- import org.springframework.web.servlet.HandlerExceptionResolver;
- import org.springframework.web.servlet.ModelAndView;
- public class GlobalExceptionResolver implements HandlerExceptionResolver {
- @Override
- public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
- Exception ex) {
- ModelAndView modelAndView=new ModelAndView();
- System.out.println("异常信息输出:"+ex.toString());
- //如果是文件太大
- if (ex instanceof MaxUploadSizeExceededException) {
- long maxSize = ((MaxUploadSizeExceededException) ex).getMaxUploadSize();
- System.out.println(this.getClass()+" 上传文件太大,不能超过" + maxSize/1024/1024 + "mb"); // 打印错误信息
- //将错误信息传到页面
- modelAndView.addObject("msg",this.getClass()+" 出现异常:"+"上传文件太大,不能超过" + maxSize/1024/1024 + "mb"+ex.getMessage());
- //指向到错误界面
- modelAndView.setViewName("error");
- return modelAndView;
- }
- if(ex instanceof MyException){ //自定义异常
- modelAndView.addObject("msg","自定义异常:"+ex.getMessage());
- }else{
- //如果该 异常类型不是系统 自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)。
- modelAndView.addObject("msg","未知异常:"+ex.getMessage());
- }
- //将错误信息传到页面
- modelAndView.addObject("msg","出现异常:"+ex.getMessage());
- //指向到错误界面
- modelAndView.setViewName("error");
- return modelAndView;
- }
- }