Struts1框架九之声明式异常

这是关于Struts1框架的最后一篇笔记,在这里我们来讲讲Struts1异常的处理,而这里主要讲的就是国际化的异常处理机制。首先我们来看看配置文件里面关于异常信息的配置,这里其他的信息在前面关于struts1框架里面都有讲解,这里我们主要关注于

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>

    <!-- 配置所有的formbean,每个formbean都可以用一个<form-bean>类指定-->
    <form-beans>
        <form-bean name="UserBean" type="com.xingyao.model.UserBean"></form-bean>
    </form-beans>

    <!-- 配置具体接受action请求的信息,每一个action请求都可以用一个<action>来指定 -->
    <action-mappings>
        <!-- 配置action信息,其中
            path表示用户form请求路径;
            type表示服务器组件action的类;
            name表示formBean组件;
            scope表示将FormBean封装到那个域中
            validate表示是否要验证该formBean
         -->
        <action 
            path="/user/test" 
            type="com.xingyao.action.LoginAction"
            name="UserBean" 
            scope="request" 
            parameter="command"
        >
            <exception key="user.not.found" type="com.xingyao.exception.UserException" handler="com.xingyao.exception.Handler.UserExceptionHandler" path="/index.jsp"></exception>
            <!-- 具体请求的时候,得到返回结果,需要跳转(转发)的页面 -->
            <forward name="success" path="/WEB-INF/JSP/success.jsp"></forward>
            <forward name="error" path="/WEB-INF/JSP/error.jsp"></forward>
        </action>
    </action-mappings>
    <!-- 配置国际化组件 -->
    <message-resources parameter="MessageResources"></message-resources>
</struts-config>

由上面的配置文件可以看出,如果要实现异常处理的国际化,必须有一个异常类和一个异常处理类,那么我们来看看这两个类是怎么定义的

————————————————————–异常类——————————————————————-这个类其实并没有什么,主要是定义一个异常类,然后保存用户自定义的异常信息内容,只不过内容的格式要用国际化文件里面的信息而已

public class UserException extends RuntimeException {

    private static final long serialVersionUID = -2628995114435366488L;

    private String errorCode;    //用于保存国际化文件里面的key

    private Object[] args;        //用户保存国际化文件里面的key对应的value的参数值

    public UserException(String errorCode, Object args0) {
        this(errorCode, new Object[] { args0 });
    }

    public UserException(String errorCode, Object[] args) {
        this.errorCode = errorCode;
        this.args = args;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public Object[] getArgs() {
        return args;
    }
}

———————————————————-异常类处理器—————————————————————–
这个异常类处理器,是重写了ExceptionHandler里面的excute()方法,首先我们来看看这里方法的主要参数都有哪些:
execute(
Exception ex, 这个是你抛出的异常类
ExceptionConfig ae, 这个是你

/**
 * 异常类处理器
 * 
 * @author xingyao
 * @since 2016-9-8
 */
public class UserExceptionHandler extends ExceptionHandler {

    public ActionForward execute(Exception ex, ExceptionConfig ae,
            ActionMapping mapping, ActionForm formInstance,
            HttpServletRequest request, HttpServletResponse response)
            throws ServletException {
        //如果你抛出的异常信息,不是你定义的异常类,则交给父类接受异常信息:父类怎么进行处理在下面将struts1的异常执行流程会将
        if (!(ex instanceof UserException)) {
            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 {
            //这个信息是<action input="属性值">,如果你没有配置上面的path,系统默认是从这里得到
            forward = mapping.getInputForward();
        }
 // 这部分代码不需要看,主要是如果异常类是系统异常类,就通过这个得到信息
        if (ex instanceof ModuleException) {
            error = ((ModuleException) ex).getActionMessage();
            property = ((ModuleException) ex).getProperty();
        } else {
//重点,这里是对异常类进行强制转换
            UserException ece = (UserException) ex;
//调用你定义异常类里面的方法,得到国际化文件里面的key
            String errorCode = ece.getErrorCode();
//的都你定义异常类里面的方法,得到用于替换国际化文件异常信息里面的参数信息
            Object[] args = ece.getArgs();
//得到一个ActionMessage对象,用error保存该对象的引用
            error = new ActionMessage(errorCode, args);
//这个key就是errorCode的值,
            property = error.getKey();
        }

        this.logException(ex);

        // Store the exception
//这里就是往request域里面设置值,key为Globals.EXCEPTION_Key,值就是你定义的异常类里面保存的信息
        request.setAttribute(Globals.EXCEPTION_KEY, ex);
//这个方法是将异常信息封装到ActionMessages里面,然后将这个对象保存<exception scope="属性值">对应的域里面,默认为session
        this.storeException(request, property, error, forward, ae.getScope());
//返回调转信息
        return forward;
    }
}

好了,这里我们讲完了怎么配置一个国际化异常类,以及自定义异常处理器,现在我们来看看怎么使用jsp页面显示异常信息
<%@ taglib prefix=”html” uri=”http://struts.apache.org/tags-html” %>需要导入的标签
这个就是显示异常信息的标签
额外知识:如果你想给异常信息为red字体,可以给这个标签套用


也可以在国际化文件上面配置 errors.header=

  • errors.prefix=

  • errors.suffix=

  • errors.footer=

jsp:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean" %>
<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
  </head>
  <body>
      <h1><bean:message key="user.title" /></h1>
      <hr>
      <html:errors/>
      <form action="user/test.do?command=login" method="post">
          <bean:message key="user.username"/> <input type="text" name="username"><br>
          <bean:message key="user.password"/>    <input type="password" name="passwrod"><br>
          <input type="submit" value='<bean:message key="user.button.login"/>'> 
      </form>
  </body>
</html>

讲完了Struts1框架处理异常信息,但是Struts1异常是怎么进行异常处理的呢?
首先我们来看看一个action类的方法是什么样的呢?由下面的代码,我们可以知道在本类不进行异常处理,而是继续往外抛,交给父类处理

/**
 * 登入功能的action
 * @author xingyao
 * @since 2016-8-24
 */
@SuppressWarnings("all")
public class LoginAction extends DispatchAction{

    /**
     * 添加用户功能
     */
    public ActionForward login(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        UserService userService = new UserService();
        UserBean userBean = (UserBean) form;
        userService.login(userBean.getUsername(), userBean.getUsername());
        //返回结果,拥有返回页面的判断,参照配置文件(struts-config.xml)里面的<forward name="success" path="/WEB-INF/JSP/success.jsp"></forward>
        return mapping.findForward("success");
    }
}

————————————————————–父类异常处理————————————————————-
在Struts1框架二之项目执行流程(源代码分析1).note 里面我将到了processActionPerform方法里面对Action里面的excute方法进行了调用。所以Struts1框架的异常处理当然也在这里面进行处理啦,这里对异常进行了捕捉,然后交给processException进行处理,我们来看看这个方法做了什么

 protected ActionForward
        processActionPerform(HttpServletRequest request,
                             HttpServletResponse response,
                             Action action,
                             ActionForm form,
                             ActionMapping mapping)
        throws IOException, ServletException {

        try {
            return (action.execute(mapping, form, request, response));
        } catch (Exception e) {
            return (processException(request, response,    -----------------------------------------看详细讲解1
                                     e, form, mapping));
        }
    }
-------------------------------------------------------------详细讲解1-----------------------------------------------------------------
 /**

     */
    protected ActionForward processException(HttpServletRequest request,
                                             HttpServletResponse response,
                                             Exception exception,
                                             ActionForm form,
                                             ActionMapping mapping)
        throws IOException, ServletException {

        //到actionMapping里面查找异常信息配置
        ExceptionConfig config = mapping.findException(exception.getClass());
        //如果没有异常信息,直接往外抛,交给用户处理,其实就是显示系统原始的异常信息到前台
        if (config == null) {
            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);
            }
        }

        // Use the configured exception handling
        try {
//这里就用到了异常处理器了,如果用户没有定义的话,这直接有父类的异常处理器
            ExceptionHandler handler = (ExceptionHandler)
            RequestUtils.applicationInstance(config.getHandler());
//这里就是利用异常处理器对异常进行处理,主要工作有,请看上面自定义的异常处理器里面功能
            return (handler.execute(exception, config, mapping, form,
                                    request, response));
        } catch (Exception e) {
            throw new ServletException(e);
        }
    }

这一篇大概的讲解了下struts1的异常处理机制,但是好多都没有讲解到,例如:jsp的标签作用的执行流程并没有讲解,这里可以参考下Struts框架八之国际化.note 这里面的jsp标签的执行流程
转载请标明出处
感谢苏波老师的指导
个人见解、错误请指出!请莫怪

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值