【开博第一篇】Struts 1.x下的自动异常处理、国际化处理

我技术浅薄,可写的东西实在太少,今天刚好搭建了一下开发框架,就把这些写出来共享,顺便留作以后参考。

转载请申明原创作者【selfimpr】。

涉及的问题主要有两个:

1. 自动异常处理:struts支持的配置异常处理,采用自己定义的异常处理系统中的所有自定义异常。

2. 国际化:一时半会想不出怎么解释,自己查查吧。

首先,看自动异常处理:

先定义自己的异常类

package deploy.test.exception; public class SystemException extends RuntimeException { private String key; private Object[] values; public SystemException(String key, Object... values) { this.key = key; this.values = values; } public Object[] getValues() { return values; } public void setValues(Object[] values) { this.values = values; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } }

定义自己的异常的处理类.

package deploy.test.exception; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionError; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ExceptionHandler; import org.apache.struts.config.ExceptionConfig; public class SystemExceptionHandler extends ExceptionHandler { @Override /** * ex : 截获的异常. * ae : struts-config.xml中对该异常的配置信息 */ public ActionForward execute(Exception ex, ExceptionConfig ae, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException { //如果异常不是我们自己定义的异常,向上抛出,由struts处理. if (!(ex instanceof SystemException)) { return super.execute(ex, ae, mapping, formInstance, request, response); } //错误消息 ActionMessage msg = null; //消息在国际化消息文本中的key String key = null; //把错误消息放到request请求的哪个生命周期中 //HTTPRequest请求包括4个生命周期: //page: 当前页面有效 //request: 当前会话有效 //session: 浏览器窗口关闭失效 //application: 服务器关闭失效 //这里查看SystemException的配置信息中是否配置了scope属性 //如果没有配置,默认使用requestScope,否则,使用配置的属性值. String scope = (ae.getScope() == null || ae.getScope().trim().equals("")) ? "request" : ae.getScope(); //发生这个异常之后要转向的页面 ActionForward forward = null; //国际化消息文本中的占位符对应的值 Object[] values = null; //从该异常的配置信息中获取"path" //如果path属性配置,则转向path配置的路径 //如果path没有配置,转向发生异常的action的配置信息中的input属性指向的页面 if (ae.getPath() != null) { forward = new ActionForward(ae.getPath()); } else { forward = mapping.getInputForward(); } SystemException exception = (SystemException) ex; //从异常中获取key值 key = exception.getKey(); //从异常中获取占位符的具体值 values = exception.getValues(); //如果程序中声明抛出异常的时候,没有指定key值, //使用异常SystemException的配置信息中的key值. //如果声明抛出异常的时候,指定了key值,则使用指定的key值. //使用key值和占位符代表的具体值创建错误信息对象. if (key == null || key.trim().equals("")) { msg = new ActionMessage(ae.getKey(), values); } else { msg = new ActionMessage(key, values); } //调用Struts的存储异常方法,将异常信息保存到指定的请求生命周期中 super.storeException(request, key, msg, forward, scope); return forward; } @Override protected void logException(Exception e) { // TODO Auto-generated method stub super.logException(e); } @Override protected void storeException(HttpServletRequest request, String property, ActionError error, ActionForward forward, String scope) { // TODO Auto-generated method stub super.storeException(request, property, error, forward, scope); } @Override protected void storeException(HttpServletRequest request, String property, ActionMessage error, ActionForward forward, String scope) { // TODO Auto-generated method stub super.storeException(request, property, error, forward, scope); } }

在struts-config.xml文件中配置异常的处理方式:

这里不要忘记最底下指定国际化资源文本的名字哦

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd"> <struts-config> <form-beans> <form-bean name="userForm" type="deploy.test.web.forms.UserForm" /> </form-beans> <!-- 将我们自定义的SystemException异常定义为全局的Exception 指定默认的key值为:errors.detail 指定我们的异常处理器是我们自定义的异常处理器SystemExceptionHandler 指定异常转向的页面是/error.jsp 用bundle指定默认的国际化消息文本是MessageResources --> <global-exceptions> <exception key="errors.detail" type="deploy.test.exception.SystemException" handler="deploy.test.exception.SystemExceptionHandler" path="/error.jsp" bundle="MessageResources"/> </global-exceptions> <action-mappings> <action path="/user" type="org.springframework.web.struts.DelegatingActionProxy" name="userForm" scope="request" parameter="method" > <forward name="success" path="/success.jsp" /> </action> </action-mappings> <message-resources parameter="MessageResources" /> </struts-config>

这样异常处理的"后台就做完了"

定义好我们需要的测试页面之后,在action中的调用中,我们模拟一个异常:

package deploy.test.web.actions; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import deploy.test.exception.SystemException; import deploy.test.manager.UserManager; import deploy.test.web.forms.UserForm; public class UserAction extends BaseAction { private UserManager userManager; public void setUserManager(UserManager userManager) { this.userManager = userManager; } public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { UserForm uf = (UserForm) form; userManager.add(uf.getUsername(), uf.getPassword()); //在异常处理中,不用关心其他业务逻辑代码. //我们模拟抛出一个自定义的SystemException异常 //指定异常的key是user.exist, 其中占位符的第一个是用户名 //请读者自己测试不指定key的情况,和有多个占位符的情况. if(1 == 1) throw new SystemException("user.exist", uf.getUsername()); return mapping.findForward("success"); } }

让我们来看看MessageResource.properties中的内容(MessageResource.properties放到类路径下就可以了,也就是我们开发的时候的src目录,部署之后的/WEB-INF/classes目录), 不用关注其他的信息,看我用# here标注的那几个我们用到的那几行.

# -- standard errors -- errors.header=<UL> errors.prefix=<LI> errors.suffix=</LI> errors.footer=</UL> # -- validator -- errors.invalid={0} is invalid. errors.maxlength={0} can not be greater than {1} characters. errors.minlength={0} can not be less than {1} characters. errors.range={0} is not in the range {1} through {2}. errors.required={0} is required. errors.byte={0} must be an byte. errors.date={0} is not a date. errors.double={0} must be an double. errors.float={0} must be an float. errors.integer={0} must be an integer. errors.long={0} must be an long. errors.short={0} must be an short. errors.creditcard={0} is not a valid credit card number. errors.email={0} is an invalid e-mail address. # -- other -- errors.cancel=Operation cancelled. # here errors.detail={0} errors.general=The process did not complete. Details should follow. errors.token=Request could not be completed. Operation is not in sequence. # -- welcome -- welcome.title=Struts Blank Application welcome.heading=Welcome! welcome.message=To get started on your own application, copy the struts-blank.war to a new WAR file using the name for your application. Place it in your container's "webapp" folder (or equivalent), and let your container auto-deploy the application. Edit the skeleton configuration files as needed, restart your container, and you are on your way! (You can find the application.properties file with this message in the /WEB-INF/src/java/resources folder.) # here # -- our keys -- user.exist=user /u3010{0}/u3011 is exists/! # -- label keys -- label.username=username label.password=password label.register=register

这样,我们在最后的异常转向页面,也就是error.jsp中用一句<html:errors />就可以拿到异常信息了

注意,在error.jsp中使用<html:errors />标签的时候需要引入相关的taglib

<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>

其实上面已经涉及了国际化的处理了,但是,我在做国际化处理的时候,发现我改了浏览器的语言,他也给我不变.

我就做了一个filter

下面具体看看我的国际化处理方式:

首先,定义我们的国际化过滤器,主要是用来获取浏览器中定义的语言选项,然后设置到struts中,让struts获取相应的国际化资源文本.

package deploy.test.i18n; import java.io.IOException; import java.util.Locale; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.struts.Globals; public class LocaleFilter implements Filter { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //从当前请求中获取浏览器定义的Locale信息 Locale locale = request.getLocale(); //将Locale信息设置到session中的Globals.LOCALE_KEY属性, //这样,struts在获取本地化信息的时候就能找到相应的资源文本 ((HttpServletRequest)request).getSession().setAttribute(Globals.LOCALE_KEY, locale); chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }

在web.xml中配置这个filter的时候,采用/*配置uri-pattern就可以了,让它去过滤所有的请求.

这样,就已经基本完工了,具体的其他代码,可以看看我上传的这个项目的源码.

地址在:http://download.csdn.net/source/1162430.

另外,提一个思路:

对于国际化而言,用户往往并不是希望固定的看浏览器语言设定的那一种语言的.这样,我们其实可以像google那样让用户可以选择语言.

这个的实现思路是:

用一个ThreadLocal保存每个用户选择的Locale信息,还是用过滤器.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值