您的位置:首页 > 编程语言 > Java开发

struts2之ajax请求返回自定义错误信息

2016-01-07 00:25 766 查看
struts2的异常处理机制是在发生异常时,跳转到我们指定的页面,并显示出相应的异常信息,如 actionErr...等信息 但如果是异步请求出错,这种方 式就蛋疼了。struts2默认的异常处理机制是这样的:

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;
}
运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: