• 统一的异常处理和自定义的全局异常处理器的配置使用


    统一的异常处理和自定义的全局异常处理器的配置使用

    一、统一的异常处理

    1、自定义异常处理类,继承了exception

    package yycg.base.process.result;
    
    
    /**
     * 自定义系统异常类
     */
    public class ExceptionResultInfo extends Exception {
    
        // 系统统一使用的结果类,包括了 提示信息类型和信息内容
        private ResultInfo resultInfo;
    
        public ExceptionResultInfo(ResultInfo resultInfo) {
            super(resultInfo.getMessage());
            this.resultInfo = resultInfo;
        }
    
        public ResultInfo getResultInfo() {
            return resultInfo;
        }
    
        public void setResultInfo(ResultInfo resultInfo) {
            this.resultInfo = resultInfo;
        }
    
    }

     2、统一的异常处理类,包括异常类型,异常信息

    package yycg.base.process.result;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import yycg.util.ResourcesUtil;
    
    /**
     * 系统提示信息封装类
     * @author mrt
     *
     */
    public class ResultInfo
    {
        public static final int TYPE_RESULT_FAIL = 0;//失败
        public static final int TYPE_RESULT_SUCCESS = 1;//成功
        public static final int TYPE_RESULT_WARN = 2;//警告
        public static final int TYPE_RESULT_INFO = 3;//提示信息
        
        public ResultInfo(){}
    
        /**
         * 消息提示类型
         */
        private int type;
            
        
        /**
         * 提示代码
         */
        private int messageCode;
        
           
        /**
         * 提示信息
         */
        private String message;
        
        
        /**
         * 提示信息明细列表
         */
        private List<ResultInfo> details;
        
        public List<ResultInfo> getDetails() {
            return details;
        }
    
    
        public void setDetails(List<ResultInfo> details) {
            this.details = details;
        } 
        
        /**
         * 提示消息对应操作的序号,方便用户查找问题,通常用于在批量提示信息中标识记录序号
         */
        private int index;
        
        
        /**
         * 提交后得到到业务数据信息从而返回给页面
         */
        private Map<String,Object> sysdata = new HashMap<String, Object>();
        
        /**
         * 构造函数,根据提交信息代码messageCode获取提示信息
         * @param MESSAGE
         */
        public ResultInfo(final int type,int messageCode,String message){
            this.type = type;
            this.messageCode = messageCode;
            this.message = message;
        }
        
       
        public int getMessageCode() {
            return messageCode;
        }
    
    
    
    
        public void setMessageCode(int messageCode) {
            this.messageCode = messageCode;
        }
    
    
        public String getMessage() {
            return message;
        }
        
        
        public void setMessage(String message) {
            this.message = message;
        }
    
    
        public int getType() {
            return type;
        }
    
        public void setType(int type) {
            this.type = type;
        }
    
        public boolean isSuccess(){
            if(this.type == TYPE_RESULT_SUCCESS){
                return true;
            }
            return false;
        }
    
        public int getIndex() {
            return index;
        }
        public void setIndex(int index) {
            this.index = index;
        }
        
            
        
    
    
        public Map<String, Object> getSysdata() {
            return sysdata;
        }
    
    
        public void setSysdata(Map<String, Object> sysdata) {
            this.sysdata = sysdata;
        }
    
    
    
    }

    3、操作结果信息返回到页面进行提示的包装类

    package yycg.base.process.result;
    
    
    /**
     * 系统提交结果结果类型
     * @author Thinkpad
     *
     */
    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;
        }
            
    }

    使用说明:

    【1】
    ExceptionResultInfo 类继承了exception,同时添加了resultInfo属性
    resultInfo用来标记异常出错类型(type)和记录异常信息(message)
    例子:
    resultInfo.setType(resultInfo.TYPE_RESULT_FAIL);//0错误 1成功 2警告3提示
    resultInfo.setMessage("账号已存在,请重新输入!");
    throw new ExceptionResultInfo(resultInfo);

    【2】
    在将json异常信息放回到页面时使用SubmitResultInfo类
    return new SubmitResultInfo(resultInfo);

     

    二、自定义全局异常处理器,springmvc 提供接口:HandlerExceptionResolver

    1、自定义的异常处理器类,实现接口:handlerExceptionResolver

    package yycg.base.process.exception;
    
    import java.io.IOException;
    import java.lang.reflect.Method;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.core.annotation.AnnotationUtils;
    import org.springframework.http.HttpOutputMessage;
    import org.springframework.http.MediaType;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.converter.HttpMessageNotWritableException;
    import org.springframework.http.server.ServletServerHttpResponse;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.HandlerExceptionResolver;
    import org.springframework.web.servlet.ModelAndView;
    
    import yycg.base.process.result.ExceptionResultInfo;
    import yycg.base.process.result.ResultInfo;
    
    /**
     * 
     * <p>
     * Title: ExceptionResolverCustom
     * </p>
     * <p>
     * Description:全局异常处理器
     * </p>
     * <p>
     * Company: www.itcast.com
     * </p>
     * 
     * @author
     * @date 
     * @version 1.0
     */
    public class ExceptionResolverCustom implements HandlerExceptionResolver {
    
        // json转换器
        // 将异常信息转json
        private HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter;
    
        // 前端控制器调用此方法执行异常处理
        // handler,执行的action类就包装了一个方法(对应url的方法)
        @Override
        public ModelAndView resolveException(HttpServletRequest request,
                HttpServletResponse response, Object handler, Exception ex) {
    
            // 输出 异常信息
            ex.printStackTrace();
            // 转成springmvc底层对象(就是对action方法的封装对象,只有一个方法)
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            // 取出方法
            Method method = 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);
    
            }
            /**
             *1如果上面是可预知异常,type和message都已经设置有值,return ModelandView
              *直接将可预知异常返回到请求页面的回调函数,不再执行以下代码end
              *2如果是未知异常,则执行以下代码,构建未知异常,跳转到error页面显示
            */
            // 这里说明action返回的是jsp页面
    
            // 解析异常
            ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex);
    
            // 将异常信息在异常页面显示
            request.setAttribute("exceptionResultInfo",
                    exceptionResultInfo.getResultInfo());
    
            // 转向错误页面
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("exceptionResultInfo",
                    exceptionResultInfo.getResultInfo());
            modelAndView.setViewName("/base/error");// 逻辑视图名
            return modelAndView;
        }
    //------------------------------------------------------------------------------------
        // 异常信息解析方法
        private ExceptionResultInfo resolveExceptionCustom(Exception ex) {
            ResultInfo resultInfo = null;
            if (ex instanceof ExceptionResultInfo) {
                // 抛出的是系统自定义异常
                resultInfo = ((ExceptionResultInfo) ex).getResultInfo();
            } else {
                // 重新构造“未知错误”异常
                resultInfo = new ResultInfo();
                resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL);
                resultInfo.setMessage("未知错误!");
            }
    
            return new ExceptionResultInfo(resultInfo);
    
        }
    //------------------------------------------------------------------------------------
        // 将异常信息转json输出
        private ModelAndView resolveJsonException(HttpServletRequest request,
                HttpServletResponse response, Object handler, Exception ex) {
    
            // 解析异常  (解析返回异常是自定义异常还是未知异常)
            ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex);
            
            HttpOutputMessage outputMessage = new ServletServerHttpResponse(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();
    
        }
    
        public HttpMessageConverter<ExceptionResultInfo> getJsonMessageConverter() {
            return jsonMessageConverter;
        }
    
        public void setJsonMessageConverter(
                HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter) {
            this.jsonMessageConverter = jsonMessageConverter;
        }
    
    }

    2、配置

      ①在springmvc.xml文件中配上json转换器(spring-web jar提供),并注入上面自定义的异常处理器类中,用于异常信息转换为json

     <!-- 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中声明屏蔽默认的异常处理器,使自定义的异常处理器生效

    <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring/springmvc.xml</param-value>
            </init-param>
            <!-- 屏蔽springmvc自动注册的异常处理器 -->
            <init-param>
                <param-name>detectAllHandlerExceptionResolvers</param-name>
                <param-value>false</param-value>
            </init-param>

    说明: 

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

    2、在springmvc.xml配置统一异常处理器。
    <!-- 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>


    3、在web.xml中配置:
    【前端控制器知道全局异常处理器id为handlerExceptionResolver
    detectAllHandlerExceptionResolvers:
    屏蔽自动注册异常处理器,固定使用bean的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>

  • 相关阅读:
    如何使用EF?
    在一般处理程序中使用session
    C# base64 加密解密
    C#操作WMI文章汇总
    ASP.NET图片防盗链(使用一般处理程序)
    前台生成验证码
    .正则
    iframe标签的初试
    sqli-labs5-10(全程sqlmap)
    sql注入文件写入和读取
  • 原文地址:https://www.cnblogs.com/fengjunming/p/7991878.html
Copyright © 2020-2023  润新知