springMVC异常处理,统一配置文件配置形式、继承SimpleMappingExceptionResolver类实现方式、@ExceptionHandler形式

配置文件形式

       <!-- 控制器异常处理,配置后,异常会打印到页面上,但是后台console就不不打印异常,很难找到问题所在。页面要是没el打印输出,更没法找原因了。要在代码里面trycatch打印出来才可以。 -->
    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">

          <!--       配置异常的属性值为exp,那么在错误页面中可以通过 ${exp} 来获取异常的信息
                如果不配置这个属性,它的默认值为exception -->

        <property name="exceptionAttribute" value="exp"></property>
        <property name="exceptionMappings">
              <props>
                  <prop key="java.lang.Exception">
                        error_all
                </prop>
            </props>
        </property>
    </bean>

页面使用el表达式接收异常信息打印出来。
jsp页面:
这里写图片描述
故意输错id,打印出来异常信息,并不具体。
这里写图片描述

  • 注意:这个坑点,异常会打印到页面上,但是后台console就不不打印异常,很难找到问题所在。页面要是没el打印输出,更没法找原因了。要在controller代码里面trycatch打印出来才可以。

继承SimpleMappingExceptionResolver类实现方式

新建类:CustomSimpleMappingExceptionResolver

/**
 * 自定义统一异常处理,主要针对当前UI架构进行修改。如是加载页面就显示异常页面,ajax的话就返回异常信息
 */
public class CustomSimpleMappingExceptionResolver extends
        SimpleMappingExceptionResolver {

    private static Logger logger = Logger.getLogger("web");

    /**
     * 重写Spring统一异常处理方法
     */
    @Override
    protected ModelAndView doResolveException(
            HttpServletRequest request,
            HttpServletResponse response, 
            Object handler, 
            Exception ex){
        logger.info("-------------------------->系统异常", ex);
//      ex.printStackTrace();
        logger.info("<--------------------------");

        StringBuffer requestUrl = request.getRequestURL();
        String contextPath = request.getContextPath();
        String path = requestUrl.substring(requestUrl.indexOf(contextPath)+contextPath.length()+1);

        String viewName = "error_all";
        if(path.startsWith("mobile") || path.startsWith("m")){
            viewName = "error_all";
        }


        //返回消息
        ModelAndView mv = new ModelAndView();
        mv.setViewName(viewName);
        StringWriter sw = new StringWriter(); 
        ex.printStackTrace(new PrintWriter(sw, true)); 
        mv.addObject("exp", sw.toString());

        //判断是否异常处理
        if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request
                .getHeader("X-Requested-With") != null && request.getHeader(
                "X-Requested-With").indexOf("XMLHttpRequest") > -1))) {

            request.setAttribute("info", "操作失败,系统发生异常。");
            Integer statusCode = determineStatusCode(request, viewName);
            if (statusCode != null) {
                applyStatusCodeIfPossible(request, response, statusCode);
            }

            return mv;
        } else {// JSON格式返回

            //否异步加载页面
            if (request.getParameter("loadPage") != null) {
                return mv;
            }

            //非异步加载页面,返回信息
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("code", "01");
            map.put("message", "异常");
            return new ModelAndView(new MappingJacksonJsonView(),map);
        }

    }

}

同时配置文件增加bean:

      <!-- 统一异常处理 -->
    <bean class="com.tgb.exception.CustomSimpleMappingExceptionResolver">
        <property name="exceptionMappings">   
        <props>   
          <prop key="java.lang.exception">errot_all</prop>  
       </props>   
     </property>   
    </bean>

这样页面的异常信息可以通过代码来控制,同时可以对页面或者json请求进行响应。

注解形式@ExceptionHandler

其实等同于配置文件的形式,区别是要每个方法都写。

    @RequestMapping("/exception")
    @ExceptionHandler
    public String exceptionTest(String id, Exception ex, HttpServletRequest request) {
        User findById = userService.findById(Integer.parseInt(id));
        System.out.println(" --------------" + findById.getUserName() + "-------- " + findById.getAge());

        request.setAttribute("exp", ex.getMessage());
        return "error_all";

    }

总结

  开发过程中要留意一下异常统一配置,如果是第一种配置的化,页面必须要EL输出,同时后台console要打印出来错误信息,不然什么都没有。一些老项目就是配置了这个,写代码些习惯了不在controller 捕获异常,导致页面没有错误信息,ajax报error,一脸懵逼。
  同样使用注解形式的也是一样的,区别就是每个方法都手动的写返回页面。会占用业务里面的页面跳转,不建议使用。
  使用继承类方式个人觉得比较好,统一打印异常,统一响应多种请求方式。对一类请求进行不用的异常返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值