码迷,mamicode.com
首页 > 其他好文 > 详细

项目总结(二、统一异常处理)

时间:2015-08-31 13:45:41      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:

二、统一异常处理

我们知道项目如果采用分层结构的话,异常需要一层层往上抛,直至到action层,然后在action处理异常,提示友好的异常信息给用户。如果在action的每个方法中都用try{}catch处理,那么类似的代码会很多,且如果需要在异常处理时新增一些逻辑,则需要更改的地方很多,工作量大,不易于维护。于是项目打算采用struts的拦截器机制,实现统一异常处理。

1、struts配置文件

首先自定义拦截器栈,配置如下:

 <!-- 自定义拦截器栈 -->

 <interceptors>  

     <interceptor name="defaultExceptionInterceptor" class="xxx.DefaultExceptionInterceptor" />  

     <interceptor-stack name="systemDefaultStack">

            <interceptor-ref name="defaultStack" />  

            <interceptor-ref name="defaultExceptionInterceptor" />  

      </interceptor-stack> 

</interceptors>  

<!-- 引用默认的拦截器栈 -->

<default-interceptor-ref name="systemDefaultStack" /> 

2、自定义枚举类(在需要被拦截的方法中加入)

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface ExceptionMeta {

public EOperStatus resultCode() default EOperStatus.FAILURE;

public String message();

}

3、拦截器类(暂时只对ajax请求进行处理)

public class DefaultExceptionInterceptor extends AbstractInterceptor {

private static final long serialVersionUID = -1409945647583201366L;

private final static Logger logger = Logger.getLogger(DefaultExceptionInterceptor.class);

@Override

public String intercept(ActionInvocation invocation) throws Exception {

String result = "";  

        try {  

            result = invocation.invoke();  

        } catch(Exception e) {  

        logger.error(e.getMessage(), e);

        // 异常处理

        ActionContext actionContext = invocation.getInvocationContext();  

               HttpServletRequest request = (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);  

               // 判断是否是ajax请求

        if(this.isAjaxRequest(request)) {

        // 获取请求action类

        Class<?> clazz = invocation.getAction().getClass();

        // 获取请求action对应的方法名

        String methodName = invocation.getProxy().getMethod();

        // 从缓存中查找异常对象是否已存在,若存在,则直接返回,否则将异常对象加入缓存中

        ExceptionMeta exceptionMeta = this.putIfAbsent(clazz, methodName);

        if(exceptionMeta != null) {

        // 将异常错误码和异常消息添加到map中

        Map<String, Object> operateMap = new HashMap<String, Object>(2);  

        operateMap.put("resultCode", exceptionMeta.resultCode().id());  

        operateMap.put("message", exceptionMeta.message());

        // 将map放入值栈,然后在xml中将map数据以json格式返回给前台

        ValueStack stack = invocation.getStack();  

        stack.set("operateMap", operateMap);

        }

        result = "ajaxException";

        }

        }

        return result;

}

/**

* 判断缓存中是否有指定key对应的ExceptionMeta对象,如果有,直接取出缓存中的数据,否则将ExceptionMeta对象加入缓存中

* @param clazz action的class

* @param methodName action对应的方法名

* @return ExceptionMeta

* @throws Exception 异常

*/

private ExceptionMeta putIfAbsent(Class<?> clazz, String methodName) {

try {

String exceptionKey = clazz.getName() + "." + methodName;

ExceptionMeta exceptionMeta = ExceptionCache.get(exceptionKey);

if(exceptionMeta == null) {

Method method = clazz.getMethod(methodName);

if(method != null) {

exceptionMeta = method.getAnnotation(ExceptionMeta.class);

ExceptionCache.put(exceptionKey, exceptionMeta);

}

}

return exceptionMeta;

} catch(Exception e) {}

return null;

}

/**

* 判断请求是否是ajax请求

* @param request HttpServletRequest

* @return true or false

*/

private boolean isAjaxRequest(HttpServletRequest request) {  

            String header = request.getHeader("X-Requested-With");  

            if(header != null && "XMLHttpRequest".equals(header)) {

        return true;  

            }

            return false;  

        }  

}

4、action方法

@ExceptionMeta(resultCode = EOperStatus.FAILURE, message = "xxx")

public String post() throws Exception {

    。。。

}

其中resultCode表示错误码,message为自定义的错误消息,用于提示给用户。

项目总结(二、统一异常处理)

标签:

原文地址:http://my.oschina.net/u/732520/blog/499441

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!