Struts(十二):异常处理:exception-mapping元素

时间:2022-03-26 06:01:33
  • 配置当前action的声明异常处理

1、exception-mapping元素中有2个属性
  exception:指定需要捕获的异常类型
  result:指定一个响应结果,该结果将在捕获到异常时被执行。即可以来自当前action的声明,也可以来自global-results声明。

2、可以在视图上通过<s:property>标签显示异常消息。

基于上几个章节的例子开始往下写,修改save函数:

    public String save(){
System.out.println("save"); int val=10/0; return "success";
}

此时访问http://localhost:8080/Struts_01/,输入信息点击“提交”按钮跳转到details.jsp,当访问save函数时,就跑出了异常信息:

Struts(十二):异常处理:exception-mapping元素

此时,我们发现异常信息并没有被合理的处理掉,比如出错了,我们让页面跳转到error.jsp该多好,其实struts2中通过配置struts.xml是可以实现的。

修改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.action.extension" value="action" />
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
-->
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
<constant name="struts.devMode" value="false" /> <package name="default" namespace="/" extends="struts-default">
<action name="product-save" class="com.dx.struts2.valuestack.Product" method="save">
<exception-mapping result="error" exception="java.lang.ArithmeticException"></exception-mapping>
<result name="error">/error.jsp</result>
<result>/details.jsp</result>
</action>
</package>
<!-- Add packages here -->
</struts>
 

添加在WebContent下添加error.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Insert title here</title>
</head>
<body>
  error
</body>
</html>

重启服务,重新访问页面,并提交参数,发现页面自动跳转到了error.jsp:Struts(十二):异常处理:exception-mapping元素

如果光跳转过来不太完美,如果可以显示错误信息不是更好,实际上通过EL或者s:property标签是可以实现的,修改error.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
error<br/>
<s:debug/>
<s:property value="exception" /><br/>
${exception}<br/>
${exception.message}<br/>
<s:property value="exception.message"/><br/>
<s:property value="exceptionStack"/><br/>
${exceptionStack} </body>
</html>

显示信息:Struts(十二):异常处理:exception-mapping元素
s:debug第一个元素类型为:com.opensymphony.xwork2.interceptor.ExceptionHolder

元素包含两个属性:exception和exceptionStack

  • 可以通过global-exception-mappings元素为应用程序提供一个全局性的异常捕获映射。

  1、但在global-exception-mappings元素下声明任何exception-mapping元素只能引用在global-results元素下声明的某个result元素。

只需要修改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.action.extension" value="action" />
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
-->
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
<constant name="struts.devMode" value="false" /> <package name="default" namespace="/" extends="struts-default">
<global-results>
<result name="error">/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="error" exception="java.lang.ArithmeticException"></exception-mapping>
</global-exception-mappings>
<action name="product-save" class="com.dx.struts2.valuestack.Product" method="save">
<!--
<exception-mapping result="error" exception="java.lang.ArithmeticException"></exception-mapping>
<result name="error">/error.jsp</result>
-->
<result>/details.jsp</result>
</action>
</package>
<!-- Add packages here -->
</struts>

重新访问即可,其他内容不影响显示。

  • 声明式异常处理机制由ExceptionMappingInterceptor拦截器负责处理。

  1、当某个exception-mapping元素声明的异常被捕获到是,ExceptionMappingInterceptor拦截器就会向ValueStack中添加两个对象:

    exception:表示被捕获异常的Exception对象
    exceptionStack:包含着被捕获异常的栈

  2、什么地方注册这个拦截器?

struts-core.jar 下的struts-default.xml中<default-interceptor-ref name="defaultStack"/>

<interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>

 com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor怎么向ValueStack中写入异常信息?

package com.opensymphony.xwork2.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory; import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* @author Matthew E. Porter (matthew dot porter at metissian dot com)
* @author Claus Ibsen
*/
public class ExceptionMappingInterceptor extends AbstractInterceptor { protected static final Logger LOG = LoggerFactory.getLogger(ExceptionMappingInterceptor.class); protected Logger categoryLogger;
protected boolean logEnabled = false;
protected String logCategory;
protected String logLevel; public boolean isLogEnabled() {
return logEnabled;
} public void setLogEnabled(boolean logEnabled) {
this.logEnabled = logEnabled;
} public String getLogCategory() {
return logCategory;
} public void setLogCategory(String logCatgory) {
this.logCategory = logCatgory;
} public String getLogLevel() {
return logLevel;
} public void setLogLevel(String logLevel) {
this.logLevel = logLevel;
} @Override
public String intercept(ActionInvocation invocation) throws Exception {
String result; try {
result = invocation.invoke();
} catch (Exception e) {
if (isLogEnabled()) {
handleLogging(e);
}
List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
ExceptionMappingConfig mappingConfig = this.findMappingFromExceptions(exceptionMappings, e);
if (mappingConfig != null && mappingConfig.getResult()!=null) {
Map parameterMap = mappingConfig.getParams();
// create a mutable HashMap since some interceptors will remove parameters, and parameterMap is immutable
invocation.getInvocationContext().setParameters(new HashMap<String, Object>(parameterMap));
result = mappingConfig.getResult();
publishException(invocation, new ExceptionHolder(e));
} else {
throw e;
}
} return result;
} /**
* Handles the logging of the exception.
*
* @param e the exception to log.
*/
protected void handleLogging(Exception e) {
if (logCategory != null) {
if (categoryLogger == null) {
// init category logger
categoryLogger = LoggerFactory.getLogger(logCategory);
}
doLog(categoryLogger, e);
} else {
doLog(LOG, e);
}
} /**
* Performs the actual logging.
*
* @param logger the provided logger to use.
* @param e the exception to log.
*/
protected void doLog(Logger logger, Exception e) {
if (logLevel == null) {
logger.debug(e.getMessage(), e);
return;
} if ("trace".equalsIgnoreCase(logLevel)) {
logger.trace(e.getMessage(), e);
} else if ("debug".equalsIgnoreCase(logLevel)) {
logger.debug(e.getMessage(), e);
} else if ("info".equalsIgnoreCase(logLevel)) {
logger.info(e.getMessage(), e);
} else if ("warn".equalsIgnoreCase(logLevel)) {
logger.warn(e.getMessage(), e);
} else if ("error".equalsIgnoreCase(logLevel)) {
logger.error(e.getMessage(), e);
} else if ("fatal".equalsIgnoreCase(logLevel)) {
logger.fatal(e.getMessage(), e);
} else {
throw new IllegalArgumentException("LogLevel [" + logLevel + "] is not supported");
}
} /**
* @deprecated since 2.3.15 please use #findMappingFromExceptions directly instead
*/
protected String findResultFromExceptions(List<ExceptionMappingConfig> exceptionMappings, Throwable t) {
ExceptionMappingConfig result = findMappingFromExceptions(exceptionMappings, t);
return result==null?null:result.getResult();
} /**
* Try to find appropriate {@link ExceptionMappingConfig} based on provided Throwable
*
* @param exceptionMappings list of defined exception mappings
* @param t caught exception
* @return appropriate mapping or null
*/
protected ExceptionMappingConfig findMappingFromExceptions(List<ExceptionMappingConfig> exceptionMappings, Throwable t) {
ExceptionMappingConfig config = null;
// Check for specific exception mappings.
if (exceptionMappings != null) {
int deepest = Integer.MAX_VALUE;
for (Object exceptionMapping : exceptionMappings) {
ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) exceptionMapping;
int depth = getDepth(exceptionMappingConfig.getExceptionClassName(), t);
if (depth >= 0 && depth < deepest) {
deepest = depth;
config = exceptionMappingConfig;
}
}
}
return config;
} /**
* Return the depth to the superclass matching. 0 means ex matches exactly. Returns -1 if there's no match.
* Otherwise, returns depth. Lowest depth wins.
*
* @param exceptionMapping the mapping classname
* @param t the cause
* @return the depth, if not found -1 is returned.
*/
public int getDepth(String exceptionMapping, Throwable t) {
return getDepth(exceptionMapping, t.getClass(), 0);
} private int getDepth(String exceptionMapping, Class exceptionClass, int depth) {
if (exceptionClass.getName().contains(exceptionMapping)) {
// Found it!
return depth;
}
// If we've gone as far as we can go and haven't found it...
if (exceptionClass.equals(Throwable.class)) {
return -1;
}
return getDepth(exceptionMapping, exceptionClass.getSuperclass(), depth + 1);
} /**
* Default implementation to handle ExceptionHolder publishing. Pushes given ExceptionHolder on the stack.
* Subclasses may override this to customize publishing.
*
* @param invocation The invocation to publish Exception for.
* @param exceptionHolder The exceptionHolder wrapping the Exception to publish.
*/
protected void publishException(ActionInvocation invocation, ExceptionHolder exceptionHolder) {
invocation.getStack().push(exceptionHolder);
} }

Struts(十二):异常处理:exception-mapping元素的更多相关文章

  1. python学习 &lpar;三十二&rpar; 异常处理

    1 异常: def exceptionHandling(): try: a = b = d = a / b print(d) except ZeroDivisionError as ex: print ...

  2. PHP学习笔记三十二【Exception】

    <?php // $fp=fopen("a.txt","r"); // echo "ok"; if(!file_exists(&quo ...

  3. WCF技术剖析之二十二&colon; 深入剖析WCF底层异常处理框架实现原理&lbrack;中篇&rsqb;

    原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...

  4. 异常处理—Exception(二)

    在上一篇中"异常处理--Exception(一)"中,跟大家简单介绍了一下Exception,也使大家充分的了解了Exception管理在一个项目中的重要性,那如何在我们的项目中处 ...

  5. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  6. (转)SpringMVC学习&lpar;十二&rpar;——SpringMVC中的拦截器

    http://blog.csdn.net/yerenyuan_pku/article/details/72567761 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter, ...

  7. 二十二、OGNL的一些其他操作

    二十二.OGNL的一些其他操作 投影 ?判断满足条件 动作类代码: ^ $   public class Demo2Action extends ActionSupport {     public ...

  8. java之jvm学习笔记六-十二&lpar;实践写自己的安全管理器&rpar;&lpar;jar包的代码认证和签名&rpar; &lpar;实践对jar包的代码签名&rpar; &lpar;策略文件&rpar;&lpar;策略和保护域&rpar; &lpar;访问控制器&rpar; &lpar;访问控制器的栈校验机制&rpar; &lpar;jvm基本结构&rpar;

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  9. Spring&plus;SpringMVC&plus;MyBatis深入学习及搭建&lpar;十二&rpar;——SpringMVC入门程序(一)

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6999743.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十一)——S ...

随机推荐

  1. 用javascript判断一个html元素是否存在的五种方法:

    1. 判断表单元素是否存在(一) if("periodPerMonth" in document.theForm){ return true; }else{ return fals ...

  2. iOS开发——OC篇&amp&semi;OC高级语法

    iOS开发高级语法之分类,拓展,协议,代码块详解 一:分类 什么是分类Category? 分类就是类的补充和扩展部分 补充和扩展的每个部分就是分类 分类本质上是类的一部分 分类的定义 分类也是以代码的 ...

  3. iOS-OC对象模型

    原文:http://blog.csdn.net/fanyiyao980404514/article/details/44864663 在C++的内存模型中我们知道,我们通过虚函数列表来存储虚函数的虚拟 ...

  4. TI Davinci DM6446开发攻略——根文件系统的裁剪和移植

    一.补充文件系统知识 Linux根文件系统是存放tool软件.lib文件.script(脚本).配置文件.其他特殊文件.自己开发的应用程序的地方.嵌入式linux的根文件系统rootfs就像windo ...

  5. Linux之ulimit详解&lpar;整理&rpar;

    修改:一般可以通过ulimit命令或编辑/etc/security/limits.conf重新加载的方式使之生效通过ulimit比较直接,但只在当前的session有效,limits.conf中可以根 ...

  6. Emmet for Dreamweaver:HTML&sol;CSS代码快速编写神器

    Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生.它使用仿CSS选择器的语法来生成代码,大大提高了HTML/CSS代码编写的速度,比如下面的演示: ...

  7. 【MySQL 读书笔记】SQL 刷脏页可能造成数据库抖动

    开始今天读书笔记之前我觉得需要回顾一下当我们在更新一条数据的时候做了什么. 因为 WAL 技术的存在,所以当我们执行一条更新语句的时候是先写日志,后写磁盘的.当我们在内存中写入了 redolog 之后 ...

  8. Pytorch多GPU并行处理

    可以参数2017coco detection 旷视冠军MegDet: MegDet 与 Synchronized BatchNorm PyTorch-Encoding官方文档对CGBN(cross g ...

  9. python2 和 python3 区别

    python2 python 2 必须加object加入后是新式类 python 2 不加object是经典类 class HTTP(object): # 经典类和新式类 @staticmethod ...

  10. byte,short,int,long数据之间的倍数关系

    基本数据类型 byte   =  -128和127------------------------------------------------------------2的8次方,1个字节 shor ...