Spring自定义全局异常处理器

1、自定义异常处理,首先需要一个自定义系统异常类,一般都是继承Exception类,下面列两个自定义的异常类。
简单的异常类:

public class CustomException extends Exception{  
    //异常信息  
    public String message;  

    public CustomException(String message){  
        super(message);  
        this.message = message;  
    }  

    public String getMessage() {  
        return message;  
    }  

    public void setMessage(String message) {  
        this.message = message;  
    }  
} 

复杂点的异常类:这里的ResultInfo是系统封装的结果类

/**
 * 自定义系统异常
 * @author KL
 *
 */
public class ExceptionResultInfo extends Exception{

    //系统统一使用的结果类,包括了 提示信息类型和信息内容
    private ResultInfo resultInfo;

    public ResultInfo getResultInfo() {
        return resultInfo;
    }

    public void setResultInfo(ResultInfo resultInfo) {
        this.resultInfo = resultInfo;
    }

    public ExceptionResultInfo(ResultInfo resultInfo){
        //调用父类Exception的构造函数将resultInfo.getMessage()当做新的异常信息构造
        super(resultInfo.getMessage()); 
        this.resultInfo=resultInfo;
    }
}

2、有了异常类接下来就可以指定异常处理器,当系统遇到异常,最简单的一级一级往上抛出,dao抛给service、service抛给controller,controller抛给前端控制器,前端控制器调用全局异常处理器。

全局异常处理器处理思路:解析出异常类型,如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示。如果该异常类型不是系统自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
Springmvc提供了一个HandlerExceptionResolver接口,只要实现这个接口,Springmvc就会默认为这是一个全局的异常处理。当然一个系统中,只能由一个全局的异常处理。可以看出这个异常处理器将错误信息封装成json数据。

/**
 * 全局异常处理器,全局一般需要在web.xml中配置,关闭spring默认的异常处理器。
 * @author KL
 *
 */
public class ExceptionResolverCustom implements HandlerExceptionResolver{


    // json转换器
    // 将异常信息转json
    private HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter;

    public HttpMessageConverter<ExceptionResultInfo> getJsonMessageConverter() {
        return jsonMessageConverter;
    }
    //依赖注入三种方式之一setter注入
    public void setJsonMessageConverter(
            HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter) {
        this.jsonMessageConverter = jsonMessageConverter;
    }

    // 前端控制器调用此方法执行异常处理
    // handler,执行的action类就包装了一个方法(对应url的方法)
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
        // 输出 异常信息
        ex.printStackTrace();
        // 转成springmvc底层对象(就是对action方法的封装对象,只有一个方法(因为springMvc面向方法开发))
        HandlerMethod handlerMethod=(HandlerMethod) handler;        
        // 取出方法
        Method method = handlerMethod.getMethod();

        // 判断方法是否返回json
        // 只要方法上有responsebody注解表示返回json,
        // 没有responsebody注解是返回jsp页面,两者都会异常处理方式不同,具体如下
        // 查询method是否有responsebody注解

        ResponseBody responseBody=AnnotationUtils.findAnnotation(method, 
                ResponseBody.class);
        if (responseBody!=null) {
            // 将异常信息转json输出
            return this.resolveJsonException(request, response, handlerMethod,
                                ex);
        }

        // 这里说明action返回的是jsp页面
        // 解析异常
        ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex);


        String view = "/base/error";
        //异常代码
        int messageCode = exceptionResultInfo.getResultInfo().getMessageCode();
        //如果是106则跳转到登陆
        if(messageCode==106){
            //跳转到登陆
            view = "/base/login";
        }
        // 将异常信息在异常页面显示
        request.setAttribute("exceptionResultInfo", 
                exceptionResultInfo.getResultInfo());
        // 转向错误页面
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.addObject("exceptionResultInfo", 
                exceptionResultInfo.getResultInfo());
        modelAndView.setViewName(view);//逻辑视图名,error.jsp
        return modelAndView;
    }

    // 异常信息解析方法(一种是系统异常,一种是Runtime异常)
    private ExceptionResultInfo resolveExceptionCustom(Exception ex) {
        ResultInfo resultInfo=null;

        if (ex instanceof ExceptionResultInfo) {
            //抛出系统自定义异常
            resultInfo=((ExceptionResultInfo) ex).getResultInfo();
        }else {
            // 重新构造“未知错误”异常,比如runtimeException
            resultInfo = new ResultInfo();
            resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL);
            resultInfo.setMessage("未知错误!");
        }
        return new ExceptionResultInfo(resultInfo);
    }

    // 将异常信息转json输出
    private ModelAndView resolveJsonException(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod,
            Exception ex) {
        // 异常信息解析
        ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex);

        HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);

        try {
            //将exceptionResultInfo对象转成json输出,这里使用spring异常处理的工具
            jsonMessageConverter.write(exceptionResultInfo, MediaType.APPLICATION_JSON, outputMessage);
        } catch (HttpMessageNotWritableException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return new ModelAndView();
    }

}

3、在springmvc的配置文件中注入这个bean,前端控制器就会调用这个全局异常处理器。

<!-- json转换器 -->
    <bean id="jsonMessageConverter"
        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
    </bean>

    <!-- 统一异常处理类,需要在web.xml中将默认的异常处理器关闭 -->
    <bean id="handlerExceptionResolver"
        class="yycg.base.process.exception.ExceptionResolverCustom">
        <!-- 注入一个json转换器 -->
        <property name="jsonMessageConverter" ref="jsonMessageConverter" />
    </bean>

4、接下来就可以把异常一层一层抛出如下
dao:dao抛出异常给service

public interface SysuserMapperCustom {

    //查询用户列表
    public List<SysuserCustom> findSysuserList(SysuserQueryVo sysuserQueryVo) throws Exception; 
    //查询总数
    public int findSysuserCount(SysuserQueryVo sysuserQueryVo) throws Exception;
    }

service:service抛出异常给Controller

public interface UserService {

    // 根据条件查询用户信息
    public List<SysuserCustom> findSysuserList(SysuserQueryVo sysuserQueryVo)
            throws Exception;

    // 根据条件查询列表的总数
    public int findSysuserCount(SysuserQueryVo sysuserQueryVo) throws Exception;
    }

Controller:Controller抛出给DispatcherServlet然后交由统一异常处理

@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/sysuserquery")
    public String queryuser(Model model) throws Exception{
    }

这篇文章贴出了部分代码,主要想阐明整体思路,让我们新手对springMVC的自定义异常处理器有一个好的认识,同时自己做一些笔记,增强记忆,本人菜鸟一枚,如有不正确的地方希望大神指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值