前言:
如今看官们对“apachejsp显示源码”大体比较关注,大家都需要学习一些“apachejsp显示源码”的相关资讯。那么小编同时在网摘上汇集了一些关于“apachejsp显示源码””的相关内容,希望各位老铁们能喜欢,咱们一起来了解一下吧!编程式异常
• 概念:在Action中调用业务逻辑层对象的方法时,用 try-catch 的方式来截获异常之后,手工对异常进行处理
• 处理:使用 struts 的消息处理机制 -- 创建消息对象并传递最后处理
• 处理过程:
○ 截获异常
○ 针对异常创建消息文本对象
○ 将消息文本对象进行传递
§ 将 ActionMessage 放到 ActionMessages 中
§ 将 ActionMessages 放到内置对象中
○ 处理异常
§ <html:messages/> 标签
§ <html:error/> 标签
• 实例:动态信息国际化 -- 编程式异常
声明式异常
• 概念:进行相应的配置后,由 struts 来处理异常,不需要手工在 Action 中进行捕获异常并处理
• 配置:
○ 在 struts-config.xml 中进行 <exception> 标签的配置
○ 在与请求对应的 <action> 标签中进行 input 属性的配置
• 缺点:
○ 代码量大,配置量大
○ 只能添加一个动态填充
• 优点:
○ 不需要手工写异常代码
声明式异常实例
• Tomcat 一启动就将 web.xml 文件读取到内存,读取 <servlet> 标签创建出中央控制器 ActionServlet ,再将主配文件 struts-config.xml 读取到内存实际是读取到内存的一个文件对象 ModuleConfigImpl [ 实现 ModuleConfig 接口 ] 中进行管理 -- 将主配文件封装到 ModuleConfigImpl 文件对象中
• ModuleConfigImpl() // 此对象继续封装配置信息
public ModuleConfigImpl( String prefix) { this.exceptions = new HashMap(); }
ModuleConfigImpl 对象创建一个 Map 集合 exceptions :
□ exceptions:存放 ExceptionConfig 对象 -- key 为 type,value 为 ExceptionConfig 对象
□ ExceptionConfig 对象 -- 封装对应的 <exception> 标签中的各个属性
® ExceptionConfig 由 exceptions 来管理,数据结构为 Bean
□ <exception> 标签中有五个属性:
® key:国际化资源文件中的 key
® type:异常的类型
® path:处理完异常后到哪个页面显示异常信息
® scope:默认为 request
® handle:默认为 ExceptionHandle
• 进入首页:
------------------------- ExceptionConfig.java
public class ExceptionConfig implements Serializable {protected String handler = "org.apache.struts.action.ExceptionHandler"; protected String key = null;protected String path = null; protected String scope = "request"; protected String type = null; }
• 进入登录页面:
<form action="login.do" method="post"><bean:message key="user.username"/>:<input type="text" name="username"><br><bean:message key="user.password"/>:<input type="password" name="password"><br><input type="submit" value="<bean:message key="user.button.login"/>"></form>
• 用户输入用户名和密码,提交请求,请求字符串:
• Tomcat 处理国际化信息:
○ 创建 request 接收协议头中的 locale 信息
○ 取得用户对应的 session
○ 将从 request 中取得的 locale 信息设置到 session 中,属性名为 Globals.LOCALE_KEY
• Tomcat 将 .do 请求提交给 struts
• struts 截取到 path="/login"
• struts 处理 locale 信息 -- processLocale():
○ 拿到当前用户对应的 session
○ 看 session 中是否有属性名为 Globals.LOCALE_KEY 的属性值
□ 如果有值就使用原值
□ 如果没有,从 request 中拿到 locale 信息并将取得的 locale 信息设置到 session 中,属性名为 Globals.LOCALE_KEY
• 在 struts-config.xml 中寻找 path="/login" 的 <action> 标签:
<action path="/login" type="com.bjsxt.struts.LoginAction" name="loginForm" scope="request"validate="false" input="/login.jsp"><exception key="user.not.found" type="com.bjsxt.struts.UserNotFoundException" path="/login_error.jsp"/><exception key="user.password.error" type="com.bjsxt.struts.PasswordErrorException" path="/login_error.jsp"/><forward name="success" path="/login_success.jsp"/></action>
• 通过 name 找 ActionForm -- 创建出 ActionForm 对象后将表单数据收集到 LoginActionForm: private String username; -- "tom"
private String password; -- "123"
• 通过 type 创建出 Action 对象,并执行 Action 中的 execute() 方法:
------------------------- LoginAction.java LoginActionForm laf = (LoginActionForm)form; String username = laf.getUsername();String password = laf.getPassword(); UserManager.getInstance().login(username, password); return mapping.findForward("success");
• 调用业务层 login() 方法:
if (!"admin".equals(username)) { throw new UserNotFoundException(username); } if (!"admin".equals(password)) { throw new PasswordErrorException(); }• 此时用户名不正确,抛出 UserNotFoundException 异常给 Action 的 execute() 方法:public class UserNotFoundException extends RuntimeException {public UserNotFoundException(String msg) { super(msg); } // super 调用父类方法}
• Action 声明了抛出异常,不处理业务对象跑出来的异常,故再往前抛异常到processException() 方法中处理异常:
---------------------------------- processActionPerform(request, response, action, form, mapping) try { return (action.execute(mapping, form, request, response));
}catch (Exception e) { // 抛给 struts 一个异常
return ( processException(request, response, e, form, mapping)); } } // e -- 抛出的异常对象的地址
○ 返回给 struts 一个 ActionForward 对象 [ 封装 name / path 跳转路径 / redirect 跳转方式]
---------------------------------- processException(request, response, e, form, mapping)
protected ActionForward processException( HttpServletRequest request, HttpServletResponse response, Exception exception,ActionForm form,ActionMapping mapping) throws IOException, ServletException { ExceptionConfig config = mapping.findException(exception.getClass());try {ExceptionHandler handler = (ExceptionHandler)RequestUtils.applicationInstance(config.getHandler()); return (handler.execute(exception, config, mapping, form, request, response));} catch (Exception e) { throw new ServletException(e); }}
---------------------------------- findException(exception.getClass()) public ExceptionConfig findException(Class type) {
ExceptionConfig config = null; // ExceptionConfig 对象中封装了 <exception> 标签中的所有属性String name = type.getName(); // 将异常对象的类名赋给name 变量
config = findExceptionConfig(name); if (config != null) { return (config); }
// 如果与请求对应的<action> 标签中没有对应 type 的 <exception> 标签,struts 会去整个配置文件中找<exception> 标签config = getModuleConfig().findExceptionConfig(name);
}
---------------------------------- findExceptionConfig(name) ExceptionConfig findExceptionConfig(String type) {
return ((ExceptionConfig) exceptions.get(type));
}
® exception.getClass().getName() -- 如果不写 getName() 也显示反射类的类名 -- 取得异常对象的类型
® 通过异常对象类型,从该请求配置文件中对应的 <action> 中按照 type 来找和异常对应的 <exception> 标签
◊ 如果没有对应type 的<exception> 标签,struts 会去整个配置文件中找 <exception> 标签
□ config:封装 <exception> 标签的 ExceptionConfig
□ 取得 ExceptionHandler 类后,通过反射方法创建出 ExceptionHandler 对象
□ 调用 ExceptionHandler 的 execute() 方法,最后返回一个ActionForward 对象
---------------------------------- execute(exception, config, mapping, form, request, response)
public ActionForward execute( Exception ex, ExceptionConfig ae, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException { ex:封装的异常对象 / ae:封装了 <exception> 标签中的各个属性
ActionForward forward = null; ActionMessage error = null; String property = null;
if (ae.getPath() != null) { forward = new ActionForward(ae.getPath());
} else { forward = mapping.getInputForward(); }
} 从 <exception> 标签中取得 path 属性值 -- 作为ActionForward 对象中的 forward 转向信息
} 如果 <exception> 标签中没有配置 path 属性,就去与请求对应的 <action> 中获取 input 属性的值作为forward 转向信息
if (ex instanceof ModuleException) {
error = ((ModuleException) ex).getActionMessage(); property = ((ModuleException) ex).getProperty();} else {error = new ActionMessage(ae.getKey(), ex.getMessage()); property = error.getKey();}
} 创建国际化消息文本对象:
– key 为 <exception> 标签中的 key -- 即国际化资源文件中的 key
– value 为异常对象的 message -- 作为动态填充符
} 将国际化消息文本对象中的 key 作为 ActionMessages 中messages 集合的 key
request.setAttribute(Globals.EXCEPTION_KEY, ex); this.storeException(request, property, error, forward, ae.getScope()); return forward;
}
---------------------------------- storeException(request, property, error, forward, ae.getScope()) protected void storeException( HttpServletRequest request, String property,
ActionMessage error, ActionForward forward, String scope) {
ActionMessages errors = new ActionMessages(); errors.add(property, error);
– 创建 ActionMessages 对象
– 将国际化文本对象作为 value 放入 ActionMessages 对象中的 Map 集合中,key 为国际化资源文件中的 key
if ("request".equals(scope)) { request.setAttribute(Globals.ERROR_KEY, errors);
} else {
request.getSession().setAttribute(Globals.ERROR_KEY, errors);
}
}
• 异常流程完成后返回给 struts 一个 ActionForward 对象,struts 解析后跳转到 jsp 页面 -- login_error.jsp:
<html:errors/> -- 直接进行异常信息的输出
复写 ExceptionHandler 类
• ExceptionHandler 类 - 语法:
○ 继承 ExceptionHandler 类
○ 要有 execute() 方法
• 优点:
○ 用一个异常类处理多个异常对象
○ 可以有多个动态填充符
○ 只需要配置一个 <exception> 标签,且该标签可以使用为 <global-exceptions> 全局标签
• 缺点:
○ 要复写 ExceptionHandler 类 -- 比较规范
--------------------------------------------------------------------------------------------------------------------------------------
• 写一个自定义异常类 -- 可以处理所有的异常对象,有多个构造方法: public class ErrorCodeException extends RuntimeException {
private String errorCode; // 国际化资源文件中的 key
private Object[] args; // 动态填充信息,类型为数组对象类型-- 可以填充多个
public ErrorCodeException(String errorCode) { this(errorCode, null); }public ErrorCodeException(String errorCode, Object args0) { this(errorCode, new Object[]{args0}); }public ErrorCodeException(String errorCode, Object[] args) { this.errorCode = errorCode; this.args = args; }}• struts-config.xml:<global-exceptions><exception key="error.exception" type="com.bjsxt.struts.ErrorCodeException" handler="com.bjsxt.struts.ErrorCodeExceptionHandler"/></global-exceptions>○ 此时使用的 handler 是自己复写的,不能使用 ExceptionHandler<action path="/login" type="com.bjsxt.struts.LoginAction" name="loginForm" scope="request"validate="false" input="/login.jsp"><forward name="success" path="/login_success.jsp"/></action>• 调用业务层 login() 方法:if (!"admin".equals(username)) { throw new ErrorCodeException("user.not.found", username); } if (!"admin".equals(password)) { throw new ErrorCodeException("user.password.error"); }
○ 通过有参的构造方法,向异常类中设值 -- 国际化资源文件中的 key,如果需要填充符则设置动态填充符errorCode = "user.not.found";
Object[] args = { tom };
--------------------------------------
errorCode = "user.password.error"; Object[] args = null;
○ 抛出异常的对象不一样,但是类型都是同一个异常类 -- 一定要调用有参的构造方法
• Action 声明了抛出异常,不处理业务对象跑出来的异常,故再往前抛异常到processException() 方法中处理异常:
---------------------------------- processActionPerform(request, response, action, form, mapping)
---------------------------------- processException(request, response, e, form, mapping)) ExceptionConfig config = mapping.findException(exception.getClass());
□
try {
此时获取到的是<global-exceptions> 中的<exception> 标签中的属性
ExceptionHandler handler = (ExceptionHandler)RequestUtils.applicationInstance(config.getHandler()); return (handler.execute(exception, config, mapping, form, request, response));
®
取得 ExceptionHandler 类,此时为自己复写的类 -- 通过反射创建出 ErrorCodeExceptionHandler 对象
® 调用复写类 ErrorCodeExceptionHandler 类的 execute() 方法,最后返回一个ActionForward 对象
} catch (Exception e) { throw new ServletException(e); }
---------------------------------- execute(exception, config, mapping, form, request, response)
public class ErrorCodeExceptionHandler extends ExceptionHandler {public ActionForward execute( Exception ex, ExceptionConfig ae, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException {// 如果异常类型不是 ErrorCodeException,就调用父类的 execute() 方法,最后返回一个 ActionForward 对象给 strutsif ( !(ex instanceof ErrorCodeException) ) { return super.execute(ex, ae, mapping, formInstance, request, response); } ActionForward forward = null; ActionMessage error = null; String property = null; if (ae.getPath() != null) { forward = new ActionForward(ae.getPath());} else { forward = mapping.getInputForward(); }} 从 <exception> 标签中取得 path 属性值 -- 作为ActionForward 对象中的 forward 转向信息
} 如果 <exception> 标签中没有配置 path 属性,就去与请求对应的 <action> 中获取 input 属性的值作为forward 转向信息
if (ex instanceof ModuleException) {error = ((ModuleException) ex).getActionMessage();property = ((ModuleException) ex).getProperty();} else {ErrorCodeException ece = (ErrorCodeException)ex; String errorCode = ece.getErrorCode();Object[] args = ece.getArgs();error = new ActionMessage(errorCode, args);property = error.getKey();
– 将 Exception 异常对象造型为 ErrorCodeException 自定义异常对象类型
标签: #apachejsp显示源码