`
lxh2002
  • 浏览: 126123 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

关于Struts2与Validation框架使用中的问题

阅读更多

完成的项目文件:直接下载 。下面先简要说明一下创建过程:

 

1、先在MyEclipse中创建一个Web项目,项目名字为Struts20。如果你用的是Eclipse,则创建的是“Dynamic Web Project”。

 

2、从Struts官方网站下载struts-2.0.14-all.zip,解压缩,从中拷贝以下五个文件到项目的WEB-INF/lib目录下面:

 

3、修改web.xml文件,在其中添加一个过滤器:

    <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>


4、新建一个reg.jsp页面,并在其中添加一个表单(使用了Struts2的标签库):

<s:form action="register" namespace="/" method="post">
    <s:textfield name="name" key="name" size="20" />
    <s:textfield name="age" key="age" size="20" />
    <s:textfield name="telephone" key="telephone" size="20" />
    <s:submit key="label.register.submit" align="center" />
</s:form>

 

5、新建一个success.jsp页面:

    <h2>Registered: <s:property value="name" /> !</h2>

 

6、在项目的src目录下面创建两个文件:ApplicationResources.properties 和 struts.xml

ApplicationResources.properties文件内容为:

name= Name
age= Age
telephone= Telephone
label.register.submit= Submit

errors.required=${getText(fieldName)} is required.
errors.range=${getText(fieldName)} is not in the range ${min} and ${max}.

struts.xml文件内容为(部分):

<struts>
    <constant name="struts.custom.i18n.resources" value="ApplicationResources" />

    <package name="default" extends="struts-default" namespace="/">
        <action name="register" class="test.RegisterAction">
            <result name="success">success.jsp</result>
            <result name="input">reg.jsp</result>
        </action>
       
    </package>
</struts>

7、创建一个RegisterAction的类,源代码如下:

package test;

import com.opensymphony.xwork2.ActionSupport;

public class RegisterAction extends ActionSupport{
    private String name;
    private Integer age;
    private String telephone;

    public String execute() {
        return SUCCESS;
    }

    ...  // getter和setter方法

}

 

现在可以运行一下,首页指向reg.jsp,应该能够成功提交。

但是,如果表单中不写 namespace="/" 的话,你会看到下面的警告:

No configuration found for the specified action: 'register' in namespace: ''. Form action defaulting to 'action' attribute's literal value.

这是因为我们在struts.xml中定义的Action指定了namespace,因此使用时如果不在表单中指定namespace的话,Struts2会到""这一默认的namespace中去找。

 

 

注意到,我们前面在web.xml中添加过滤器的时候,使用的是“/*”,但在有些地方我们也会看到使用“*.action”的情形,那么这两者之间有什么区别呢?

试着修改一下web.xml文件,将“/*”替换成“*.action”,然后再次运行,浏览reg.jsp页面,我们会看到下面的异常信息:

The Struts dispatcher cannot be found . This is usually caused by using Struts tags without the associated filter . Struts tags are only usable when the request has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag. - [unknown location]

原因解释:如果在jsp页面中用到了Struts2的标签库,必须让该jsp页面经过Struts2过滤器处理一下。因为我们提交的是reg.jsp,只有*.action的链接才会由Struts2来处理。

 

有些文章提到在这种情况下(即url映射方式为*.action),可以使用另一种方法强制让Struts2过滤器处理jsp页面。我们可以修改struts.xml文件:

    <package name="default" extends="struts-default" namespace="/">
        <action name="register" class=...> ... </action>
        <action name="*">
            <result>{1}.jsp</result>
        </action>
    </package>

这是一个通用的Action配置,此时提交形如“reg .action”的链接时,Struts2最后会转到reg .jsp页面中去。

再试着运行一下,在浏览器中输入: http://..../Struts20/reg.action,看看会不会出现正常的页面。不过,如果提交的链接是http://..../Struts20/reg的话,就会出现HTTP404的错误(我做试验得到的是这种结果),原因是我们已经在web.xml中配置url映射方式是“*.action”。

 

为了不找麻烦的话,干脆在web.xml中就直接配置映射方式为“/*”就一劳永逸了。

 

接下来我们再来看看Struts2中的验证框架的使用。在Struts2中有多种验证方式,可以是传统的手工Javascript验证,也可以直接使用Struts2的验证框架。要启用验证框架的步骤很简单,我们需要在RegisterAction类的相同位置新建一个配套的RegisterAction-validation.xml文件,其主要内容为:

<validators>
    <field name="name ">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="errors.required" />
        </field-validator>
    </field>
    <field name="age ">
        <field-validator type="required">
            <message key="errors.required" />
        </field-validator>
        <field-validator type="int">
            <param name="min">1</param>
            <param name="max">100</param>
            <message key="errors.range"/>
        </field-validator>
    </field>
    <field name="telephone" >
        <field-validator type="requiredstring">
            <message key="errors.required" />
        </field-validator>
    </field>
</validators>
这里的蓝色部分必须与页面中的命名完全一致(实际上和RegisterAction类的几个成员变量名字也是一致的)。其中对用户name的验证规则是:必填(忽略前后的空格);对用户age的验证规则是:必填、整数、大小介于1-100之间;对用户telephone的验证规则是:必填。

 

配置好了验证的xml文件后,还需要在jsp页面中启用验证:

<s:form action="register" namespace="/" method="post" validate="true" >
   ...
</s:form>

 

运行一下,是不是得到下面失望的结果:

FreeMarker template error!

Method public java.lang.String com.opensymphony.xwork2.validator.validators.ValidatorSupport.getMessage(java.lang.Object) threw an exception when invoked on com.opensymphony.xwork2.validator.validators.RequiredStringValidator@f62eba
The problematic instruction:
----------
==> ${validator.getMessage(action)?js_string} [on line 50, column 26 in template/xhtml/form-close-validate.ftl]
 in include "/${parameters.templateDir}/xhtml/form-close-validate.ftl" [on line 25, column 1 in template/xhtml/form-close.ftl]
----------

Java backtrace for programmers:
...

这是什么原因呢?

接下来我们再来试验,修改reg.jsp页面:

<s:form action="register.action " namespace="/" method="post" validate="true" >
   ...
</s:form>

即在表单的action属性中附加“.action”后缀。再次运行,我们的确看到了reg.jsp页面的结果,但MyEclipse的控制台又出现了下面的信息:

2010-7-22 12:53:34 org.apache.struts2.components.Form evaluateExtraParamsServletRequest
警告: No configuration found for the specified action: 'register.action' in namespace: '/'. Form action defaulting to 'action' attribute's literal value.

意思是我们在struts.xml文件中没有定义名为“register.action ”的Action配置。查阅Struts2的标签库文档可知,s:form标签的action属性的确不需要再附加“.action”后缀:

 

action Set action name to submit to, without .action suffix

 

那为什么我们按照要求不加.action后缀会引发异常呢,问题的症结在哪里?

原来啊,我们使用的验证框架里用到了资源文件,此时就要求必须先进入action,然后再转入jsp才行。至于在s:form中添加.action后缀可以使得reg.jsp能够正常显示的原因(虽然出现了 No configuration found for the specified action 的警告 ),我没能找到答案

 

最后的解决办法:

(1)struts.xml中配置通用Action

    <package name="default" extends="struts-default" namespace="/">
        <action name="register" class=...> ... </action>
        <action name="*">
            <result>{1}.jsp</result>
        </action>
    </package>

(2)web.xml配置过滤器

    <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>

(3)对于需要用到资源文件的jsp页面,且该页面又要用到验证框架,我们采用

                   http://..../Struts20/reg.action

        的方式来转向我们真正关心的reg.jsp 页面。

 

另外,如果你仍然希望在链接中使用“reg.jsp”来得到正常的页面的话,可在struts.xml中重新配置如下:

 

<struts>
    <constant name="struts.custom.i18n.resources" value="ApplicationResources" />
    <constant name="struts.action.extension" value="action,jsp" />

    <package name="default" extends="struts-default" namespace="/">
        <action name="register" class="test.RegisterAction">
            <result name="success">success.jsp</result>
            <result name="input">reg.jsp</result>
        </action>

        <action name="*">
            <result>{1}.jsp</result>
        </action>

        
    </package>
</struts>

上面的配置是把后缀“.jsp”也纳入与“.action”同等对待,即寻找对应Action进行处理。

现在可以在浏览器地址栏中输入 http://..../Struts20/reg.jsp 看看结果是否正常。

 

  • 大小: 3.3 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics