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


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值