struts2之ajax请求返回自定义错误信息
2016-01-07 00:25
766 查看
struts2的异常处理机制是在发生异常时,跳转到我们指定的页面,并显示出相应的异常信息,如 actionErr...等信息 但如果是异步请求出错,这种方 式就蛋疼了。struts2默认的异常处理机制是这样的:
1)struts.xml中配置
2)出错则跳到指定页面err.jsp
3)到这里,如果我们要返回一个 JSON 字符串呢。struts中如果要返回 JSON 是将 result 标签的 type 设置为 json 如下:
继续我们的
那如果把我们的错误页面
的 type 也改为 json 呢 ,嗯 先照着撸先,配置文件修改如下
运行一下,看看结果
看到这个 眼瞎~~ 什么鬼东西呃 程序员的命,结果分析先
1)struts2 返回的 JSON 数据 是读取 【栈顶】 的数据 进行序列化返回客户端的.
2) 知道了这个 就好办了 看看发生错误时 【栈顶】都放了 什么东东
4)发生错误时的 栈顶 数据 点击 第2步错误页面中的 [Ddbug] 得到如下图:
从图上的信息可以得出结论:
1 ) struts2 对我们抛出的 错误信息 进行 了 封装 形成一个新的异常类 ExceptionHolder
2 ) 将这个 新异常类 对象压入 【栈顶】
可以看出 上面那堆乱七八糟的信息是这个ExceptionHolder 搞的,如果压入【栈顶】的数据直接是我们抛出的
自定义错误类对象 不就实现我们的目 的了吗
↖(▔^▔)↗ ,要实现这个,首先要了解 struts2 的错误拦截器
5) struts2 拦截的实现细节 和 关键点 点开源码中的 struts-default.xml 默认拦截器栈 如下 :
红线标出的就是 异常拦截器 当发生错误 或 抛出自定义错误时 将会被这个拦截器拦截(具体原理这里先不谈)。该拦截器对应的实现类:
该类核心代码 如下:
到这里 就可以下手了 自定义一个 异常拦截器类 继承 默认的拦截器类 重写 Interceptor 方法就可以了 如果是 ajax 请求 就只压入我们抛出的异常即可
6) 自定义一个 异常拦截器类 继承 默认的拦截器类 重写
Interceptor 方法 实现代码如下:
7)最后修改 struts.xml 配置文件 如下:
Action 中 代码:
1)struts.xml中配置
<global-results> <!-- 返回指定错误页 --> <result name="myExcetion">err.jsp</result> </global-results> <!-- 错误映射结果 --> <global-exception-mappings> <exception-mapping result="myExcetion" exception="yuan.utils.MyExcetion"> </exception-mapping> </global-exception-mappings> <action name="demoerr" class="yuan.action.ErrAction"> <result name="userData" type="json"></result> </action>
2)出错则跳到指定页面err.jsp
3)到这里,如果我们要返回一个 JSON 字符串呢。struts中如果要返回 JSON 是将 result 标签的 type 设置为 json 如下:
<result name="userData" type="json"></result>想想还是.net mvc 中方便的多 直接一个方法 return json( userData ) 搞定 ╮(╯Д╰)╭扯远了
继续我们的
那如果把我们的错误页面
的 type 也改为 json 呢 ,嗯 先照着撸先,配置文件修改如下
<!-- 全局界面 --> <global-results> <!-- 返回指定错误 --> <!-- 这里返回类型 为 json! --> <result name="myExcetion" type="json"> </result> </global-results>
运行一下,看看结果
看到这个 眼瞎~~ 什么鬼东西呃 程序员的命,结果分析先
1)struts2 返回的 JSON 数据 是读取 【栈顶】 的数据 进行序列化返回客户端的.
2) 知道了这个 就好办了 看看发生错误时 【栈顶】都放了 什么东东
4)发生错误时的 栈顶 数据 点击 第2步错误页面中的 [Ddbug] 得到如下图:
从图上的信息可以得出结论:
1 ) struts2 对我们抛出的 错误信息 进行 了 封装 形成一个新的异常类 ExceptionHolder
2 ) 将这个 新异常类 对象压入 【栈顶】
可以看出 上面那堆乱七八糟的信息是这个ExceptionHolder 搞的,如果压入【栈顶】的数据直接是我们抛出的
自定义错误类对象 不就实现我们的目 的了吗
↖(▔^▔)↗ ,要实现这个,首先要了解 struts2 的错误拦截器
5) struts2 拦截的实现细节 和 关键点 点开源码中的 struts-default.xml 默认拦截器栈 如下 :
红线标出的就是 异常拦截器 当发生错误 或 抛出自定义错误时 将会被这个拦截器拦截(具体原理这里先不谈)。该拦截器对应的实现类:
该类核心代码 如下:
到这里 就可以下手了 自定义一个 异常拦截器类 继承 默认的拦截器类 重写 Interceptor 方法就可以了 如果是 ajax 请求 就只压入我们抛出的异常即可
6) 自定义一个 异常拦截器类 继承 默认的拦截器类 重写
Interceptor 方法 实现代码如下:
package yuan.interceptor; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.StrutsStatics; import yuan.utils.MyExcetion; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig; import com.opensymphony.xwork2.interceptor.ExceptionHolder; import com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor; import com.opensymphony.xwork2.util.ResolverUtil.IsA; import com.opensymphony.xwork2.util.ValueStack; public class MyExcetionInterceptor extends ExceptionMappingInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { String result; try { result = invocation.invoke(); } catch (Exception e) { List<ExceptionMappingConfig> exceptionMappings = invocation .getProxy().getConfig().getExceptionMappings(); ExceptionMappingConfig mappingConfig = this .findMappingFromExceptions(exceptionMappings, e); // 获取httpRequest ActionContext actionContext = invocation.getInvocationContext(); HttpServletRequest request = (HttpServletRequest) actionContext .get(StrutsStatics.HTTP_REQUEST); // 判断是否是异步请求 if (isAjaxRequest(request)) { if (mappingConfig != null && mappingConfig.getResult() != null) { Map parameterMap = mappingConfig.getParams(); invocation.getInvocationContext().setParameters( new HashMap<String, Object>(parameterMap)); result = mappingConfig.getResult(); // 获取值栈 压入自己的错误信息 if (e.getClass() == MyExcetion.class) { ValueStack vs = invocation.getStack(); vs.push(e); } else { // 不是自己抛出的异常 信息 则可能是系统发生错误 这里 可按照个人 习惯 自行处理.... } } else { throw e; } // 默认的处理 } else { if (isLogEnabled()) { handleLogging(e); } if (mappingConfig != null && mappingConfig.getResult() != null) { Map parameterMap = mappingConfig.getParams(); invocation.getInvocationContext().setParameters( new HashMap<String, Object>(parameterMap)); result = mappingConfig.getResult(); publishException(invocation, new ExceptionHolder(e)); } else { throw e; } } } return result; } /** * 判断是否是ajax请求 * * @param request * @return */ private boolean isAjaxRequest(HttpServletRequest request) { return (request.getHeader("X-Requested-With") != null && "XMLHttpRequest" .equals(request.getHeader("X-Requested-With").toString())); } }
7)最后修改 struts.xml 配置文件 如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="default" namespace="/" extends="json-default"> <interceptors> <interceptor name="myexception" class="yuan.interceptor.MyExcetionInterceptor"></interceptor> <interceptor-stack name="myStack"> <!-- <interceptor-ref name="exception" /> --> <!-- 使用自定义的 错误拦截器 --> <interceptor-ref name="myexception" /> <interceptor-ref name="alias" /> <interceptor-ref name="servletConfig" /> <interceptor-ref name="i18n" /> <interceptor-ref name="prepare" /> <interceptor-ref name="chain" /> <interceptor-ref name="scopedModelDriven" /> <interceptor-ref name="modelDriven" /> <interceptor-ref name="fileUpload" /> <interceptor-ref name="checkbox" /> <interceptor-ref name="multiselect" /> <interceptor-ref name="staticParams" /> <interceptor-ref name="actionMappingParams" /> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param> </interceptor-ref> <interceptor-ref name="conversionError" /> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="debugging" /> </interceptor-stack> </interceptors> <!-- 全局界面 --> <global-results> <!-- 返回指定错误 --> <!-- 这里返回类型 为 json! --> <result name="myExcetion" type="json"> <!-- 只将指定的属性序列化 为 json 字符串 这个看个人习惯 --> <!-- <param name="includeProperties">mymessage,code</param> --> </result> </global-results> <!-- 错误映射结果 --> <global-exception-mappings> <exception-mapping result="myExcetion" exception="yuan.utils.MyExcetion"> </exception-mapping> </global-exception-mappings> <action name="demoerr" class="yuan.action.ErrAction"> <!-- 引用新的 拦截器栈 【也可以直接用自定义的 异常异常类 去去覆盖源码中的配置文件 】 看个人习惯 --> <interceptor-ref name="myStack" /> <result name="userData" type="json"></result> </action> </package> </struts>
Action 中 代码:
@Override public String execute() throws Exception { try { int d = 1 / 0; } catch (Exception e) { // e.printStackTrace(); // 抛出自定义错误 MyExcetion ex = new MyExcetion(); ex.setMymessage("我的错误信息"); ex.setCode(12345); throw ex; } return NONE; }运行结果:
相关文章推荐
- 关于java中路径的思考:相对路径,以及在不同场景下的区别 classpath
- Java电话号码和手机号码正则验证
- 反射的应用
- Java Day8
- java之辨析Session Cookie Servletcontext
- Java开发中的23种设计模式详解
- Java的Web项目使用DWR简单配置说明
- 数据格式化###,###.##
- Spring 框架 Quick Start
- 使用eclipse创建maven聚合项目
- Google java编程风格指南
- 应届生参加蜂窝教育Java培训获8.5k入职软通动力
- Hibernate工作原理及优缺点详解
- Struts2 配置文件result的name属性和type属性
- java debug 信息
- java中OutOfMemory种类和解决方法
- Java简单爬虫系列(3)---正则表达式和Java正则API的使用
- spring源码阅读笔记(二)——自定义标签
- eclipse设置和优化
- springmvc提交带日期的表单400