zoukankan      html  css  js  c++  java
  • Struts2、Spring MVC4 框架下的ajax统一异常处理

    本文算是struts2 异常处理3板斧spring mvc4:异常处理 后续篇章,普通页面出错后可以跳到统一的错误处理页面,但是ajax就不行了,ajax的本意就是不让当前页面发生跳转,仅局部刷新,从而改善用户体验,基本思路是:把异常转换成json数据返回,这样ajax的回调函数,就能解析出错误原因。

    一、如何区分ajax请求与普通请求

    打开firefox的调试工具观察一下:

    普通的页面请求

    jquery发起的ajax请求

    对比一下,可以发现jquery发生的ajax请求,Request Headers里多出了x-requested-with,用它就可以判断是否ajax请求。

    二、struts2框架

    a) 先定义一个ajax通用异常

     1 package com.cnblogs.yjmyzz.exception;
     2 
     3 public class AjaxException extends Exception {    
     4 
     5     private static final long serialVersionUID = -8503861588580421151L;
     6 
     7     public AjaxException(String message) {
     8         super(message);
     9     }
    10 
    11 }
    View Code

    b) 然后修改异常拦截器

     1 package com.cnblogs.yjmyzz.interceptor;
     2 import javax.servlet.http.HttpServletRequest;
     3 
     4 import org.apache.logging.log4j.*;
     5 import org.apache.struts2.ServletActionContext;
     6 import org.springframework.util.StringUtils;
     7 import com.cnblogs.yjmyzz.exception.AjaxException;
     8 import com.opensymphony.xwork2.*;
     9 import com.opensymphony.xwork2.interceptor.*;
    10 
    11 public class ExceptionInterceptor extends AbstractInterceptor {
    12 
    13     private static final long serialVersionUID = -6358803554282730952L;
    14     Logger logger = LogManager.getLogger();
    15 
    16     @Override
    17     public String intercept(ActionInvocation ai) throws Exception {
    18         String result = null;
    19         try {
    20             result = ai.invoke();
    21         } catch (Exception e) {
    22             logger.error(ai.toString(), e);
    23             ai.getStack().push(new ExceptionHolder(e));
    24             result = "error";
    25 
    26             HttpServletRequest request = ServletActionContext.getRequest();
    27             String xRequestedWith = request.getHeader("X-Requested-With");
    28             if (!StringUtils.isEmpty(xRequestedWith)) {
    29                 // ajax请求
    30                 // 转换成ajax异常,并放入stack中
    31                 ai.getStack().push(
    32                         new ExceptionHolder(new AjaxException(e.getMessage())));
    33                 result = "ajax-error";
    34             }
    35         }
    36         return result;
    37     }
    38 
    39 }
    View Code

    c) 修改struts.xml文件

     1     <package name="base-default" extends="struts-default">
     2         <global-results>
     3             <result name="ajax-error">/WEB-INF/common/ajax-error.jsp</result>
     4             <result name="error">/WEB-INF/common/error.jsp</result>
     5         </global-results>
     6         <global-exception-mappings>
     7             <exception-mapping exception="com.cnblogs.yjmyzz.exception.AjaxException"
     8                 result="ajax-error" />
     9             <exception-mapping exception="java.lang.Exception"
    10                 result="error" />
    11         </global-exception-mappings>
    12     </package>
    View Code

    即:返回ajax-error,异常类型为AjaxException,则交给/WEB-INF/common/ajax-error.jsp处理

    d) ajax-error.jsp页面

    1 <%@ page contentType="application/json;charset=UTF-8" language="java"%><%@ taglib prefix="s" uri="/struts-tags"%>{"error":"<s:property value="exception" />"}
    View Code

    即:如果出错,最终返回的是json串,类似:{"error":"com.cnblogs.yjmyzz.exception.AjaxException: / by zero"}

    e) 然后调用ajax的地方

     1             $.ajax({
     2                 type:"GET",
     3                 url:"${pageContext.request.contextPath}/rest/orders/x",               
     4                 success: function(data, textStatus, jqXHR){
     5                     if (data.error!=undefined){
     6                         alert("错误:" + data.error);
     7                         return false;
     8                     }
     9                     //正常处理
    10                     alert("ajax请求成功!");
    11                 },
    12                 error: function(jqXHR, textStatus, errorThrown){
    13                     alert('error: ' + textStatus);
    14                 }
    15             });
    View Code

    如果服务端出异常,则ajax调用完成后,会弹出异常信息,否则按正常流程处理

    三、Spring MVC4

    a) 先修改Controller基类里的异常处理方法

     1     @ExceptionHandler
     2     public String exp(HttpServletRequest request, Exception ex) {
     3         String resultViewName = "errors/error";
     4 
     5         // 记录日志
     6         logger.error(ex.getMessage(), ex);
     7 
     8         // 根据不同错误转向不同页面
     9         if (ex instanceof BusinessException) {
    10             resultViewName = "errors/biz-error";
    11         } else {
    12             // 异常转换
    13             ex = new Exception("系统太累了,需要休息!");
    14         }
    15         request.setAttribute("ex", ex);
    16 
    17         String xRequestedWith = request.getHeader("X-Requested-With");
    18         if (!StringUtils.isEmpty(xRequestedWith)) {
    19             // ajax请求
    20             resultViewName = "errors/ajax-error";
    21 
    22         }
    23 
    24         return resultViewName;
    25     }
    View Code

    大致意思是,如果发现是ajax请求,则有异常,则交给"errors/ajax-error"视图处理

    b) ajax-error.jsp页面

    1 <%@ page contentType="application/json;charset=UTF-8" language="java"%><%Exception e = (Exception) request.getAttribute("ex");%>{"error":"<%=e.getClass().getSimpleName()%>","detail":"<%=e.getMessage()%>"}
    View Code

    c) 调用ajax的页面

     1             $.ajax({
     2                 type:"GET",
     3                 url:"${pageContext.request.contextPath}/common-exception",               
     4                 success: function(d, textStatus, jqXHR){
     5                     if (d.error!=undefined){
     6                         alert("错误:" + d.detail);
     7                         return false;
     8                     }
     9                     //其它正常处理
    10                     alert("ajax请求成功!");
    11                 },
    12                 error: function(jqXHR, textStatus, errorThrown){
    13                     alert('error: ' + textStatus);
    14                 }
    15             });
    View Code

    如果服务端返回异常,ajax得到的反馈内容大概是:{"error":"Exception","detail":"系统太累了,需要休息!"}

  • 相关阅读:
    Codeforces 812E Sagheer and Apple Tree
    bzoj 4765: 普通计算姬
    bzoj 4552: [Tjoi2016&Heoi2016]排序
    bzoj 1096: [ZJOI2007]仓库建设
    bzoj 1030: [JSOI2007]文本生成器
    bzoj 1095: [ZJOI2007]Hide 捉迷藏
    JS实现HashMap
    A4纸表格打印
    JAVA字符串格式化-String.format()的使用
    证书打印CSS知识点总结
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/ajax-exception-handle-in-struts2-and-spring-mvc4.html
Copyright © 2011-2022 走看看