zoukankan      html  css  js  c++  java
  • Action 跟 Actionsupport 的区别

    转自:http://www.cnblogs.com/xlwmin/articles/2212416.html

    Action 跟 Actionsupport 的区别
    当我们在写action的时候,可以实现Action接口,也可以继承Actionsupport这个类.到底这两个有什么区别呢?

    Action接口有:
    public static final java.lang.String SUCCESS = "success";
    public static final java.lang.String NONE = "none";
    public static final java.lang.String ERROR = "error";
    public static final java.lang.String INPUT = "input";
    public static final java.lang.String LOGIN = "login";

    public abstract java.lang.String execute() throws java.lang.Exception;

    而Actionsupport这个工具类在实现了Action接口的基础上还定义了一个validate()方法,重写该方法,它会在execute()方法之前执行,如校验失败,会转入input处,必须在配置该Action时配置input属性。

    另外,Actionsupport还提供了一个getText(String key)方法还实现国际化,该方法从资源文件上获取国际化信息.

    这样在自定义标签时可以定义一个变量为new actionsupport对象实现国际化。


    ActionSupport类的作用
    struts2不要求我们自己设计的action类继承任何的struts基类或struts接口,但是我们为了方便实现我们自己的action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并重写此类里的public String execute() throws Exception方法。因为此类中实现了很多的实用借口,提供了很多默认方法,这些默认方法包括国际化信息的方法、默认的处理用户请求的方法等,这样可以大大的简化Acion的开发。
    Struts2中通常直接使用Action来封装HTTP请求参数,因此,Action类里还应该包含与请求参数对应的属性,并且为属性提供对应的getter和setter方法。
    ==========================
    <s:property>
    关于struts2标签取值的备忘录

    取值要通过<s:property value="" />或在任意的<s:/>标签内使用%{};

    当Action的valueStack中有该属性的值时,只需直接使用该属性的名字即可;

    当Action的valueStack中没有该属性的值时,比如在session,application范围中的属性值时,需要加#或者#attr.;

    例子:
    假设某Action中有person成员变量,在application中存在company属性
    那么我们可以通过以下方法取值:
    <s:property value="person.name" />
    <s:property value="#person.name" />
    <s:property value="company.name" /> //无法取到,因为company不在action的valueStack中
    <s:property value="#company.name" />

    <s:textfield name="person.name" value="person.name" /> //错误,value会直接显示person.name字样
    <s:textfield name="person.name" value="%{person.name}" />
    <s:textfield name="person.company.name" value="%{#company.name}" />
    <s:textfield name="person.company.name" value="%{#attr.company.name}" />
    =====================
    一次Action调用都会创建一个ActionContext
    调用:ActionContext context = ActionContext.getContext()
    ValueStack由OGNL框架实现
    可以把它简单的看作一个集合
    Stack Object:放入stack中的对象,一般是action
    Stack Context(map):stack上下文,它包含一些列对象,包括request/session/attr/application map等。
    EL:存取对象的任意属性,调用对象的方法,遍历整个对象结…
    ===========
    WebWork2.2笔记(二)ActionSupport及其他基础知识
    绝大多数情况下,WebWork不是直接实现com.opensymphony.xwork.Action接口,而是扩展 com.opensymphony.xwork.ActionSupport类。ActionSupport实现了除Action以外的其他几个接口,主要的几个接口是:
    com.opensymphony.xwork.Validateable
    com.opensymphony.xwork.Validateaware
    com.opensymphony.xwork.TextProvider
    com.opensymphony.xwork.LocaleProvider
    这些接口主要是提供给WebWork的拦截器使用的,接口配合拦截器可以实现AOP功能。比如Validateable接口和Validateaware 接口配合DefailtWorkflowInterceptor就可以实现对用户输入进行检验的功能,当用户调用Action时,首先执行 Validateable接口定义的validate()方法,如果在这个方法中用户使用接口Validateaware中的方法设置了错误信息,则 DefaultWorkflowInterceptor会自动终止Action的执行,并产生一个INPUT的result,只有没有任何错误信息才会执行Action的剩余部分。

    前面我们定义的xwork.xml配置文件中包含了一句:<include file="webwork-default.xml">,这个webwork-default.xml包含在webwork的jar包中。 webwork-default.xml预建了很多常用的result-type、interceptor和interceptor-stack。其中 interceptor和interceptor-stack用于定义webwork将要使用那些拦截器。interceptor定义一个拦截器,而 interceptor定义一组拦截器。如果一个Action使用一组拦截器,则这些拦截器将以其定义的顺序执行,可见,interceptor- stack中拦截器的顺序时很重要的。

    在webwork-default.xml中有如下定义:
    <interceptor class="com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor" name="workflow">
    ......
    而名为validationWorkflowStack和completeStack这两个预建的interceptor-stack则包含了workflow这个interceptor。

    下面做一个检查用户输入的练习,如果用户没有输入内容,则让用户重新输入,并且提示错误信息。

    web.xml
    与上次的相同。

    xwork.xml
    </interceptor></include>
    xml 代码


    1.
    2. "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">
    3.
    4. <xwork>
    5. <include file="webwork-default.xml" />
    6.
    7. <package name="default" extends="webwork-default">
    8.
    9. <default-interceptor-ref name="validationWorkflowStack"/>
    10. <action name="alidateInput" class="example.ValidateInputAction">
    11. <result name="success">success.jspresult>
    12. <result name="input">input.jspresult>
    13. action>
    14.
    15. package>
    16. xwork>


    input.jsp
    xml 代码


    1. <%@taglib prefix="ww" uri="/webwork"%>
    2. <html>
    3. <head><title>Input Somethingtitle>head>
    4. <body>
    5.
    6. <ww:form action="alidateInput.action">
    7. <ww:textfield label="Input something:" name="something">ww:textfield>
    8. <ww:submit>ww:submit>
    9. ww:form>
    10.
    11. body>
    12. html>


    success.jsp
    xml 代码


    1. <%@taglib prefix="ww" uri="/webwork"%>
    2. <html>
    3. <head><title>Success!title>head>
    4. <body>
    5. <ww:property value="something"/>
    6. body>
    7. html>

    ==============================
    Action的实例,总是放到value stack中。因为Action放在stack中,而stack是root(根对象),所以对Action中的属性的访问就可以省略#标记。但是,要访问 ActionContext中其它对象的属性,就必须要带上#标记,以便让OGNL知道,不是从根对象,而是从其它对象中去寻找。

    Struts2中OGNL,valueStack,stackContext的学习
    学习Struts2,一直不明白表单中的值是怎么传给Action的,上网查了些资料,基本了解了!下面基本是从几个人的BOLG转载过来,以后记不清了再来看~

    [color=red]先看看我做的实验jsp页面
    Java代码

    <s:form action="hello/converter.action" method="post">
    <s:textfield name="point" label="点"></s:textfield>
    <s:textfield name="point2" label="2"></s:textfield>
    <s:textfield name="point3" label="3"></s:textfield>
    <s:textfield name="age" label="年龄"></s:textfield>
    <s:textfield name="date" label="日期"></s:textfield>
    <s:submit name="提交"></s:submit>
    </s:form>


    结果图(是通过<s:debug></s:debug>得到的)
    value stack:

    [点击查看原始大小图片]

    Stack context:

    通过图中我们可以看到
    valuestack中包括我传递的值(point,point2,point3,age,date)
    stack context中包括了 request application OgnlValueStack(root) session parameters 等属性

    值栈(ValueStack)    
    Struts2将OGNL上下文设置为Struts2中的ActionContext(内部使用的仍然是OgnlContext),并将值栈设为OGNL的根对象。    
    我们知道,OGNL上下文中的根对象可以直接访问,不需要使用任何特殊的“标记”,而引用上下文中的其他对象则需要使用“#”来标记。由于值栈是上下文中的根对象,因此可以直接访问。那么对于值栈中的对象该如何访问呢?Struts2提供了一个特殊的OGNLPropertyAccessor,它可以自动查找栈内的所有对象(从栈顶到栈底),直接找到一个具有你所查找的属性的对象。也就是说,对于值栈中的任何对象都可以直接访问,而不需要使用 “#”。    
    假设值栈中有两个对象:student和employee,两个对象都有name属性,student有学号属性number,而 employee有薪水属性salary。employee先入栈,student后入栈,位于栈顶,那么对于表达式name,访问的就是student 的name属性,因为student对象位于栈顶;表达式salary,访问的就是employee的salary属性。正如你所见,访问值栈中的对象属性或方法,无须指明对象,也不用“#”,就好像值栈中的对象都是OGNL上下文中的根对象一样。这就是Struts2在OGNL基础上做出的改进。

    值栈中的Action实例  
    Struts2框架总是把Action实例放在栈顶。因为Action在值栈中,而值栈又是OGNL中的根,所以引用Action的属性可以省略“#”标记,这也是为什么我们在结果页面中可以直接访问Action的属性的原因。

    Struts2中的命名对象    
    Struts2还提供了一些命名对象,这些对象没有保存在值栈中,而是保存在ActionContext中,因此访问这些对象需要使用“#”标记。这些命名对象都是Map类型。   

    parameters    
    用于访问请求参数。如:#parameters['id']或#parameters.id,相当于调用了HttpServletRequest对象的getParameter()方法。    
    注意,parameters本质上是一个使用HttpServletRequest对象中的请求参数构造的Map对象,一量对象被创建(在调用Action实例之前就已经创建好了),它和HttpServletRequest对象就没有了任何关系。 

    request    
    用于访问请求属性。如:#request['user']或#request.user,相当于调用了HttpServletRequest对象的getAttribute()方法。   

    session    
    用于访问session属性。如:#session['user']或#session.user,相当于调用了HttpSession对象的getAttribute()方法。   

    application    
    用于访问application属性。如:#application['user']或#application.user,相当于调用了ServletContext的getAttribute()方法。   

    attr    
    如果PageContext可用,则访问PageContext,否则依次搜索request、session和application对象。

    以下是转过来的:先分清楚下ActionContext 、ValueStack 、Stack Context三者

    ActionContext
    一次Action调用都会创建一个ActionContext
    调用:ActionContext context = ActionContext.getContext()

    ValueStack
    由OGNL框架实现
    可以把它简单的看作一个栈(List) 。

    Stack Object:放入stack中的对象,一般是action。
    Stack Context(map):stack上下文,它包含一系列对象,包括request/session/attr/application map等。
    EL:存取对象的任意属性,调用对象的方法,遍历整个对象结…

    ActionContext是Action上下文,可以得到request session application
    ValueStack是值栈 存放表单中的值
    Stack Context 栈上下文 也是用来存值的



    struts2对OGNL上下文的概念又做了进一步扩充,在struts2中,OGNL上下文通常如下所示:

    |--request

    |

    |--application

    |

    context map---|--OgnlValueStack(root) [ user, action, OgnlUtil, ... ]

    |

    |--session

    |

    |--attr

    |

    |--parameters




    在Struts2中,采用标准命名的上下文(Context)来处理OGNL表达式。处理OGNL的顶级对象是一个Map(也叫context map),而OGNL在这个context中就是一个顶级对象(root)。在用法上,顶级对象的属性访问,是不需要任何标记前缀的。而其它非顶级的对象访问,需要使用#标记。
    Struts2框架把OGNL Context设置为我们的ActionContext。并且ValueStack作为OGNL的根对象。除value stack之外,Struts2框架还把代表application、session、request这些对象的Map对象也放到 ActionContext中去。(这也就是Struts2建议在Action类中不要直接访问Servlet API的原因,他可以通过ActionContext对象来部分代替这些(Servlet API)功能,以方便对Action类进行测试!)
    Action的实例,总是放到value stack中。因为Action放在stack中,而stack是root(根对象),所以对Action中的属性的访问就可以省略#标记。但是,要访问 ActionContext中其它对象的属性,就必须要带上#标记,以便让OGNL知道,不是从根对象,而是从其它对象中去寻找。
    那么访问Action中的属性的代码就可以这样写

    <s:property value="postalCode"/>
    其它ActionContext中的非根对象属性的访问要像下面这样写:
    <s:property value="#session.mySessionPropKey"/> or
    <s:property value="#session['mySessionPropKey']"/> or
    <s:property value="#request['myRequestPropKey']"/>
    对Collection的处理,内容就很简单。
    <s:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}" />
    这是处理List。这个代码在页面上建立一个下拉选项,内容是list中的内容,默认值是name2.
    处理map

    <s:select label="label" name="name" list="#{'foo':'foovalue', 'bar':'barvalue'}" />

    需要注意的是,判断一个值是否在collection中。我们要使用in或者not in来处理。
    <s:if test="'foo' in {'foo','bar'}">
    muhahaha
    </s:if>
    <s:else>
    boo
    </s:else>
    另外,可以使用通配符来选择collection对象的子集。
    ?——所有匹配选择逻辑的元素
    ^——只提取符合选择逻辑的第一个元素
    $——只提取符合选择逻辑的最后一个元素
    person.relatives.{? #this.gender == 'male'}

    `````````````````````````````````````````````````````````````````````````````````

    以下为补充摘录的一些问题:

    提问:在Struts2中,如何使用自身的Tag读取Action中的变量?

    Struts2自身的Tag会根据value中的OGNL表达式,在ValueStack中寻找相应的对象。因为action在 ValueStack的顶部,所以默认情况下,Struts2的Tag中的OGNL表达式将查找action中的变量。请注意,value中的内容直接是 OGNL表达式,无需任何el的标签包装。

    例如:<s:property value="user.name" />

    提问:在Struts2中,如何使用自身的Tag读取HttpServletRequest,HttpSession中的变量?

    在上面的知识中,我们知道,Struts2中OGNL的上下文环境中,包含request,session,application等 servlet对象的Map封装。既然这些对象都在OGNL的上下文中,那么根据OGNL的基本知识,我们可以通过在表达式前面加上#符号来对这些变量的值进行访问。

    例如:<s:property value="%{#application.myApplicationAttribute}" />
    <s:property value="%{#session.mySessionAttribute}" />
    <s:property value="%{#request.myRequestAttribute}" />
    <s:property value="%{#parameters.myParameter}" />



    提问:在Struts2中,如何使用JSTL来读取Action中的变量?

    这是一个历史悠久的问题。因为事实上,很多朋友(包括我在内)是不使用Struts2自身的标签库,而是使用JSTL的,可能因为JSTL标签库比较少,简单易用的原因吧。

    我们知道,JSTL默认是从page,request,session,application这四个Scope逐次查找相应的EL表达式所对应的对象的值。那么如果要使用JSTL来读取Action中的变量,就需要把Action中的变量,放到request域中才行。所以,早在 Webwork2.1.X的年代,我们会编写一个拦截器来做这个事情的。大致的原理是:在Action执行完返回之前,依次读取Action中的所有的变量,并依次调用request.setAttribute()来进行设置。具体的整合方式,请参考以下这篇文档:http://wiki.opensymphony.com/display/WW /Using+WebWork+and+XWork+with+JSP+2.0+and+JSTL+1.1

    不过随着时代的发展,上面的这种方式,已经不再被推荐使用了。(虽然如此,我们依然可以学习它的一个解决问题的思路)目前来说,自从 Webwork2.2以后,包括Struts2,都使用另外一种整合方式:对HttpServletRequest进行装饰。让我们来看一下源码:
    Java代码

    public class StrutsRequestWrapper extends HttpServletRequestWrapper {

    /**
    * The constructor
    * @param req The request
    */
    public StrutsRequestWrapper(HttpServletRequest req) {
    super(req);
    }

    /**
    * Gets the object, looking in the value stack if not found
    *
    * @param s The attribute key
    */
    public Object getAttribute(String s) {
    if (s != null && s.startsWith("javax.servlet")) {
    // don't bother with the standard javax.servlet attributes, we can short-circuit this
    // see WW-953 and the forums post linked in that issue for more info
    return super.getAttribute(s);
    }

    ActionContext ctx = ActionContext.getContext();
    Object attribute = super.getAttribute(s);

    boolean alreadyIn = false;
    Boolean b = (Boolean) ctx.get("__requestWrapper.getAttribute");
    if (b != null) {
    alreadyIn = b.booleanValue();
    }

    // note: we don't let # come through or else a request for
    // #attr.foo or #request.foo could cause an endless loop
    if (!alreadyIn && attribute == null && s.indexOf("#") == -1) {
    try {
    // If not found, then try the ValueStack
    ctx.put("__requestWrapper.getAttribute", Boolean.TRUE);
    ValueStack stack = ctx.getValueStack();
    if (stack != null) {
    attribute = stack.findValue(s);
    }
    } finally {
    ctx.put("__requestWrapper.getAttribute", Boolean.FALSE);
    }
    }
    return attribute;
    }
    }



    看到了嘛?这个类会在Struts2初始化的时候,替换HttpServletRequest,运行于整个Struts2的运行过程中,当我们试图调用 request.getAttribute()的时候,就会执行上面的这个方法。(这是一个典型的装饰器模式)在执行上面的方法时,会首先调用 HttpServletRequest中原本的request.getAttribute(),如果没有找到,它会继续到ValueStack中去查找,而action在ValueStack中,所以action中的变量通过OGNL表达式,就能找到对应的值了。

    在这里,在el表达式广泛使用的今天,JSTL1.1以后,也支持直接使用el表达式。注意与直接使用struts2的tag的区别,这里需要使用el的表示符号:${}

    例如:${user.name}, <c:out value="${department.name}" />

    提问:在Struts2中,如何使用Freemarker等模板来读取Action中的变量以及HttpServletRequest和HttpSession中的变量?

    Freemarker等模板在Struts2中有对应的Result,而在这些Result中,Freemarker等模板会根据 ValueStack和ActionContext中的内容,构造这些模板可识别的Model,从而使得模板可以以他们各自的语法对ValueStack 和ActionContext中的内容进行读取。

    有关Freemarker对于变量的读取,可以参考Struts2的官方文档,非常详细:http://struts.apache.org/2.0.14/docs/freemarker.html

    设值计算

    Struts2中使用OGNL进行设值计算,就是指View层传递数据到Control层,并且能够设置到相应的Java对象中。这个过程从逻辑上说需要分成两步来完成:

    1. 对于每个请求,都建立一个与相应Action对应的ActionContext作为OGNL的上下文环境和ValueStack,并且把Action压入ValueStack

    2. 在请求进入Action代码前,通过某种通用的机制,搜集页面上传递过来的参数,并调用OGNL相关的代码,对Action进行设值。
    上面的第一个步骤,在处理URL请求时完成,而第二个步骤由struts2内置的拦截器完成。
    ================================
    Struts2教程:使用validate方法验证数据
    在Struts2中最简单的验证数据的方法是使用validate。我们从ActionSupport类的源代码中可以看到,ActionSupport类实现了一个Validateable接口。这个接口只有一个validate方法。如果Action类实现了这个接口,Struts2在调用execute方法之前首先会调用这个方法,我们可以在validate方法中验证,如果发生错误,可以根据错误的level选择字段级错误,还是动作级错误。并且可使用addFieldError或addActionError加入相应的错误信息,如果存在Action或 Field错误,Struts2会返回“input”(这个并不用开发人员写,由Struts2自动返回),如果返回了“input”,Struts2就不会再调用execute方法了。如果不存在错误信息,Struts2在最后会调用execute方法。

    这两个add方法和ActionErrors类中的add方法类似,只是add方法的错误信息需要一个ActionMessage对象,比较麻烦。除了加入错误信息外,还可以使用addActionMessage方法加入成功提交后的信息。当提交成功后,可以显示这些信息。

    以上三个add方法都在ValidationAware接口中定义,并且在ActionSupport类中有一个默认的实现。其实,在 ActionSupport类中的实现实际上是调用了ValidationAwareSupport中的相应的方法,也就是这三个add方法是在 ValidationAwareSupport类中实现的,代码如下:

    1. private final ValidationAwareSupport validationAware = new ValidationAwareSupport();
    2.
    3. public void addActionError(String anErrorMessage)
    4. { validationAware.addActionError(anErrorMessage);
    5. }
    6. public void addActionMessage(String aMessage)
    7. {
    8. validationAware.addActionMessage(aMessage);
    9. }
    10. public void addFieldError(String fieldName, String errorMessage)
    11. {
    12. validationAware.addFieldError(fieldName, errorMessage);
    13. }

    下面我们来实现一个简单的验证程序,来体验一个validate方法的使用。

    先来在Web根目录建立一个主页面(validate.jsp),代码如下:

    1. < %@ page language="java" import="java.util.*" pageEncoding="GBK"%>
    2. < %@ taglib prefix="s" uri="/struts-tags" %>
    3. < html>
    4. < head>
    5. < title>验证数据< /title>
    6. < /head>
    7.
    8. < body>
    9. < s:actionerror/>
    10. < s:actionmessage/>
    11. < s:form action="validate.action" theme="simple">
    12. 输入内容:< s:textfield name="msg"/>
    13. < s:fielderror key="msg.hello" />
    14. < br/>
    15. < s:submit/>
    16. < /s:form>
    17. < /body>
    18. < /html>

    在上面的代码中,使用了Struts2的tag:< s:actionerror>、< s:fielderror>和< s:actionmessage>,分别用来显示动作错误信息,字段错误信息,和动作信息。如果信息为空,则不显示。

    现在我们来实现一个动作类,代码如下:

    1. package action;
    2.
    3. import javax.servlet.http.*;
    4.
    5. import com.opensymphony.xwork2.ActionSupport;
    6. import org.apache.struts2.interceptor.*;
    7.
    8. public class ValidateAction extends ActionSupport
    9. {
    10. private String msg;
    11. public String execute()
    12. {
    13. System.out.println(SUCCESS);
    14. return SUCCESS;
    15. }
    16. public void validate()
    17. {
    18. if(!msg.equalsIgnoreCase("hello"))
    19. {
    20. System.out.println(INPUT);
    21. this.addFieldError("msg.hello", "必须输入hello!");
    22. this.addActionError("处理动作失败!");
    23. }
    24. else
    25. {
    26. this.addActionMessage("提交成功");
    27. }
    28. }
    29. public String getMsg()
    30. {
    31. return msg;
    32. }
    33. public void setMsg(String msg)
    34. {
    35. this.msg = msg;
    36. }
    37. }

    大家从上面的代码可以看出,Field错误需要一个key(一般用来表示是哪一个属性出的错误),而Action错误和Action消息只要提供一个信息字符串就可以了。

    最后来配置一下这个Action,代码如下:

    1. < package name="demo" extends="struts-default">
    2. < action name="validate" class="action.ValidateAction">
    3. < result name="success">/error/validate.jsp< /result>
    4. < result name="input">/error/validate.jsp< /result>
    5. < /action>
    6. < /package>

    假设应用程序的上下文路径为demo,则可通过如下的URL来测试程序:

    http://localhost:8080/demo/validate.jsp

    我们还可以使用ValidationAware接口的其他方法(由ValidationAwareSupport类实现)获得或设置字段错误信息、动作错误信息以及动作消息。如hasActionErrors方法判断是否存在动作层的错误,getFieldErrors获得字段错误信息(一个Map 对象)。下面是ValidationAware接口提供的所有的方法:

    1. package com.opensymphony.xwork2;
    2.
    3. import java.util.Collection;
    4. import java.util.Map;
    5.
    6. public interface ValidationAware
    7. {
    8. void setActionErrors(Collection errorMessages);
    9. Collection getActionErrors();
    10.
    11. void setActionMessages(Collection messages);
    12. Collection getActionMessages();
    13. void setFieldErrors(Map errorMap);
    14. Map getFieldErrors();
    15. void addActionError(String anErrorMessage);
    16. void addActionMessage(String aMessage);
    17. void addFieldError(String fieldName, String errorMessage);
    18. boolean hasActionErrors();
    19. boolean hasActionMessages();
    20. boolean hasErrors();
    21. boolean hasFieldErrors();
    22. }
    ===========================
    实现com.opensymphony.xwork2.TextProvider接口 --需要导入xwork.jar
    该接口主要提供读取消息资源文件,获取消息文本的功能。该接口的getText()用来获取消息文本的内容。

    一般继承ActionSupport助手类,其实现了TextProvider接口并提供了默认实现
    所以在,action/拦截器中(只要其继承了actionSupport)要获取资料文件(properties文件),可以直接放入以下代码:

    import com.opensymphony.xwork2.LocaleProvider;
    import com.opensymphony.xwork2.TextProvider;
    import com.opensymphony.xwork2.TextProviderFactory;

    public class Log拦截器 extends AbstractInterceptor implements LocaleProvider
    {
    //初始化拦截器时,获取资源文件
    public void init() {
    protected TextProvider operateCodeProvider = new TextProviderFactory().createInstance(
    ResourceBundle.getBundle( "LogDefinitions资源文件名", getLocale()), this);
    }

    /**
    * 获取语言
    */
    public Locale getLocale() {
    ActionContext ctx = ActionContext.getContext();
    if (ctx != null) {
    return ctx.getLocale();
    } else {
    sysLogger.debug("Action context not initialized");
    return null;
    }
    }

    调用方法:
    this.operateCodeProvider.getText("hwj") -->便可获取hwj的值.
    }

    看看ActionSupport 是怎样实现TextProvider的:
    public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider,
    LocaleProvider, Serializable {
    protected static Logger LOG = LoggerFactory.getLogger(ActionSupport.class);
    private final transient TextProvider textProvider = new TextProviderFactory().createInstance
    (getClass(), this);
    //返回国际化信息的方法
    public String getText(String aTextName) {
    return textProvider.getText(aTextName);
    }

  • 相关阅读:
    1027 Colors in Mars (20 分)
    1025 PAT Ranking (25 分)
    1024 Palindromic Number (25 分)
    JVM调优之jstack找出最耗cpu的线程并定位代码
    kill -3 获取threaddump信息
    java单例支持高并发
    yum出现的“UnicodeDecodeError: 'ascii' codec”问题解决
    命令行参数
    vyatta常用操作
    mysql5.8安装指南
  • 原文地址:https://www.cnblogs.com/PatrickLee/p/2617696.html
Copyright © 2011-2022 走看看