空间站

北极心空

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

Struts2与Struts1对比

Struts2与Struts1Struts2与Struts1对比
Action 类:
  Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。
  Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一

个ActionSupport基类去实现 常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作

Struts2的Action对象。

线程模式:
  Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制

了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
  Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生

许多可丢弃的对象,并且不会导致性能和垃圾回收问题)

Servlet 依赖:
  Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse

被传递给execute方法。
  Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的

request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要

性。

可测性:
  测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方

扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。
  Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。

捕获输入:
  Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作

ActionForm,开发者经常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是

,开发者可能是在重新描述(创建)已经存在的JavaBean(仍然会导致有冗余的javabean)。
  Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的

rich对象类型。Action属性能够通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包

括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。

表达式语言:
  Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
  Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--"Object Graph Notation Language"

(OGNL).

绑定值到页面(view):
  Struts 1使用标准JSP机制把对象绑定到页面中来访问。
  Struts 2 使用 "ValueStack"技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。

ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
 
类型转换:
  Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换

器,对每一个实例来说是不可配置的。
  Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。

校验:
  Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以

有不同的校验内容,但不能校验子对象。
  Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校

验,来支持chain校验子属性

Action执行的控制:
  Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命

周期。
  Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不

同的Action一起使用。

 

--------------------------------------------------------------------------------
注释struts.action.extension
          The URL extension to use to determine if the request is meant for a Struts action
           用URL扩展名来确定是否这个请求是被用作Struts action,其实也就是设置 action的后缀,例如

login.do的'do'字。

struts.configuration
          The org.apache.struts2.config.Configuration implementation class
            org.apache.struts2.config.Configuration接口名

struts.configuration.files
          A list of configuration files automatically loaded by Struts
           struts自动加载的一个配置文件列表

struts.configuration.xml.reload
          Whether to reload the XML configuration or not
           是否加载xml配置(true,false)

struts.continuations.package
           The package containing actions that use Rife continuations
           含有actions的完整连续的package名称

struts.custom.i18n.resources
          Location of additional localization properties files to load
           加载附加的国际化属性文件(不包含.properties后缀)

struts.custom.properties
          Location of additional configuration properties files to load
           加载附加的配置文件的位置


struts.devMode
          Whether Struts is in development mode or not
           是否为struts开发模式

struts.dispatcher.parametersWorkaround
          Whether to use a Servlet request parameter workaround necessary for some versions of WebLogic
            (某些版本的weblogic专用)是否使用一个servlet请求参数工作区(PARAMETERSWORKAROUND)

struts.enable.DynamicMethodInvocation
          Allows one to disable dynamic method invocation from the URL
            允许动态方法调用

struts.freemarker.manager.classname
          The org.apache.struts2.views.freemarker.FreemarkerManager implementation class
           org.apache.struts2.views.freemarker.FreemarkerManager接口名

struts.i18n.encoding
          The encoding to use for localization messages
           国际化信息内码

struts.i18n.reload
          Whether the localization messages should automatically be reloaded
           是否国际化信息自动加载

struts.locale
          The default locale for the Struts application
           默认的国际化地区信息

struts.mapper.class
          The org.apache.struts2.dispatcher.mapper.ActionMapper implementation class
            org.apache.struts2.dispatcher.mapper.ActionMapper接口

struts.multipart.maxSize
          The maximize size of a multipart request (file upload)
           multipart请求信息的最大尺寸(文件上传用)

struts.multipart.parser
          The org.apache.struts2.dispatcher.multipart.MultiPartRequest parser implementation for a

multipart request (file upload)
          专为multipart请求信息使用的org.apache.struts2.dispatcher.multipart.MultiPartRequest解析器接口

(文件上传用)


struts.multipart.saveDir
          The directory to use for storing uploaded files
           设置存储上传文件的目录夹

struts.objectFactory
          The com.opensymphony.xwork2.ObjectFactory implementation class
           com.opensymphony.xwork2.ObjectFactory接口(spring)

struts.objectFactory.spring.autoWire
          Whether Spring should autoWire or not
           是否自动绑定Spring

struts.objectFactory.spring.useClassCache
          Whether Spring should use its class cache or not
           是否spring应该使用自身的cache

struts.objectTypeDeterminer
          The com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation class
            com.opensymphony.xwork2.util.ObjectTypeDeterminer接口

struts.serve.static.browserCache
          If static content served by the Struts filter should set browser caching header properties or

not
           是否struts过滤器中提供的静态内容应该被浏览器缓存在头部属性中

struts.serve.static
          Whether the Struts filter should serve static content or not
           是否struts过滤器应该提供静态内容

struts.tag.altSyntax
          Whether to use the alterative syntax for the tags or not
           是否可以用替代的语法替代tags

struts.ui.templateDir
          The directory containing UI templates
           UI templates的目录夹

struts.ui.theme
          The default UI template theme
           默认的UI template主题

struts.url.http.port
          The HTTP port used by Struts URLs
           设置http端口

struts.url.https.port
          The HTTPS port used by Struts URLs
           设置https端口

struts.url.includeParams
          The default includeParams method to generate Struts URLs
          在url中产生 默认的includeParams


struts.velocity.configfile
          The Velocity configuration file path
           velocity配置文件路径

struts.velocity.contexts
          List of Velocity context names
           velocity的context列表


struts.velocity.manager.classname
          org.apache.struts2.views.velocity.VelocityManager implementation class
           org.apache.struts2.views.velocity.VelocityManager接口名

struts.velocity.toolboxlocation
          The location of the Velocity toolbox
           velocity工具盒的位置
struts.xslt.nocache
          Whether or not XSLT templates should not be cached
           是否XSLT模版应该被缓存
在Struts2中,action中的getXXX()只在服务器启动时执行一次,一刷新页面显示的数据内容全都没了,这种问题的解

决办法是:
在web.xml中配置struts2.0时,
<filter-mapping>
<filter-name>action2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
把/*改成*.ation就OK了
一、Struts2配置文件
Struts2相关的配置文件有web.xml,struts.xml,struts.properties,
struts-default.xml,velocity.properties,struts-default.vm。其中web.xml,struts.xml是必须的,其它的配置

文件可选择。它们在web应用中的功能如下:
web.xml:包含所有必须的框架组件的web部署描述符。
Struts.xml:配置包含result/view类型、action映射、拦截器等的Struts2的主要配置文件。
Struts.properties:配置struts2的框架属性。
Struts-default.xml:在文件在struts-action-x.x.jar中,该文件是应该被包含在struts.xml中的缺省配置。
Welocity.properties:重写了velocity的配置文件。
Struts-default.vm:相对于velocity的缺省配置。

二、Struts2配置元素
Struts2核心的配置文件是缺省的struts.xml。
必要的时候,缺省的配置文件可以包含其它的配置文件;struts文件可以放入jar中,并自动插入应用程序,这样每个

模块可以包含自己的配置文件并自动配置。在Freemarker和Velocity模块中,模板也能从classpath中加载,所以整个

模块可以作为一个简单的jar文件被包含。
Struts.xml配置文件可以包含Interceptor、Action类和Results。
Struts.xml配置元素说明:

1、Packages
Packages:packages把actions、results、results types、interceptors
和interceptor-stacks组装到一个逻辑单元中,从概念上讲,packages就像一个对象,可以被其它子包从写,而且可

以拥有自己独立的部分。
Name属性是packages的必填元素,它作为一个关键字被后边的包引用;extends元素是可选的,它允许包扩展一个和多

个前边定义的包。注意,
struts.xml文件是至上而下处理的,所有被扩展的包,需要在扩展包前定义。
Abstract元素是可选的,它可以申明一个不包含actions的配置文件。

2、Namespace
Namespace元素把actions细分到逻辑模块,每一个namespace都有自己的
前缀(prefix),namespace避免了action之间的名字冲突,当前缀出现在URI中时,这些标签都是名字空间感知的(

“namespace aware”),所以这些namespace prefix不必嵌入到表单或连接中。
Default的namespace是一个空字符串“”,如果在指定的配置文件中,没有找到action,缺省的namespace也会被查找

。Local/global策略允许应用程序在action “extends”元素层次结构之外,有全局的action配置。缺省的namespace

也可以不在package中申明。
Namespace prefix可以注册为java的申明式安全,以确保授权的用户才能访问namespace的资源。
Root namespace(“/”)也被支持,root就是当直接请求context path的时候的namespace。

[个人理解:namespace的用法就像struts1.x中的path一样,只不过它在package中什么路径,而在action中申明

action名子罢了]

3、Include
Include元素使得框架能应用“divide and conquer”来配置文件。被include
的每个配置文件必须和struts.xml有一样的格式,一个大的项目可以采用这样方式来组织程序模块。
Include元素也可以和package交替出现,框架将按照顺序加载配置文件。

4、Interceptor configuration
Interceptor允许应用程序在Action方法执行前后定义执行代码,
Interceptor在应用程序开发中十分重要,对于Interceptor有许多用例,如validation, property population,

security, logging, 和profiling。
Interceptor被定义为一个Java类,Interceptor也可以组装成Interceptor-stack,他们将按照定义的顺序执行。
在struts-default.xml中定义了一些缺省的Interceptor-stack,以便框架能很好地运行。

5、Action
Action是框架的“工作单元”。Action可以指定一个Interceptor-stack、
一序列的return type和一序列的异常处理,但只有name属性是必须的。

 

--------------------------------------------------------------------------------
struts2.0简单的例子今天在apache网站上无意中看到了struts项目2.0.8正式发布了,怀着欣喜的心情我下载了

stuts2.0.8完整包。 Struts2.0.8是struts项目和WebWork2.2项目的合并版本,集成了两大流行MVC框架的优点,对

struts框架来说是一个大的提升,同时也更大程度地简化了开发人员的开发过程。我简单地研究了一下这个新版本,

现在给大家介绍一个入门级的小例子,希望能对学习这个新版本的朋友有点帮助。
这个例子完成了一次URL调用返回结果页面的过程。
首先,要从apache网站上下载struts2.0.8的完整包(可以从这里下载:

http://www.signal42.com/mirrors/apache/struts/binaries/struts-2.0.8-all.zip),解压后需要找到下列几个文

件:
commons-logging-1.0.4.jar
freemarker-2.3.8.jar
ognl-2.6.11.jar
struts2-core-2.0.8.jar
xwork-2.0.3.jar
然后,我们就开始做第一个例子,我们就使用经典的“HelloWorld”的名字吧!
1. 制作目录结构
如下图所示:
stuts2是web应用的根目录。
2. 拷贝引用文件
将上面列举的jar文件拷贝到步骤1中制作的目录struts2\WEB-INF\lib中。
3. 制作jsp文件HelloWorld.jsp

<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h2><s:property value="message" /></h2>
</body>
</html>
将该文件拷贝到步骤1中制作的目录struts2\example中。
4.制作java文件HelloWorld.java

package example;

/** *//**
* <code>Set welcome message.</code>
*/
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorld extends ActionSupport ...{

public static final String MESSAGE = "Struts is up and running ...";

public String execute() throws Exception ...{
setMessage(MESSAGE);
return SUCCESS;
}

private String message;

public void setMessage(String message)...{
this.message = message;
}

public String getMessage() ...{
return message;
}
}
使用下面的命令编译这个java文件:
set CLASSPATH=yourdirectory\xwork-2.0-beta-1.jar
javac HelloWorld.java
将编译后的HelloWorld.class文件拷贝到步骤1中制作的目录struts2\WEB-INF\classes\example中。
5.制作web应用的描述文件web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-

app_2_4.xsd"
    version="2.4">

<display-name>Struts Blank</display-name>

<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>

<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
将该文件拷贝到步骤1中制作的目录struts2\WEB-INF中。
6.制作MANIFEST.MF文件(从其它地方随便找一个即可)
将该文件拷贝到步骤1中制作的目录struts2\META-INF中。
7.制作struts配置文件struts.xml和struts.properties
struts.xml文件:

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="abc" namespace="/example" extends="struts-default">
<action name="HelloWorld" class="example.HelloWorld">
<result>/example/HelloWorld.jsp</result>
</action>
<!-- Add your actions here -->
</package>
</struts>
struts.properties文件:
struts.devMode = true
struts.enable.DynamicMethodInvocation = false
将这两个文件拷贝到步骤1中制作的目录struts2\ WEB-INF\classes中。
好了整个例子的文件我们都搞定了。
最后,你可以将制作好的web应用struts2拷贝到tomcat下运行。
访问http://localhost:8080/struts2/example/HelloWorld.action如果能够看到页面上的“Struts is up and

running ...”提示信息说明你的例子是正确的。

 


--------------------------------------------------------------------------------
Struts2.0 中文乱码1.为了能正确显示 jsp页面直接写的中文 在jsp页面正确显示添加下面字符设置。
   <%@ page contentType="text/html;charset=GBK"%>
2.为了解决form提交到action中的中文参数乱码问题,在src\struts.properties文件添加
struts.i18n.encoding=GBK



    在struts2-core-2.0.8.jar 包中路径为struts2-core-2.0.8\org\apache\struts2 有一个default.properties

文件
    把struts.i18n.encoding=UTF-8改为struts.i18n.encoding=GBK 或者在struts.xml里面改
    这样在action中取到的参数不用自己手工转码 了。

 

--------------------------------------------------------------------------------
Struts 2.0的标志(Tag)介绍介绍常用标志前,我想先从总体上,对Struts 1.x与Struts 2.0的标志库(Tag

Library)作比较。  Struts 1.x Struts 2.0
分类 将标志库按功能分成HTML、Tiles、Logic和Bean等几部分 严格上来说,没有分类,所有标志都在URI为

“/struts-tags”命名空间下,不过,我们可以从功能上将其分为两大类:非UI标志和UI标志
表达式语言(expression languages) 不支持嵌入语言(EL) OGNL、JSTL、Groovy和Velcity
以上表格,纯属个人总结,如有所不足或错误,请不吝指正

好了,我要开始介绍“常用”(这里所谓的“常用”,是指在已往工作中使用Struts里经常用到的)的标志了。


  要在JSP中使用Struts 2.0标志,先要指明标志的引入。通过在JSP的代码的顶部加入以下代码可以做到这点。
<%@taglib prefix="s" uri="/struts-tags" %>

非UI标志
if、elseif和else
描述:
执行基本的条件流转。

参数:

名称 必需 默认 类型 描述 备注
test 是  Boolean 决定标志里内容是否显示的表达式 else标志没有这个参数
id 否  Object/String 用来标识元素的id。在UI和表单中为HTML的id属性  

例子:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>Condition Flow</title>
    </head>
    <body>
        <h3>Condition Flow</h3>           
        <!--
            这里有点小技巧:
            本来可以用#parameters.name[0]来获得,请求中name的值。但是,在我实现include例子时,
            无论我用param标志给name赋任何值,#parameters里面不会含有任何值,所以#parameters.name也为空

值。
           
            其原因为:
            当使用include标志时,被包含的页面(included)里#parameters拿到的是包含页面里的请求参数。
           
            因此,这里必须手工调用request.getParameter("name")。
        -->
        <s:set name="name" value="<%= "'" + request.getParameter("name") + "'" %>" />
        <s:if test="#name == 'Max'">
            Max's file here
        </s:if>
        <s:elseif test="#name == 'Scott'">
            Scott's file here
        </s:elseif>
        <s:else>
            Other's file here
        </s:else>       
    </body>
</html>
例1 condition.jsp

iterator
描述:
用于遍历集合(java.util.Collection)或枚举值(java.util.Iterator)。

参数:

名称 必需 默认 类型 描述
status 否  String 如果设置此参数,一个IteratorStatus的实例将会压入每个遍历的堆栈
value 否  Object/String 要遍历的可枚举的(iteratable)数据源,或者将放入新列表(List)的对象
id 否  Object/String 用来标识元素的id。在UI和表单中为HTML的id属性 

例子:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
    List list = new ArrayList();
    list.add("Max");
    list.add("Scott");
    list.add("Jeffry");
    list.add("Joe");
    list.add("Kelvin");
    request.setAttribute("names", list);
%>
<html>
    <head>
        <title>Iterator</title>
    </head>
    <body>
        <h3>Names: </h3>
        <!--
            1、此处的空property元素用于获得当前iterator的值
            2、status被设成stuts,在iterator的里面就可以通过#stuts取得IteratorStatus的对象。

IteratorStatus类包含当前序号信息,如是否第一个或最后一个,是否为奇数序号。这些信息在我们做格式化的时候

,显得非常有用。
        -->
        <ol>
            <s:iterator value="#request.names" status="stuts">               
                <s:if test="#stuts.odd == true">
                    <li>White <s:property /></li>
                </s:if>
                <s:else>
                    <li style="background-color:gray"><s:property /></li>
                </s:else>
            </s:iterator>
        </ol>
    </body>
</html>
例2 iterator.jsp

i18n
描述:
加载资源包到值堆栈。它可以允许text标志访问任何资源包的信息,而不只当前action相关联的资源包。

参数:

名称 必需 默认 类型 描述
value 是  Object/String 资源包的类路径(如com.xxxx.resources.AppMsg)
id 否  Object/String 用来标识元素的id。在UI和表单中为HTML的id属性 

例子:

HelloWorld=Hello Wrold!
例3 classes\ ApplicationMessages.properties


<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>Internationization</title>
    </head>
    <body>
        <h3>
            <s:i18n name="ApplicationMessages">
                <s:text name="HelloWorld" />
            </s:i18n>
        </h3>
    </body>
</html>
例3 i18n.jsp

include
描述:
包含一个servlet的输出(servlet或jsp的页面)。

参数:

名称 必需 默认 类型 描述
value 是  String 要包含的jsp或servlet
id 否  Object/String 用来标识元素的id。在UI和表单中为HTML的id属性 

例子:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>Iterator</title>
    </head>
    <body>
        <h3>Interator Page</h3>
        <s:include value="/condition.jsp">
            <s:param name="name">Max</s:param>
        </s:include>
        <h3>i18n</h3>
        <s:include value="/i18n.jsp" />
    </body>
</html>
例4 include.jsp

param
描述:
为其他标签提供参数,比如include标签和bean标签. 参数的name属性是可选的,如果提供,会调用Component的方法

addParameter(String, Object), 如果不提供,则外层嵌套标签必须实现UnnamedParametric接口(如TextTag)。


 value的提供有两种方式,通过value属性或者标签中间的text,不同之处我们看一下例子:

<param name="color">blue</param><!-- (A) -->

<param name="color" value="blue"/><!-- (B) -->
(A)参数值会以String的格式放入statck.
(B)该值会以java.lang.Object的格式放入statck.
 

参数:

名称 必需 默认 类型 描述
name 否  String 参数名
value 否  String value表达式
id 否  Object/String 用来标识元素的id。在UI和表单中为HTML的id属性 

例子:
请参考例4。

set
描述:
set标签赋予变量一个特定范围内的值。当希望给一个变量赋一个复杂的表达式,每次访问该变量而不是复杂的表达式

时用到。其在两种情况下非常有用: 复杂的表达式很耗时 (性能提升) 或者很难理解 (代码可读性提高)。

参数:

名称 必需 默认 类型 描述
name 是  String 变量名字
scope 否  String 变量作用域,可以为application, session, request, page, 或action.
value 否  Object/String 将会赋给变量的值
id 否  Object/String 用来标识元素的id。在UI和表单中为HTML的id属性 

例子:
请参考例1。

text
描述:
支持国际化信息的标签。国际化信息必须放在一个和当前action同名的resource bundle中,如果没有找到相应

message,tag body将被当作默认message,如果没有tag body,message的name会被作为默认message。

参数:

名称 必需 默认 类型 描述
name 是  String 资源属性的名字
id 否  Object/String 用来标识元素的id。在UI和表单中为HTML的id属性 

例子:
请参考例3。

url
描述:
该标签用于创建url,可以通过"param"标签提供request参数。


 当includeParams的值时'all'或者'get', param标签中定义的参数将有优先权,也就是说其会覆盖其他同名参数的值

。 

参数: 略

例子:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>URL</title>
    </head>
    <body>
        <h3>URL</h3>           
        <a href='<s:url value="/i18n.jsp" />'>i18n</a><br />
        <s:url id="url" value="/condition.jsp">
            <s:param name="name">Max</s:param>
        </s:url>       
        <s:a href="%{url}">if\elseif\else</s:a>
    </body>
</html>
例5 url.jsp

property
描述:
得到'value'的属性,如果value没提供,默认为堆栈顶端的元素。

参数:

名称 必需 默认 类型 描述
default 否  String 如果属性是null则显示的default值
escape 否 true Booelean 是否escape HTML
value 否 栈顶 Object 要显示的值
id 否  Object/String 用来标识元素的id。在UI和表单中为HTML的id属性 

例子:
请参考例2。

 

--------------------------------------------------------------------------------
UI标志UI标志又可以分为表单UI和非表单UI两部分。表单UI部分基本与Struts 1.x相同,都是对HTML表单元素的包装

。不过,Struts 2.0加了几个我们经常在项目中用到的控件如:datepicker、doubleselect、timepicker、

optiontransferselect等。因为这些标志很多都经常用到,而且参数也很多,要在一篇文章详细说明并非易事。


 需要深入了解这些标志的朋友,可以到以下查看以下网址:
http://wiki.javascud.org/display/ww2cndoc/Tags WebWork2文档中文化计划(中文)
http://cwiki.apache.org/WW/tag-reference.html Tag Developers Guide(英文)
本文有相当的内容也来自这两处。 
 

--------------------------------------------------------------------------------
Struts 2.0的Action讲解http://www.blogjava.net/max/archive/2006/10/25/77157.html

当请求HelloWorld.action发生时,Struts运行时(Runtime)根据struts.xml里的Action映射集(Mapping),实例化

tutoiral.HelloWorld类,并调用其execute方法。当然,我们可以通过以下两种方法改变这种默认调用。这个功能

(Feature)有点类似Struts 1.x中的LookupDispathAction。

在classes/sturts.xml中新建Action,并指明其调用的方法;
访问Action时,在Action名后加上“!xxx”(xxx为方法名)。
现方法一,在classes/sturts.xml中加入下面代码:
<action name="AliasHelloWorld" class="tutorial.HelloWorld" method="aliasAction">
   <result>/HelloWorld.jsp</result>
</action>例2 classes/struts.xml中AlaisHelloWorld Action的配置
通过上面的两个例子,细心的朋友应该可能会发现classes/tutorial/HelloWorld.java中Action方法(execute和

aliasAction)返回都是SUCCESS。这个属性变量我并没有定义,所以大家应该会猜到它在ActionSupport或其父类中定

义。没错,SUCCESS在接口com.opensymphony.xwork2.Action中定义,另外同时定义的还有ERROR, INPUT, LOGIN,

NONE。

此外,我在配置Action时都没有为result定义名字(name),所以它们默认都为success。值得一提的是Struts 2.0中

的result不仅仅是Struts 1.x中forward的别名,它可以实现除forward外的很激动人心的功能,如将Action输出到

FreeMaker模板、Velocity模板、JasperReports和使用XSL转换等。这些都过result里的type(类型)属性

(Attribute)定义的。另外,您还可以自定义result类型。

下面让我们来做一个Velocity模板输出的例子,首先在classes/struts.xml中新建一个Action映射(Mapping),将其

result类型设为velocity,如以下代码所示:
<action name="VMHelloWorld" class="tutorial.HelloWorld">
    <result type="velocity">/HelloWorld.vm</result>
</action>例3 classes/struts.xml中VMHelloWorld Action的配置

新建HelloWorld.vm,内容如下所示:
<html>
  <head>
    <title>Velocity</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <h2>Message rendered in Velocity: $message</h2>
  </body>
</html>例3 HelloWorld.vm


很多时候我的同事会问我:“如果我要取得Servlet API中的一些对象,如request、response或session等,应该怎么

做?这里的execute不像Struts 1.x的那样在参数中引入。”开发Web应用程序当然免不了跟这些对象打交道。在

Strutx 2.0你可以有两种方式获得这些对象:非IoC(控制反转Inversion of Control)方式和IoC方式。

非IoC方式

要获得上述对象,关键Struts 2.0中com.opensymphony.xwork2.ActionContext类。我们可以通过它的静态方法

getContext()获取当前Action的上下文对象。 另外,org.apache.struts2.ServletActionContext作为辅助类

(Helper Class),可以帮助您快捷地获得这几个对象。

HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = request.getSession();
如果你只是想访问session的属性(Attribute),你也可以通过ActionContext.getContext().getSession()获取或添

加session范围(Scoped)的对象。

IoC方式

要使用IoC方式,我们首先要告诉IoC容器(Container)想取得某个对象的意愿,通过实现相应的接口做到这点。具体

实现,请参考例6 IocServlet.java。
package tutorial;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

publicclass NonIoCServlet extends ActionSupport {
    private String message;
   
    public String getMessage() {
        return message;       
    }
   
    @Override
    public String execute() {   
        ActionContext.getContext().getSession().put("msg", "Hello World from Session!");
       
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();       
        HttpSession session = request.getSession();
       
        StringBuffer sb =new StringBuffer("Message from request: ");
        sb.append(request.getParameter("msg"));
        sb.append("<br>Response Buffer Size: ");
        sb.append(response.getBufferSize());
        sb.append("<br>Session ID: ");
        sb.append(session.getId());
       
        message = sb.toString();
        return SUCCESS;
    }
}例6 classes/tutorial/NonIoCServlet.java

package tutorial;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

publicclass IoCServlet extends ActionSupport implements SessionAware, ServletRequestAware,

ServletResponseAware {
    private String message;
    private Map att;
    private HttpServletRequest request;
    private HttpServletResponse response;   
   
    public String getMessage() {
        return message;       
    }
   
    publicvoid setSession(Map att) {
        this.att = att;
    }
   
    publicvoid setServletRequest(HttpServletRequest request) {
        this.request = request;
    }
   
    publicvoid setServletResponse(HttpServletResponse response) {
        this.response = response;
    }
   
    @Override
    public String execute() {       
        att.put("msg", "Hello World from Session!");
       
        HttpSession session = request.getSession();
       
        StringBuffer sb =new StringBuffer("Message from request: ");
        sb.append(request.getParameter("msg"));
        sb.append("<br>Response Buffer Size: ");
        sb.append(response.getBufferSize());
        sb.append("<br>Session ID: ");
        sb.append(session.getId());
       
        message = sb.toString();
        return SUCCESS;
    }
}例6 classes/tutorial/IoCServlet.java

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    <h2>
        <s:property value="message" escape="false"/>
        <br>Message from session: <s:property value="#session.msg"/>
    </h2>
</body>
</html>例6 Servlet.jsp

<action name="NonIoCServlet" class="tutorial.NonIoCServlet">
    <result>/Servlet.jsp</result>
</action>
<action name="IoCServlet" class="tutorial.IoCServlet">
    <result>/Servlet.jsp</result>
</action>

 


--------------------------------------------------------------------------------
在src文件夹中加入struts.properties文件,内容如下:
struts.custom.i18n.resources=globalMessages
Struts 2.0有两个配置文件,struts.xml和struts.properties都是放在WEB-INF/classes/下。
struts.xml用于应用程序相关的配置
struts.properties用于Struts 2.0的运行时(Runtime)的配置


在src文件夹中加入globalMessages_en_US.properties文件,内容如下:
HelloWorld=Hello World!
在src文件夹中加入globalMessages_zh_CN.properties文件,内容如下:
HelloWorld=你好,世界!

在WebContent文件夹下加入HelloWorl.jsp文件,内容如下:
<%@ page  contentType="text/html; charset=UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
    <title>Hello World</title>
</head>
<body>
    <h2><s:text name="HelloWorld"/></h2>
    <h2><s:property value="%{getText('HelloWorld')}"/></h2>
</body>
</html>
资源文件查找顺序
之所以说Struts 2.0的国际化更灵活是因为它可以能根据不同需要配置和获取资源(properties)文件。在Struts

2.0中有下面几种方法:

使用全局的资源文件,方法如上例所示。这适用于遍布于整个应用程序的国际化字符串,它们在不同的包(package)

中被引用,如一些比较共用的出错提示;
使用包范围内的资源文件。做法是在包的根目录下新建名的package.properties和package_xx_XX.properties文件。

这就适用于在包中不同类访问的资源;
使用Action范围的资源文件。做法为Action的包下新建文件名(除文件扩展名外)与Action类名同样的资源文件。它

只能在该Action中访问。如此一来,我们就可以在不同的Action里使用相同的properties名表示不同的值。例如,在

ActonOne中title为“动作一”,而同样用title在ActionTwo表示“动作二”,节省一些命名工夫;
使用<s:i18n>标志访问特定路径的properties文件。使用方法请参考我早前的文章《常用的Struts 2.0的标志(Tag)

介绍》。在您使用这一方法时,请注意<s:i18n>标志的范围。在<s:i18n name="xxxxx">到</s:i18n>之间,所有的国

际化字符串都会在名为xxxxx资源文件查找,如果找不到,Struts 2.0就会输出默认值(国际化字符串的名字)。
上面我列举了四种配置和访问资源的方法,它们的范围分别是从大到小,而Struts 2.0在查找国际化字符串所遵循的

是特定的顺序,如图3所示:


图3 资源文件查找顺序图
假设我们在某个ChildAction中调用了getText("user.title"),Struts 2.0的将会执行以下的操作:

查找ChildAction_xx_XX.properties文件或ChildAction.properties;
查找ChildAction实现的接口,查找与接口同名的资源文件MyInterface.properties;
查找ChildAction的父类ParentAction的properties文件,文件名为ParentAction.properties;
判断当前ChildAction是否实现接口ModelDriven。如果是,调用getModel()获得对象,查找与其同名的资源文件;
查找当前包下的package.properties文件;
查找当前包的父包,直到最顶层包;
在值栈(Value Stack)中,查找名为user的属性,转到user类型同名的资源文件,查找键为title的资源;
查找在struts.properties配置的默认的资源文件,参考例1;
输出user.title。
参数化国际化字符串
许多情况下,我们都需要在动行时(runtime)为国际化字符插入一些参数,例如在输入验证提示信息的时候。在

Struts 2.0中,我们通过以下两种方法做到这点:

在资源文件的国际化字符串中使用OGNL,格式为${表达式},例如:
validation.require=${getText(fileName)} is required
使用java.text.MessageFormat中的字符串格式,格式为{ 参数序号(从0开始), 格式类形(number | date | time

| choice), 格式样式},例如:
validation.between=Date must between {0, date, short} and {1, date, short}
在显示这些国际化字符时,同样有两种方法设置参数的值:

使用标志的value0、value1...valueN的属性,如:
<s:text name="validation.required" value0="User Name"/>
使用param子元素,这些param将按先后顺序,代入到国际化字符串的参数中,例如:
<s:text name="validation.required">
   <s:param value="User Name"/>
</s:text>
让用户方便地选择语言
开发国际化的应用程序时,有一个功能是必不可少的——让用户快捷地选择或切换语言。在Struts 2.0中,通过

ActionContext.getContext().setLocale(Locale arg)可以设置用户的默认语言。不过,由于这是一个比较普遍的应

用场景(Scenario),所以Struts 2.0为您提供了一个名i18n的拦截器(Interceptor),并在默认情况下将其注册到

拦截器链(Interceptor chain)中。它的原理为在执行Action方法前,i18n拦截器查找请求中的一个名

为"request_locale"的参数。如果其存在,拦截器就将其作为参数实例化Locale对象,并将其设为用户默认的区域

(Locale),最后,将此Locale对象保存在session的名为“WW_TRANS_I18N_LOCALE”的属性中。

下面,我将提供一完整示例演示它的使用方法。

package tutorial;

import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;

publicclass Locales {
    public Map<String, Locale> getLocales() {
        Map<String, Locale> locales =new Hashtable<String, Locale>(2);
        locales.put("American English", Locale.US);
        locales.put("Simplified Chinese", Locale.CHINA);
        return locales;
    }
}tutorial/Locales.java

<%@taglib prefix="s" uri="/struts-tags"%>
<script type="text/javascript">
<!--
    function langSelecter_onChanged() {
        document.langForm.submit();
    }
//-->
</script>
<s:set name="SESSION_LOCALE" value="#session['WW_TRANS_I18N_LOCALE']"/>
<s:bean id="locales" name="tutorial.Locales"/>
<form action="<s:url includeParams="get" encode="true"/>" name="langForm"
    style="background-color: powderblue; padding-top: 4px; padding-bottom: 4px;">
    Language: <s:select label="Language"
        list="#locales.locales" listKey="value"    listValue="key"
        value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE"
        name="request_locale" id="langSelecter"
        onchange="langSelecter_onChanged()" theme="simple"/>
</form>LangSelector.jsp
上述代码的原理为,LangSelector.jsp先实例化一个Locales对象,并把对象的Map类型的属性locales赋予下拉列表(

select) 。如此一来,下拉列表就获得可用语言的列表。大家看到LangSelector有<s:form>标志和一段Javascript脚

本,它们的作用就是在用户在下拉列表中选择了后,提交包含“reqeust_locale”变量的表单到Action。在打开页面

时,为了下拉列表的选中的当前区域,我们需要到session取得当前区域(键为“WW_TRANS_I18N_LOCALE”的属性),

而该属性在没有设置语言前是为空的,所以通过值栈中locale属性来取得当前区域(用户浏览器所设置的语言)。

你可以把LangSelector.jsp作为一个控件使用,方法是在JSP页面中把它包含进来,代码如下所示: <s:include

value="/LangSelector.jsp"/>
在例1中的HellloWorld.jsp中<body>后加入上述代码,并在struts.xml中新建Action,代码如下:
<action name="HelloWorld">
    <result>/HelloWorld.jsp</result>
</action>
或者,如果你多个JSP需要实现上述功能,你可以使用下面的通用配置,而不是为每一个JSP页面都新建一个Action。
<action name="*">
    <result>/{1}.jsp</result>
</action>
分布运行程序,在浏览器的地址栏中输入http://localhost:8080/Struts2_i18n/HelloWorld.action,出现图4所示页

面:

图3 HelloWorld.action

在下拉列表中,选择“American English”,出现图5所示页面:

图4 HelloWorld.action
可能大家会问为什么一定要通过Action来访问页面呢?
你可以试一下不用Action而直接用JSP的地址来访问页面,结果会是无论你在下拉列表中选择什么,语言都不会改变。

这表示不能正常运行的。其原因为如果直接使用JSP访问页面,Struts 2.0在web.xml的配置的过滤器(Filter)就不

会工作,所以拦截器链也不会工作。

posted on 2007-11-02 12:07 芦苇 阅读(2292) 评论(0)  编辑  收藏 所属分类: Struts

只有注册用户登录后才能发表评论。


网站导航: