今天在整理之前的项目的时候想着有的action层没有做异常处理,于是想着自定义拦截器处理一下未拦截的异常。

代码:

package cn.xm.exam.action.safeHat;

import java.util.HashMap;
import java.util.Map; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller; import com.opensymphony.xwork2.ActionSupport; @Controller
@Scope("prototype")
public class SafeHatAction extends ActionSupport {
private static final Logger log = LoggerFactory.getLogger(SafeHatAction.class);
private Map<String, Object> response; public SafeHatAction() {
log.info("SafeHatAction init.........");
} public String test1() {
response = new HashMap();
response.put("ttt", "tttttt");
return SUCCESS;
} public String test2() {
response = new HashMap();
response.put("ttt", "tttttt");
int i = 1/0;
return SUCCESS;
} public Map<String, Object> getResponse() {
return response;
} public void setResponse(Map<String, Object> response) {
this.response = response;
} }

1.异常在Action层未做处理的情况:

由于在web.xml中定义了500错误的页面,因此跳转到500页面,如下:

    <!-- 500页面 -->
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>

  可是上面终究不够友好。

2.自定义拦截器处理全局异常

(1)自定义拦截器

package cn.xm.exam.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor; public class ExceptionInterception implements Interceptor {
private static final Logger log = LoggerFactory.getLogger(ExceptionInterception.class);
/**
*
*/
private static final long serialVersionUID = 2268867259828199826L; @Override
public void destroy() { } @Override
public void init() { } @Override
public String intercept(ActionInvocation arg0) throws Exception {
log.info("enter ExceptionInterception intercept ... ");
String result = "";
try {
result = arg0.invoke();
log.info("result -> {}", result);
} catch (Throwable e) {
log.error("未处理的异常在拦截器被拦截,class:{}", arg0.getAction().getClass(), e);
throw new Exception(e);
}
log.debug("exit ExceptionInterception intercept ... ");
return result;
} }

  arg0.invoke();是调用我们的action的方法,其返回值就是action的返回值,相当于放行;捕捉到异常之后进行一个简单的异常记录之后再次抛出异常,再次抛出异常是为了跳到500页面;如果有需要可以自己再写一个页面提示错误已经被记录等信息,捕捉到异常之后返回到此页面。 

(2)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>
<constant name="struts.i18n.encoding" value="utf-8"></constant>
<constant name="devMode" value="true"></constant>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<!-- 配置拦截的后缀 -->
<constant name="struts.action.extension" value="action,do" />
<!-- 与spring整合 -->
<constant name="struts.objectFactory" value="spring"></constant> <package name="interceptPackage" extends="json-default"> <!-- 拦截器 -->
<interceptors>
<!-- 定义刚才的拦截器 -->
<interceptor name="exceptionInterceptor"
class="cn.xm.exam.interceptor.ExceptionInterception"></interceptor>
<!-- 定义拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 拦截器栈里面可以引用另外一个拦截器,也可以引用另外一个拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="exceptionInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 这句是设置所有Action自动调用的拦截器堆栈 -->
<default-interceptor-ref name="myStack" />
</package> <!-- 2018-11-11引入的二开action -->
<include file="struts/safeHat.xml"></include> </struts>

自定义的package继承上面的package(package具有多重继承的特性,safeHalt会继承其所有父类),例如:safeHat.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="safeHalt" namespace="/" extends="interceptPackage">
<!-- 全局结果集,将response转换为json传到前台 -->
<global-results>
<result name="success" type="json">
<param name="root">response</param>
</result>
</global-results> <action name="safeHat_*" class="safeHatAction" method="{1}"></action>
</package>
</struts>

 (3)继续访问上面的错误action进行测试:

查看记录的错误日志:

2018-11-01 23:09:30 [cn.xm.exam.interceptor.ExceptionInterception]-[ERROR] 未处理的异常在拦截器被拦截,class:class cn.xm.exam.action.safeHat.SafeHatAction
java.lang.ArithmeticException: / by zero
at cn.xm.exam.action.safeHat.SafeHatAction.test2(SafeHatAction.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:871)
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1294)
at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:117)
at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:108)
at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1370)
at ognl.ASTMethod.getValueBody(ASTMethod.java:91)
  ........

至此实现了简单的全局异常处理。

3.补充:根据ajax请求与普通请求回传不同数据 (捕捉到异常之后进行提示)

3.1首先明白ajax请求与普通请求的不同:

AJAX请求头会多一个x-requested-with参数,值为XMLHttpRequest

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

3.2修改上面的拦截器

package cn.xm.exam.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor; public class ExceptionInterception implements Interceptor {
private static final Logger log = LoggerFactory.getLogger(ExceptionInterception.class);
/**
*
*/
private static final long serialVersionUID = 2268867259828199826L; @Override
public void destroy() { } @Override
public void init() { } @Override
public String intercept(ActionInvocation arg0) throws Exception {
log.info("enter ExceptionInterception intercept ... ");
String result = "";
try {
result = arg0.invoke();
log.info("result -> {}", result);
} catch (Throwable e) {
log.error("未处理的异常在拦截器被拦截,class:{}", arg0.getAction().getClass(), e);
return "interceptorError";
}
log.debug("exit ExceptionInterception intercept ... ");
return result;
} }

struts全局结果集:

    <package name="interceptPackage" extends="json-default">
<!-- 拦截器 -->
<interceptors>
<!-- 定义刚才的拦截器 -->
<interceptor name="exceptionInterceptor"
class="cn.xm.exam.interceptor.ExceptionInterception"></interceptor>
<!-- 定义拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 拦截器栈里面可以引用另外一个拦截器,也可以引用另外一个拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="exceptionInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 这句是设置所有Action自动调用的拦截器堆栈 -->
<default-interceptor-ref name="myStack" /> <!-- 拦截器拦截的全局异常 -->
<global-results>
<result name="interceptorError">/interceptorError.jsp</result>
</global-results>
</package>

错误JSP:interceptorError.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
if (request.getHeader("X-Requested-With") != null
&& "XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
response.setContentType("application/javascript;charset=utf-8");
out.write("错误提醒:系统发生错误,系统已经记录错误日志");
} else {
response.setContentType("text/html;charset=\"utf-8\"");
out.write(
"<html><head><meta charset=\"utf-8\" /><title>错误提醒</title></head><body><br /><span style=\"font-weight: bold;font-size: 20px;margin: 20px;\">系统发生错误!日志已经记录!</span> <br /></body></html>");
}
%>

测试:

(1)普通页面访问:

(2)ajax请求测试:

js代码:

<script>
+function(){
$.post("/Exam/safeHat_test2.do",function(response){
alert(response);
},"text");
}();
</script>

结果:

拦截器的使用参考我另一篇博客:https://www.cnblogs.com/qlqwjy/p/7190784.html

Struts2自定义拦截器处理全局异常的更多相关文章

  1. Struts2自定义拦截器Interceptor以及拦截器登录实例

    1.在Struts2自定义拦截器有三种方式: -->实现Interceptor接口 public class QLInterceptorAction implements Interceptor ...

  2. struts2自定义拦截器 设置session并跳转

    实例功能:当用户登陆后,session超时后则返回到登陆页面重新登陆. 为了更好的实现此功能我们先将session失效时间设置的小点,这里我们设置成1分钟 修改web.xml view plainco ...

  3. 【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】

    一.struts2文件上传 1.上传文件的时候要求必须使得表单的enctype属性设置为multipart/form-data,把它的method属性设置为post 2.上传单个文件的时候需要在Act ...

  4. Struts2自定义拦截器

    1. 需求 自定义拦截器实现,用户登录的访问控制. 2. 定义拦截器类 public class LoginInterceptor extends AbstractInterceptor { @Ove ...

  5. springboot(四)拦截器和全局异常捕捉

    github代码:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service 全部 ...

  6. 12.Struts2自定义拦截器

    12.自定义拦截器        拦截器是Struts2的一个重要特性.因为Struts2的大多数核心功能都是通过拦截器实现的. 拦截器之所以称之为“拦截器”,是因为它可以拦截Action方法的执行, ...

  7. Struts2 自定义拦截器

    自定义拦截器(权限管理),包含了对ajax和表单请求的拦截 package com.interceptor; import java.io.IOException; import java.io.Pr ...

  8. struts2自定义拦截器与cookie整合实现用户免重复登入

    目的:测试开发时,为了减少用户登入这个繁琐的登入验证,就用struts2做了个简单的struts2拦截器,涉及到了与cookie整合,具体的看代码 结构(两部份)=struts2.xml+自定义拦截器 ...

  9. 5、Struts2自定义拦截器

    一.拦截器相关知识 1.Struts2框架剖析 Holly版本生活案例: 影视公司(拍电影)    ActionMapper 传媒公司(包装明星) ActionMapping 明星           ...

随机推荐

  1. C# 对象与JSON字符串互相转换的三种方式

    C# 对象与JSON字符串互相转换的三种方式 JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式. 关于内存对象和JSON字符串的相互转换, ...

  2. ACM-ICPC 2018 焦作赛区网络预赛 E Jiu Yuan Wants to Eat (树链剖分+线段树)

    题目链接:https://nanti.jisuanke.com/t/31714 题意:给你一棵树,初始全为0,有四种操作: 1.u-v乘x    2.u-v加x   3. u-v取反  4.询问u-v ...

  3. IDEA在debug时修改变量值

    IDEA在debug调试时修改变量值 例如以下代码: int y1 = 0; anchor.setDy1(y1); 在代码中,这个y1永远是0,但是y1本身是个变量 debug的时候获取到这个属性,并 ...

  4. 集成Android免费语音合成功能(在线、离线、离在线融合)

    集成Android免费语音合成功能(在线.离线.离在线融合),有这一篇文章就够了(离线)集成Android免费语音合成功能(在线.离线.离在线融合),有这一篇文章就够了(离在线融合) 转眼间,大半年没 ...

  5. 【Luogu1937】仓配置(贪心,线段树)

    [Luogu1937]仓配置 题面 直接找洛谷把... 题解 很明显的贪心吧 按照线段的右端点为第一关键字,左端点第二关键字排序 然后线段树维护区间最小就可以啦 #include<iostrea ...

  6. BZOJ 5308 [ZJOI2018] Day2T2 胖 | 二分 ST表

    题目链接 LOJ 2529 BZOJ 5308 题解 这么简单的题 为什么考场上我完全想不清楚 = = 对于k个关键点中的每一个关键点\(a\),二分它能一度成为哪些点的最短路起点(显然这些点在一段包 ...

  7. coursera吴恩达 机器学习编程作业原文件 及我的作业

    保存在github上供广大网友下载:点击 8个zip,原文件,没有任何改动. 另外,不定期上传我自己关于这门课的学习过程笔记和心得,有兴趣的盆友可以点击这里查看.

  8. [HEOI2013]SAO ——计数问题

    题目大意: Welcome to SAO ( Strange and Abnormal Online).这是一个 VR MMORPG, 含有 n 个关卡.但是,挑战不同关卡的顺序是一个很大的问题. 有 ...

  9. textarea 字体限制,超出部分不显示并及时显示还剩字体个数

    1)HTML <textarea class="box" ></textarea > 2)JQ: $(function(){ $(".box&qu ...

  10. Java_Mybatis_注解代理写法

    Mybatis的开发方式其实有3种: 1. 原始Dao开发(就是把mapper接口.映射文件和实现类都一并开发) 2. xml代理(就是只实现mapper接口和映射文件) 3.注解代理(就是只实现ma ...