DispatchAction.docx

上传人:b****5 文档编号:5626792 上传时间:2022-12-29 格式:DOCX 页数:30 大小:35.96KB
下载 相关 举报
DispatchAction.docx_第1页
第1页 / 共30页
DispatchAction.docx_第2页
第2页 / 共30页
DispatchAction.docx_第3页
第3页 / 共30页
DispatchAction.docx_第4页
第4页 / 共30页
DispatchAction.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

DispatchAction.docx

《DispatchAction.docx》由会员分享,可在线阅读,更多相关《DispatchAction.docx(30页珍藏版)》请在冰豆网上搜索。

DispatchAction.docx

DispatchAction

EnablingTechnology

Archivefordispatchaction

覆盖DispatchAction中的分发方法

June27,2007at11:

32am·Filedunderdispatchaction,struts

在使用struts时我们经常会用到DispatchAction.有了这个类,我们不需要针对每一个Action都要写一个特定的类,而是可以把一些相关的方法放到一个类中.

  

  DispatchActon中使用了reflection来根据你传入的method参数的值来获取相应的参数来处理你的请求.正如他的方法—他根据你传入的请求参数,用不同的方法来处理你的请求.

  

  但是,通常我们还会遇到另一种情况,如果我想在之行实际的action处理方法之前或者之后再去做一些别的事情而又不想修改我们实际存在的action类呢?

这里我将介绍一种方法.

  

  只要看看struts中DispatchAction(以下简写做DA)的源文件你就会发现,它有一个dispatchMethod方法,接受5个参数.其中4个就是我们通常的strutsaction里的(mapping,request,response,form),还有一个参数就是指定方法的参数的名字.

  

  protectedActionForwarddispatchMethod(ActionMappingmapping,

  ActionFormform,HttpServletRequestrequest,

  HttpServletResponseresponse,Stringname)throwsException

  

  其实现方法如下:

  

  //Makesurewehaveavalidmethodnametocall.

  //Thismaybenulliftheuserhacksthequerystring.

  if(name==null){

  returnthis.unspecified(mapping,form,request,response);

  }

  

  //Identifythemethodobjecttobedispatchedto

  Methodmethod=null;

  try{

  method=getMethod(name);

  

  }catch(NoSuchMethodExceptione){

  Stringmessage=messages.getMessage(”dispatch.method”,mapping

  .getPath(),name);

  log.error(message,e);

  throwe;

  }

  

  ActionForwardforward=null;

  try{

  Objectargs[]={mapping,form,request,response};

  

  //特殊的url不进行处理(add)

  StringactionUrl=request.getServletPath();// ”/rolesign.do”

  booleanexception=isException(actionUrl);

  if(exception){

  logger.debug(”requestUrl:

”+actionUrl+”,nopreandpostprocess”);

  }

  //预处理(add)

  if(!

disabled&&!

exception){

  logger.debug(”preProcessbegin”);

  preProcess(request);

  logger.debug(”preProcessend”);

  }

  

  forward=(ActionForward)method.invoke(this,args);

  

  //后处理(add)

  if(!

disabled&&!

exception){

  logger.debug(”postProcessbegin”);

  postProcess(request);

  logger.debug(”postProcessend”);

  }

  }catch(ClassCastExceptione){

  Stringmessage=messages.getMessage(”dispatch.return”,mapping

  .getPath(),name);

  log.error(message,e);

  throwe;

  

  }catch(IllegalAccessExceptione){

  Stringmessage=messages.getMessage(”dispatch.error”,mapping

  .getPath(),name);

  log.error(message,e);

  throwe;

  

  }catch(InvocationTargetExceptione){

  //Rethrowthetargetexceptionifpossiblesothatthe

  //exceptionhandlingmachinerycandealwithit

  Throwablet=e.getTargetException();

  if(tinstanceofException){

  throw((Exception)t);

  }else{

  Stringmessage=messages.getMessage(”dispatch.error”,mapping

  .getPath(),name);

  log.error(message,e);

  thrownewServletException(t);

  }

  }

  

  //ReturnthereturnedActionForwardinstance

  return(forward);

  

  大部分代码还是从DA的实现方法中copy过来,但是我在这里加入了3个地方.分别是:

  

  1.对请求url的识别,确定是否使用预/后处理

  

  2.预处理方法调用

  

  3.后处理方法调用

  

  当然你要自己写预处理方法和后处理方法.这里你可以传任意你想要的参数给request,然后通过reflection来动态调用任意的java方法,比如你可以在页面设置一个preFunction参数,它的值是classname.methodname.然后你可以在preProcess的实现中通过reflection来查找这个方法并执行.

  

  如果你想让项目中所有的action都有这种特性,则只要让根Action继承DA并覆盖它的dispatchMethod方法即可.

  

  这是在实际项目中用到的一个特性,为了尽可能少的修改原有的代码使用了这种折中的做法.使用reflection时建议不要执行太过复杂的方法,可能会使你的action响应慢的.

PermalinkComments

Struts应用的国际化

June27,2007at11:

26am·Filedunderdispatchaction,struts

万维网(WorldWideWeb)的迅猛发展推动了跨国业务的发展,它成为一种在全世界范围内发布产品信息、吸引客户的有效手段。

为了使企业Web应用能支持全球客户,软件开发者应该开发出支持多国语言、国际化的Web应用。

1本地化与国际化的概念

国际化(简称为I18N)指的是软件设计阶段,就应该使软件具有支持多种语言和地区的功能。

这样,当需要在应用中添加对一种新的语言和国家的支持时,不需要对已有的软件返工,无需修改应用的程序代码。

本地化意味着针对不同语言的客户,开发出不同的软件版本;国际化意味着同一个软件可以面向使用各种不同语言的客户。

如果一个应用支持国际化,它应该具备以下特征:

·当应用需要支持一种新的语言时,无需修改应用程序代码。

·文本、消息和图片从源程序代码中抽取出来,存储在外部。

·应该根据用户的语言和地理位置,对与特定文化相关的数据,如日期、时间和货币,进行正确的格式化。

·支持非标准的字符集。

·可以方便快捷地对应用作出调整,使它适应新的语言和地区。

在对一个Web应用进行国际化时,除了应该对网站上的文本、图片和按钮进行国际化外,还应该对数字和货币等根据不同国家的标准进行相关的格式化,这样才能保证各个国家的用户都能顺利地读懂这些数据。

Locale(本地)指的是一个具有相同风俗、文化和语言的区域。

如果一个应用没有事先把I18N作为那前的功能,那么当这个应用需要支持新的Locale时,开发人员必需对嵌入在源代码中的文本、图片和消息进行修改,然后重新编译源代码。

每当这个应用需要支持新的Locale时,就必需重复这些繁琐的步骤,这种做法显然大大降低了软件开发效率。

2Web应用的中文本地化

无论时对Web应用的本地化还是国际化,都会涉及字符编码转换问题。

当数据流的源与目的地使用不同的字符编码时,就需要对字符编码进行正确的转换。

2.1处理HTTP请求数据编码

默认情况下,IE浏览器发送请求时采用“ISO-8859-1”字符编码,如果Web应用程序要正确地读取用户发送的中文数据,则需要进行编码转换。

一种方法是在处理请求前,先设置HttpServletRequest对象的字符编码:

request.setCharacterEncoding(“gb2312”);

还有一种办法是对用户输入的请求数据进行编码转换:

StringclientData=request.getParameter(“clientData”);

if(clientData!

=null)

clientData=newString(clientData.getBytes(“ISO-8859-1”),“GB2312”);

2.2处理数据库数据编码

如果数据库系统的字符编码为“GB2312”,那么可以直接读取数据库中的中文数据,而无需进行编码转换。

如果数据库字符编码为“ISO-8859-1”,那么必需先对来自数据库的数据进行编码转换,然后才能使用。

2.3处理XML配置文件编码

如果在XML文件中包含中文,可以将XML文件的字符编码为“GB2312”。

这样,当Java程序加载和解析XML文件时无需再进行编码转换。

xmlversion=’1.0’encoding=”GB2312”?

>

2.4处理响应结果的编码

可以通过以下方式来设置响应结果的编码:

·在Servlet中

response.setContentType(“text/html;charset=GB2312”);

·在JSP中

<%@pagecontentType=”text/html;charset=GB2312”%>

·在HTML中

3Java对I18N的支持

Java在其核心库中提供了支持I18N的类和接口。

Struts框架依赖于这些JavaI18N组件来实现对I18N的支持,因此,掌握JavaI18N组件的使用方法有助于理解Struts应用的国际化机制。

3.1Locale类

java.util.Locale类时最重要的JavaI18N类,在Java语言中,几乎所有对国际化和本地化的支持都依赖于这个类。

Locale类的实例代表一种特定的语言和地区。

如果Java类库中的某个类在运行时需要根据Locale对象来调整其功能,那么就称这个类是本地敏感的(Locale-Sensitive)。

例如,java.text.DateFormat类就是本地敏感的,因为它需要依照特定的Locale对象来对日期进行相关的格式化。

Locale对象本身病不执行和I18N相关的格式化或解析工作。

Locale对象仅仅负责向本地敏感的类提供本地化信息。

例如,DateFormat类依据Locale对象来确定日期的格式,然后对日期进行语法分析和格式化。

创建Locale对象时,需要明确地指定其语言和国家代码。

如:

LocaleusLocale=newLocale(“en”,“

US”);

LocalechLocale=newLocale(“ch”,“CH”);

构造方法的第一个参数是语言代码。

语言代码由两个小写字母组成,遵从ISO-639规范。

可以从http:

//www.unicode.org/unicode/onlinedat/languages.html中获得完整的语言代码列表。

构造方法的第二个参数是国家代码,它由两个大写字母组成,遵从ISO-3166规范。

可以从http:

//www.unicode.org/unicode/onlinedat/countries.html中获得完整的国家代码列表。

Locale类提供了几个静态常量,他们代表一些常用的Locale实例。

例如,如果要获得JapaneseLocale实例,可以使用如下两种方法之一:

Localelocale1=Locale.JAPAN;

Localelocale2=newLocale(“ja”,“JP”);

3.1.1Web容器中Locale对象的来源

Java虚拟机在启动时会查询操作系统,为运行环境设置默认的Locale。

Java程序可以调用java.util.Locale类的静态方法getLocale()来获得默认的Locale:

LocaledefaultLocale=Locale.getDefault();

Web容器在其本地环境中通常会使用以上默认的Locale;而对于特定的中断用户,Web容器会从HTTP请求中获取Locale信息。

3.1.2在Web应用中访问Locale对象

在创建Locale对象时应该把语言和国家代码两个参数传递给构造方法。

对于Web应用程序,通常不必创建自己的Locale实例,因为Web容器会负责创建所需的Locale实例。

在应用程序中,可以调用HttpServletRequest对象的以下两个方法,来取得包含Web客户的Locale信息的Locale实例:

publicjava.util.LocalegetLocale();

publicjava.util.EnumerationgetLocales();

着两个方法都会访问HTTP请求中的Accept-Language头信息。

getLocale()方法返回客户优先使用的Locale,而getLocales()方法返回一个Enumeration集合对象,它包含了按优先级降序排列的所有Locale对象。

如果客户没有配置任何Locale,getLocale()方法将会返回默认的Locale。

3.1.3在Struts应用中访问Locale对象

有序Web服务器并不和客户浏览器保持长期的连接,因此每个发送到Web容器的HTTP请求中都包含了Locale信息。

Struts配置文件的元素的locale属性指定是否把Locale对象保存在session范围中,默认值为true,表示会把Locale对象保存在session范围中。

在处理每一个用户请求时,RequestProcessor类都会调用它的processLocale()方法。

尽管每次发送的HTTP请求都包含Locale信息,processLocale()方法把Locale对象存储在session范围中必需满足以下条件:

·Struts配置文件的元素的locale属性为true。

·在session范围内Locale对象还不存在。

processLocale()方法把Locale对象存储在session范围中时,属性key为Globals.LOCALE_KEY,这个常量的字符串值为“org.apache.struts.action.LOCALE”。

如果应用程序允许用户在同一个会话中改变Locale,那么应该对每一个新的HttpServletRequest调用其getLocale()方法,来判断用户是否改变了Locale,如果Locale发生改变,就把新的Locale对象保存在session范围内。

在Struts应用程序中可以很方便地获取Locale信息。

例如,如果在Action类中访问Locale信息,可以调用在StrutsAction基类中定义的getLocale()方法。

Action类的getLocale()方法调用RequestUtils.getUserLocale()方法。

getUserLocale()方法先通过HttpServletRequest参数获得HttpSession对象,然后再通过HttpSession对象来读取Locale对象。

如果存在HttpSession对象并且HttpSession中存储了Locale对象,就返回该Locale对象,否则就直接调用HttpServletRequest的getLocale()方法取得Locale对象,并降它返回。

在Web应用程序的其他地方也可以直接调用RequestUtils类的getUserLocale()方法来获取Locale对象。

3.2ResourceBundle类

java.util.ResourceBundle类提供存放和管理与Locale相关的资源的功能。

这些资源包括文本域或按钮的Label、状态信息、图片名、错误信息和网页标题等。

Struts框架并没有直接使用Java语言提供的ResourceBundle类。

在Struts框架中提供了两个类:

·org.apache.struts.util.MessageResources

·org.apache.struts.util.PropertyMesasgeResources

这两个类具有和ResourceBundle相似的功能,其中PropertyMessageResources是MessageResources类的子类。

3.3MessageFormat类和符合消息。

Java的ResourceBundle和Struts的MessageResources类都允许使用静态和动态的文本。

静态文本指定的是实现就已经具有明确内容的文本。

动态文本指的是只有在运行时才能确定内容的文本。

通常把包含可变数据的消息成为符合消息。

符合消息允许在程序运行时把动态数据加入到消息文本中。

着能够减少ResourceBundle中的静态消息数量,从而减少把静态消息文本翻译成其他Locale版本所花费的时间。

当然,在ResourceBundle中使用符合信息会使文本的翻译变得更加困难。

因为文本包含了直到运行时才知道的替代值,而把包含替代值的消息文本翻译成不同的语言时,往往要对语言做适当调整。

Struts框架封装了MessageFormat类的功能,支持复合消息文本,该功能的实现对于Struts的其他组件是透明的。

4Struts框架对国际化的支持

Struts框架对国际化的支持体现在能够输出何用户Locale相符合的文本何图片上。

当Struts配置文件的元素的locale属性为true时,Struts框架把用户的Locale实例保存在session范围内,这样,Struts框架能自动根据这一Lcoale实例来从ResourceBundle中选择合适的资源文件。

当用户的Locale为英文时,Struts框架就会向用户返回来自于application_en.properties文件的文本内容:

当用户的Locale为中文时,Struts框架就会向用户返回来自于appcation_ch.properties文件的文本内容。

4.1创建Struts的ResourceBundle

对于多应用模块的Struts应用,可以为每个子应用配置一个或多个ResourceBundle,应用模块中的Action、ActionFormBean、JSP页和客户化标签都可以访问这些Bundle。

Struts配置文件中的每个元素定义了一个ResourceBundle。

当应用中包含多个ResourceBundle时,它们通过元素的key属性来区别。

ResourceBundle的持久化消息文本存储在资源文件中,其扩展名为“.properties”,这一文件中消息的格式为:

key=value。

在创建ResourceBundle的资源文件时,可以先提供一个默认的资源文件,默认资源文件应该取名为application.properties。

如果应用程序需要支持中文用户,可以再创建一个包含中文消息的资源文件,文件名为:

application_ch_CH.properties或application_ch.properties。

当Struts框架处理Locale为中文的用户请求时,Struts框架首先在WEB-INF/classes/目录下寻找application_ch_CH.properties文件,如果存在该文件,就从该文件中获取文本消息,否则再一次寻找application_ch.properties和application.properties文件。

应该总是为ResourceBundle提供默认的资源文件,这样,当不存在和某个Locale对应的资源文件时,就可以使用默认的资源文件。

应该把ResourceBundle的资源文件放在能被定位并加载的位置。

对于Web应用程序,资源文件的存放目录为WEB-INF/classes目录。

如果在配置ResourceBundle时还给定了包名,那么包名应该和资源文件所在的子目录对应。

4.2访问ResourceBundle

Struts应用的每个ResourceBundle和org.apache.struts.util.MessageResources类(实际上是其子类PropertyMessageResources)的一个实例对应。

MessageResources对象中存放了来自资源文件的文本。

当应用程序初始化时,这些MessageResources实例被存储在ServletContext中(即application范围内),因此任何一个Web组件都可以访问它们。

一个MessageResources对象可以包含多种本地化版本的资源文件

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1