springmvc+mybatis项目中的统一异常处理器

统一异常处理

1.1     统一异常结果类型(不使用框架配置)

Java中进行异常处理:


一类是可预知的异常,程序员在编码时,主动抛出的异常,为了给用户操作提示,提前检查代码中可能存在异常。

通过开发中,采用自定义的异常类,每个异常类表示每一类异常信息。类需要继承Exception

本系统采用统一异常类,提供一个属性标识异常类

 

另一类是不可预知异常,就是runtimeException异常,通过提高代码编写质量来避免此类异常,也可通过后期测试 人员进行系统功能测试对runtime异常进行避免。

 首先定义统一的异常处理类


此类继承了Exception并包含了ResultInfo

/**

 * 系统抛出异常结果类

 * @author mrt

 *

 */

public class ExceptionResultInfo extends Exception {

 

    /**

     * 系统提示信息

     */

    private ResultInfo resultInfo;

   

    public ExceptionResultInfo(ResultInfo resultInfo) {

       super(resultInfo.getMessage());

       this.resultInfo = resultInfo;

    }

 

    //get方法在转json时使用

    public ResultInfo getResultInfo() {

       return resultInfo;

    }

 

    public void setResultInfo(ResultInfo resultInfo) {

       this.resultInfo = resultInfo;

    }

 

}

 

 

 

如何使用异常类?

在service中要抛出此异常类。

 springmvc+mybatis项目中的统一异常处理器

在action中捕获系统自定义异常,解析系统自定义异常。

 

解析系统自定义异常过程:

如果抛出的ExceptionResultInfo系统自定义异常,直接获取该异常信息即可。

如果不是抛出的ExceptionResultInfo系统自定义异常,重新构造一个“未知错误异常!”。

 

   @RequestMapping("/addsysusersubmit")

    public @ResponseBody

    SubmitResultInfo addsysusersubmit(SysuserQueryVo sysuserQueryVo)

           throws Exception {

       //使用统一异常类

       ResultInfo resultInfo=new ResultInfo();

       resultInfo.setType(ResultInfo.TYPE_RESULT_SUCCESS);

       resultInfo.setMessage("操作成功");

       try {

           userService.inisertSysuser(sysuserQueryVo.getSysuserCustom());

       } catch (Exception e) {

           // 输出异常信息

           e.printStackTrace();

           if(e instanceofExceptionResultInfo)

           {//系统自定义异常

              resultInfo=((ExceptionResultInfo)e).getResultInfo();

           }else{

           //重新构造未知错误异常

              resultInfo=new ResultInfo();

              resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL);

              resultInfo.setMessage("未知错误!");

             

           }                   

       }

        SubmitResultInfosubmitResultInfo=new SubmitResultInfo(resultInfo);

       return submitResultInfo;

    }

 

 

将异常信息或成功信息返回到页面:

统一使用类SubmitResultInfo,提交类的方法统一使用该类型作为返回值类型。

 

表单提交结果类,类封装了ResultInfo对象 。

代码如下:

 

public class SubmitResultInfo {

 

    public SubmitResultInfo(ResultInfo resultInfo){

       this.resultInfo = resultInfo;

    }

   

    //操作结果信息

    private ResultInfo resultInfo;

   

    public ResultInfo getResultInfo() {

       return resultInfo;

    }

 

    public void setResultInfo(ResultInfo resultInfo) {

       this.resultInfo = resultInfo;

    }

      

}

 

 

 

系统提交结果和异常信息结果都封装了ResultInfo对象,这样在前台可以使用一个js方法处理正常和异常的处理结果。

由于action中所有的提交类方法统一返回SubmitResultInfo,所以在页面要统一使用一个方法解析json结果

Js处理方法如下:

 

//提交结果提示信息

function message_alert(data){

    var resultInfo = data.resultInfo;//获取resultInfo信息

 

    var type= resultInfo.type;

    var message= resultInfo.message;

    //alert(message);

    if(type==0){

       $.messager.alert('提示信息',message,'error');

    }else if(type==1){

       $.messager.alert('提示信息',message,'success');

    }else if(type==2){

       $.messager.alert('提示信息',message,'warning');

    }else if(type==3){

       $.messager.alert('提示信息',message,'info');

    }

}

 

 

修改回调函数:

 

function sysusersave_callback(data){

    

     message_alert(data);

 

 

1.2     统一异常处理器(掌握

 

Springmvc提供统一处理器机制,springmvc的前端控制器在调用适配器,去调用action,过程中如果发生异常,前端控制器交给异常处理器进行异常处理。

 

前端控制器源代码:

 springmvc+mybatis项目中的统一异常处理器

1.2.1     自定义异常处理器流程(掌握)

对dao、service及action所抛出的异常进行统一处理,在action中就不需要添加try{}catch{}捕获的代码。

 

springmvc+mybatis项目中的统一异常处理器

1.2.1     自定义异常处理器编写

 

自定义全局异常处理器,实现HandlerExceptionResolver接口

 

 

public classExceptionResolverCustom implements HandlerExceptionResolver {

 

   // json转换器

   // 将异常信息转json

   privateHttpMessageConverter<ExceptionResultInfo> jsonMessageConverter;

 

   // 前端控制器调用此方法执行异常处理

   // handler,执行的action类就包装了一个方法(对应url的方法)

   @Override

   public ModelAndViewresolveException(HttpServletRequest request,

         HttpServletResponseresponse, Object handler, Exception ex) {

 

      // 输出异常信息

      ex.printStackTrace();

      // 转成springmvc底层对象(就是对action方法的封装对象,只有一个方法)

      HandlerMethodhandlerMethod = (HandlerMethod) handler;

      // 取出方法

      Methodmethod = handlerMethod.getMethod();

 

      // 判断方法是否返回json

      // 只要方法上有responsebody注解表示返回json

      // 查询method是否有responsebody注解

      ResponseBody responseBody =AnnotationUtils.findAnnotation(method,

            ResponseBody.class);

      if (responseBody != null) {

         // 将异常信息转json输出

         return this.resolveJsonException(request,response, handlerMethod,

                ex);

 

      }

      // 这里说明action返回的是jsp页面

 

      // 解析异常

      ExceptionResultInfoexceptionResultInfo = resolveExceptionCustom(ex);

 

      // 将异常信息在异常页面显示

      request.setAttribute("exceptionResultInfo",

            exceptionResultInfo.getResultInfo());

 

      // 转向错误页面

      ModelAndViewmodelAndView = newModelAndView();

      modelAndView.addObject("exceptionResultInfo",

            exceptionResultInfo.getResultInfo());

      modelAndView.setViewName("/base/error");// 逻辑视图名

      return modelAndView;

   }

 

   // 异常信息解析方法

   private ExceptionResultInforesolveExceptionCustom(Exception ex) {

      ResultInforesultInfo = null;

      if (ex instanceofExceptionResultInfo) {

         // 抛出的是系统自定义异常

         resultInfo= ((ExceptionResultInfo) ex).getResultInfo();

      }else{

         // 重新构造未知错误异常

         resultInfo= newResultInfo();

         resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL);

         resultInfo.setMessage("未知错误!");

      }

 

      return newExceptionResultInfo(resultInfo);

 

   }

 

   // 将异常信息转json输出

   private ModelAndViewresolveJsonException(HttpServletRequest request,

         HttpServletResponseresponse, Object handler, Exception ex) {

 

      // 解析异常

      ExceptionResultInfoexceptionResultInfo = resolveExceptionCustom(ex);

     

      HttpOutputMessageoutputMessage = newServletServerHttpResponse(response);

     

      try {

         //exceptionResultInfo对象转成json输出

         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();

 

   }

 

   publicHttpMessageConverter<ExceptionResultInfo> getJsonMessageConverter() {

      return jsonMessageConverter;

   }

 

   public voidsetJsonMessageConverter(

         HttpMessageConverter<ExceptionResultInfo>jsonMessageConverter) {

      this.jsonMessageConverter= jsonMessageConverter;

   }

 

}

 

1.2.2     统一异常处理器配置

 

springmvc.xml配置统一异常处理器。   Json转换器中的id要和统一异常处理器中注入的json组件名字相同

<!-- HttpmessageConverters,用于将对象转换为json输出到客户端 -->

   <bean id="jsonMessageConverter"

   class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">

   </bean>

 

   <!-- 统一异常处理类 -->

   <bean id="handlerExceptionResolver"

      class="yycg.base.process.exception.ExceptionResolverCustom">

<!—json组件注入-->

      <property name="jsonMessageConverter" ref="jsonMessageConverter" />

   </bean>

 

 

web.xml中配置:

前端控制器知道全局异常处理器id为handlerExceptionResolver

 

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <init-param>

      <param-name>contextConfigLocation</param-name>

      <param-value>classpath:spring/springmvc.xml</param-value>

    </init-param>

    <init-param>

     <param-name>detectAllHandlerExceptionResolvers</param-name>

     <param-value>false</param-value>

    </init-param>

  </servlet>

detectAllHandlerExceptionResolvers

屏蔽自动注册异常处理器,固定使用bean的id为handlerExceptionResolver的异常处理器。

 

 

1.2.3     统一异常处理器使用

 

系统中所有异常由全局异常处理器处理。

Dao方法向外抛出系统自定义异常。

Service方法向外抛出系统自定义异常。

Action方法向外抛出系统自定义异常。

1.2.4     统一异常处理器测试

 

1、  在action的提交方法中发生异常,由全局异常处理器进行处理。

 

2、在action返回jsp方法中发生异常,由全局异常处理器进行处理。