SpringMVC的控制器抛异常

本文介绍了如何在SpringMVC中通过自定义`SimpleMappingExceptionResolver`子类实现控制器层的统一异常处理。详细讲解了配置步骤,包括设置异常映射、默认错误视图和HTTP状态码。此外,还展示了如何根据不同请求类型返回JSON或JSP格式的错误信息,提高代码可维护性和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习过程中,dao层会经常往service层抛异常,再向controller层抛出异常。此时要么控制器层异常继续抛向页面, 要么在控制器层中做大量异常判断,返回相应视图。无法统一管理控制器层的异常,而不是每个控制器都做异常判断。

由网上资料我发现了一个办法:通过SimpleMappingExceptionResolver接口实现异常处理。

有2步

1. 创建SimpleMappingExceptionResolver子类,并实现doResolveException 方法。

2. 在spring 配置文件中配置bean信息。

spring配置:

<!-- 异常处理 -->
    <bean id="exceptionResolver"
        class="com.**.**.exception.CustomSimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <!-- 不同异常跳转不同异常页面 -->
                <prop key="com.**.**.exception.CustomException">error/CE</prop>
                <prop key="com.**.**.exception.CustomerLoginTimeOutException">error/CustomerLoginTimeOutException</prop>
                <prop key="com.**.**.exception.PropertyLoginTimeOutException">error/PropertyLoginTimeOutException</prop>
            </props>
        </property>
        <!-- 默认错误页面,当找不到上面mappings中指定的异常对应视图时,使用本默认配置 -->
        <property name="defaultErrorView" value="/error/500" />
        <!-- 默认HTTP状态码 -->
        <property name="defaultStatusCode" value="500" />
    </bean>

CustomSimpleMappingExceptionResolver 类配置:

//import com.alibaba.fastjson.support.spring.FastJsonJsonView;
public class CustomSimpleMappingExceptionResolver extends SimpleMappingExceptionResolver {
    static Log log = LogFactory.getLog(CustomSimpleMappingExceptionResolver.class);
 
    @Override
    protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception ex) {
        // Expose ModelAndView for chosen error view.
        String viewName = determineViewName(ex, request);
        HandlerMethod mathod = (HandlerMethod) handler;
        ResponseBody body = mathod.getMethodAnnotation(ResponseBody.class);
        // 判断有没有@ResponseBody的注解没有的话调用父方法
        if (body == null) {
            // return super.doResolveException(request, response, handler, ex);
            Integer statusCode = determineStatusCode(request, viewName);
            if (statusCode != null) {
                applyStatusCodeIfPossible(request, response, statusCode);
            }
            request.setAttribute("errorMsg", ex.getMessage());
            return getModelAndView(viewName, ex, request);
        }
        ModelAndView mv = new ModelAndView();
 
        if (viewName != null) {// JSP格式返回
            // if (!(request.getHeader("accept").indexOf("application/json") > -1 ||
            // (request
            // .getHeader("X-Requested-With")!= null && request
            // .getHeader("X-Requested-With").indexOf("XMLHttpRequest") > -1))) {
            // // 如果不是异步请求
            // // Apply HTTP status code for error views, if specified.
            // // Only apply it if we're processing a top-level request.
            // Integer statusCode = determineStatusCode(request, viewName);
            // if (statusCode != null) {
            // applyStatusCodeIfPossible(request, response, statusCode);
            // }
            // request.setAttribute("errorMsg", ex.getMessage());
            // return getModelAndView(viewName, ex, request);
            // } else {// JSON格式返回
            try {
                // 设置ContentType
                log.info(ex.getMessage());
                response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                // 避免乱码
                response.setCharacterEncoding("UTF-8");
                response.setHeader("Cache-Control", "no-cache, must-revalidate");
                PrintWriter writer = response.getWriter();
                JSONObject jo = new JSONObject();
                if (ex instanceof BusinessException) {
                    jo.put("code", ((BusinessException) ex).getCode());
                    jo.put("message", ((BusinessException) ex).getMessage());
                    if (null != ((BusinessException) ex).getData()) {
                        jo.put("data", ((BusinessException) ex).getData());
                    }
                }
                // else if(ex instanceof AgentLoginTimeOutException){
                // jo.put("code", 8001);
                // jo.put("message", ((AgentLoginTimeOutException)ex).getMessage());
                // }else if(ex instanceof ManagerLoginTimeOutException){
                // jo.put("code", 8001);
                // jo.put("message", ((ManagerLoginTimeOutException)ex).getMessage());
                // }else if(ex instanceof CustomerLoginTimeOutException){
                // jo.put("code", 8001);
                // jo.put("message", ((CustomerLoginTimeOutException)ex).getMessage());
                // }
                log.info(jo.toString());
                // System.out.println(jo.toString());
                writer.write(jo.toString());
                writer.flush();
            } catch (Exception e) {
            }
            // return getModelAndView(viewName, ex, request);
            // 或者使用view视图返回
            // FastJsonJsonView view = new FastJsonJsonView();
            // Map<String, Object> attributes = new HashMap<String, Object>();
            // attributes.put("success", Boolean.FALSE);
            // attributes.put("msg", ex.getMessage());
            // view.setAttributesMap(attributes);
            // mv.setView(view);
            // return mv;
            return mv;
 
            // }
        } else {
            return mv;
        }
    }
}

开发过程中要留意一下异常统一配置,写代码习惯了不在controller 捕获异常,导致页面没有错误信息,ajax报error,一脸懵逼。使用继承类方式我觉得比较好,统一打印异常,统一响应多种请求方式。对一类请求进行不用的异常返回。
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值