首先我们的国际化资源文件中有

  1. user.not.found = 用户不能找到,用户名称=[{0}]
  2. user.password.error = user.password.error

第一种 声明式异常处理

为国际化配置文件中的每个key,设计一个异常。

用户登录验证,用户名错误抛出UserNotFoundException,密码错误抛出PasswordErrorException

代码

public void login(String username, String password) {   
        if (!"admin".equals()) {   
            throw new UserNotFoundException();   
        }   
        if (!"admin".equals(password)) {   
            throw new PasswordErrorException();   
        }   
    } 

struts-config.xml文件中,<exception/>的key对应国际化配置文件中key,type是对应的异常处理类

代码

<global-exceptions>  
    <!-- 为所有Action使用的,全局异常 -->  
        <exception key="user.not.found" type="demo.struts.UserNotFoundException"/>  
        <exception key="user.password.error" type="demo.struts.PasswordErrorException"/>  
    </global-exceptions>  
           
    <action-mappings>  
        <action path="/login"  
                type="demo.struts.LoginAction"  
                name="loginForm"  
                scope="request"  
                validate="false"  
                input="/login.jsp"  
        >       
        <!-- path 错误时候 跳转的页面,优先级高于 action中的input -->  
        <!-- 为每一个action配置    
            <exception key="user.not.found" type="demo.struts.UserNotFoundException" path="/login_error.jsp"/>  
            <exception key="user.password.error" type="demo.struts.PasswordErrorException" path="/login_error.jsp"/>  
        -->  
            <forward name="success" path="/login_success.jsp"/>  
            <forward name="error" path="/login.jsp"/>  
        </action>  
           
        <action path="/changelang"  
                type="demo.struts.ChangeLanguageAction"  
        >  
            <forward name="index" path="/index.jsp"/>  
        </action>  
  
    </action-mappings>

Struts的RequestProcessor类

代码

protected ActionForward processException(HttpServletRequest request,   
                                            HttpServletResponse response,   
                                            Exception exception,   
                                            ActionForm form,   
                                            ActionMapping mapping)   
       throws IOException, ServletException {   
  
       // 是否在配置了Exception   
       ExceptionConfig config = mapping.findException(exception.getClass());   
       // 找到的config就是下面这条信息   
       // <exception key="user.not.found" type="demo.struts.UserNotFoundException" path="/login_error.jsp"/>   
       if (config == null) {   
       // 没有配置,struts不管了,往web容器里抛,看在web.xml文件中是否配置,   
       // 如果仍没有配置,则把异常显示到页面上   
           log.warn(getInternal().getMessage("unhandledException",   
                                             exception.getClass()));   
           if (exception instanceof IOException) {   
               throw (IOException) exception;   
           } else if (exception instanceof ServletException) {   
               throw (ServletException) exception;   
           } else {   
               throw new ServletException(exception);   
           }   
       }   
  
       // struts异常默认处理类   
       try {   
           ExceptionHandler handler = (ExceptionHandler)   
           RequestUtils.applicationInstance(config.getHandler());   
           return (handler.execute(exception, config, mapping, form,   
                                   request, response));   
       } catch (Exception e) {   
           throw new ServletException(e);   
       }   
   }  

struts默认的exceptionHandler

代码

public ActionForward execute(   
    Exception ex,   
    ExceptionConfig ae,   
    ActionMapping mapping,   
    ActionForm formInstance,   
    HttpServletRequest request,   
    HttpServletResponse response)   
    throws ServletException {   
  
    ActionForward forward = null;   
    ActionMessage error = null;   
    String property = null;   
  
    // 在<exception>中配置了path,返回actionForward就是path中的配置   
    if (ae.getPath() != null) {   
        forward = new ActionForward(ae.getPath());   
    } else {   
    // 没有配置的话,返回actionForward就是<action>中的input   
        forward = mapping.getInputForward();   
    }   
  
    // Figure out the error   
    if (ex instanceof ModuleException) {   
        error = ((ModuleException) ex).getActionMessage();   
        property = ((ModuleException) ex).getProperty();   
    } else {   
    // 我们写的程序抛出的异常都是这种情况   
    // 从国际化文件中,根据key取   
    // ae.getKey() -- 拿到<exception>中key值 user.not.found   
        error = new ActionMessage(ae.getKey(), ex.getMessage());   
        // 集合ActionMessages中的key,和国际化资源文件中的key一样   
        property = error.getKey();   
    }   
  
    this.logException(ex);   
  
    // Store the exception   
    request.setAttribute(Globals.EXCEPTION_KEY, ex);   
    // 放到ActionMessages集合中 getScope()默认request   
    this.storeException(request, property, error, forward, ae.getScope());   
  
    return forward; 

第二种 个性化异常处理

代码

public void login(String username, String password) {   
        if (!"admin".equals(username)) {   
                        //user.not.found资源文件中的key, username 占位符   
            throw new ErrorCodeException("user.not.found", username);   
        }   
        if (!"admin".equals(password)) {   
            throw new ErrorCodeException("user.password.error");   
        }  

代码

<global-exceptions>  
    <!-- key值随便配一个 具体的是在程序中控制-->  
    <!-- type异常类 handler异常处理类 都是由我们来写和控制 -->  
    <exception key="error.exception" type="demo.struts.ErrorCodeException" handler="demo.struts.ErrorCodeExceptionHandler"/>  
</global-exceptions>

代码

public class ErrorCodeException extends RuntimeException {   
  
    // 错误码就是国际化资源文件的key   
    private String errorCode;   
  
    // 占位符   
    private Object[] args;   
  
    public ErrorCodeException(String errorCode) {   
        this(errorCode, null);   
    }   
  
    public ErrorCodeException(String errorCode, Object arg) {   
        this(errorCode, new Object[]{arg});   
    }   
       
    public ErrorCodeException(String errorCode, Object[] args){   
        this.errorCode = errorCode;   
        this.args = args;   
    }   
  
    // 只提供get方法   
    public String getErrorCode() {   
        return errorCode;   
    }   
  
    public Object[] getArgs() {   
        return args;   
    }  

代码

public class ErrorCodeExceptionHandler extends ExceptionHandler {   
  
    public ActionForward execute(Exception ex, ExceptionConfig ae,   
            ActionMapping mapping, ActionForm formInstance,   
            HttpServletRequest request, HttpServletResponse response)   
            throws ServletException {   
  
        // 不是ErrorCodeException,我们不处理   
        if (!(ex instanceof ErrorCodeException)) {   
            return super.execute(ex, ae, mapping, formInstance, request, response);   
        }   
           
        ActionForward forward = null;   
        ActionMessage error = null;   
        String property = null;   
  
        // Build the forward from the exception mapping if it exists   
        // or from the form input   
        if (ae.getPath() != null) {   
            forward = new ActionForward(ae.getPath());   
        } else {   
            forward = mapping.getInputForward();   
        }   
  
        // Figure out the error   
        if (ex instanceof ModuleException) {   
            error = ((ModuleException) ex).getActionMessage();   
            property = ((ModuleException) ex).getProperty();   
        } else {   
            // 原来的代码 error = new ActionMessage(ae.getKey(), ex.getMessage());   
            // ae.getKey() 拿出的key是配置文件中<exception>写的,因为所有异常都用同一个key   
            // 无法找到国际化资源文件中的key,好在我们在抛异常时,把key写进异常的errorCode中   
               
            ErrorCodeException ece = (ErrorCodeException) ex;   
            // 拿到errorCode   
            String errorCode = ece.getErrorCode();   
            // 拿到占位符   
            Object[] args = ece.getArgs();   
               
            error = new ActionMessage(errorCode, args);   
            property = error.getKey();   
        }   
  
        this.logException(ex);   
  
        // Store the exception   
        request.setAttribute(Globals.EXCEPTION_KEY, ex);   
        this.storeException(request, property, error, forward, ae.getScope());   
  
        return forward;   
  
    }  

如果我们不想写国际化配置文件,在程序中之际页面提示内容

<!-- 用默认的handler也能能执行 -->  
<exception key="error.exception" type="demo.struts.AppException" handler="demo.struts.AppExceptionHandler"/>  

国际化资源文件:

  1. # 只有一个占位符
  2. error.exception={0}
    代码

    public void login(String username, String password) {   
        if (!"admin".equals(username)) {   
                           // 直接写内容   
            throw new AppException("用户不能找到【" + username + "】");   
        }   
        if (!"admin".equals(password)) {   
            throw new ErrorCodeException("密码错误");   
        }   
    }  

public class AppException extends RuntimeException {   
    public AppException(String msg){   
        super(msg);   
    }   
}  
代码

public class AppExceptionHandler extends ExceptionHandler {   
  
    public ActionForward execute(Exception ex, ExceptionConfig ae,   
            ActionMapping mapping, ActionForm formInstance,   
            HttpServletRequest request, HttpServletResponse response)   
            throws ServletException {   
  
        if(!(ex instanceof AppException)){   
            return super.execute(ex, ae, mapping, formInstance, request, response);   
        }   
           
        ActionForward forward = null;   
        ActionMessage error = null;   
        String property = null;   
  
        // Build the forward from the exception mapping if it exists   
        // or from the form input   
        if (ae.getPath() != null) {   
            forward = new ActionForward(ae.getPath());   
        } else {   
            forward = mapping.getInputForward();   
        }   
  
        // Figure out the error   
        if (ex instanceof ModuleException) {   
            error = ((ModuleException) ex).getActionMessage();   
            property = ((ModuleException) ex).getProperty();   
        } else {   
               
            AppException appe = (AppException) ex;   
            // ae.getKey() 没用   
            // appe.getMessage() ("用户不能找到【" + username + "】   
            error = new ActionMessage(ae.getKey(), appe.getMessage());   
            property = error.getKey();   
        }   
  
        this.logException(ex);   
  
        // Store the exception   
        request.setAttribute(Globals.EXCEPTION_KEY, ex);   
        this.storeException(request, property, error, forward, ae.getScope());   
  
        return forward;   
  
    }  

转载于:https://www.cnblogs.com/Fskjb/archive/2010/03/27/1698578.html

Struts 声明式异常处理和个性化异常处理(转)相关推荐

  1. struts声明式异常

    一,局部exception 把action中产生的异常配置到struts-config.xml中,哪个action出现异常就在哪个action的配置中进行配置. <action path=&qu ...

  2. Spring 声明式事务在业务开发中容易碰到的坑总结

    Spring 声明式事务,在业务开发使用上可能遇到的三类坑,包括: 第一,因为配置不正确,导致方法上的事务没生效.我们务必确认调用 @Transactional 注解标记的方法是 public 的,并 ...

  3. 实现自己的BeanFactory、AOP以及声明式事务

    实现自己的BeanFactory                                                                   在使用spring时,我们很少用& ...

  4. WebFlux响应式编程基础之 6 webflux客户端声明式restclient框架开发讲解

    第6章 webflux客户端声明式 restclient框架开发讲解 看不懂,为什么看不懂? 写方法最主要考虑输入与输出 Feign Retrofit 框架 6-1 框架效果介绍 6-2 设计思路 6 ...

  5. 为什么spring中的controller跳转出错_你的业务代码中Spring声明式事务处理正确了吗?

    Spring 针对 Java Transaction API (JTA).JDBC.Hibernate 和 Java Persistence API(JPA) 等事务 API,实现了一致的编程模型,而 ...

  6. 详解 Spring 声明式事务

    一.引言 Spring的事务机制包括声明式事务和编程式事务. 编程式事务管理:Spring推荐使用 TransactionTemplate,实际开发中使用声明式事务较多. 声明式事务管理:将我们从复杂 ...

  7. [JAVAEE]实验06:基于XML和基于注解的声明式事务管理方式模拟银行转账程序

    一.实验目的: 熟练掌握声明式事务管理. 二.实验内容: 编写一个模拟银行转账的程序,要求在转账时通过Spring对事务进行控制. 三.实验要求: 分别使用基于XML和基于注解的声明式事务管理方式来实 ...

  8. Spring的声明式事务底层原理

    文章目录 声明式事务的概述 声明式事务的初探 声明式事务的源码分析 声明式事务的概述 Spring 的声明式事务管理在底层是建立在 AOP 的基础之上的.其本质是对方法前后进行拦截,然后在目标方法开始 ...

  9. 9、 Struts2验证(声明式验证、自定义验证器)

    1. 什么是Struts2 验证器 一个健壮的 web 应用程序必须确保用户输入是合法.有效的. Struts2 的输入验证 基于 XWork Validation Framework 的声明式验证: ...

最新文章

  1. AngularJS指令封装高德地图组件
  2. iOS UI基础-4.1应用程序管理 字典转Model
  3. 你必须拥有的Python调试神器
  4. 04.React事件 方法、 React定义方法的几种方式 获取数据 改变数据 执行方法传值...
  5. 【今日CS 视觉论文速览】 24 Jan 2019
  6. 多拉A梦——日语歌词
  7. 发动机性能测试软件,发动机的性能测试方法
  8. POJ 3046 Ant Counting ( 多重集组合数 经典DP )
  9. ArcGIS Engine开发前基础知识(3)
  10. 软件开发需求分析内容
  11. 极客爱情 2.4 | 和程序员男友过节是这样的
  12. 超尴尬婆婆对儿媳的新婚之夜的指导
  13. 并行接口芯片8255与定时器/计数器接口芯片8253
  14. [附源码]Python计算机毕业设计高校请假管理系统
  15. 生活 or 办公——怎么能少了 PeakDo 毫米波无线投屏器呢
  16. 分析nmn抗衰老的真实性,nmn的效果到底怎么样
  17. 按键精灵 android 精简版,超精简的游戏脚本(适合大部分游戏)
  18. 机器学习之网格搜索调参sklearn
  19. 【Leetcode】对 矩 阵 螺 旋 输 出 java/c++
  20. 二、Snapman多人协作电子表格之——软件下载安装与配置

热门文章

  1. BP神经网络-- C语言实现
  2. Basic脚本解释器移植到STM32
  3. clock_gettime获取时间
  4. springmvc二十四:自定义国际化信息
  5. 使用libcurl开源库和Duilib做的下载文件并显示进度条的小工具
  6. autoburn eMMC hacking
  7. ubuntu下配置交叉编译环境
  8. 易语言 企鹅机器人开发文档
  9. Appium 命令行安装教程
  10. 禁止北京地区IP访问站点