我想弄个登录页面客户端验证的功能,现在碰到个问题。
如果我表单写成
<s:form action="login.action" validate="true">
……
</s:form>
的形式,就变成服务器端验证了,而且不管我用没有输入字符,验证消息都是我设定的“必须输入”的提示信息如果我把表单改成
<s:form action="login" validate="true">
……
</s:form>
登录页面就无法显示,报错如下
type Exception reportmessage description The server encountered an internal error () that prevented it from fulfilling this request.exception org.apache.jasper.JasperException: Method public java.util.List org.apache.struts2.components.Form.getValidators(java.lang.String) threw an exception when invoked on org.apache.struts2.components.Form@1dafbaf - Class: freeer.ext.beans.SimpleMethodModel
File: SimpleMethodModel.java
Method: exec
Line: 130 - freeer/ext/beans/SimpleMethodModel.java:130:-1
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:522)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:416)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:88)我的strut.xml是这么写的
<action name="login" class="lifeinfo.Login">
<result name="input">/login.jsp</result>
<result name="success"></result>
<result name="error"></result>
</action>Login-validation.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.3//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<validators>
<field name="username">
<field-validator type="requiredstring">
<message>用户名不能为空!</message>
</field-validator>
</field>
</validators>
谁能告诉我是哪里的问题?

解决方案 »

  1.   

    你form中的input有name="username"属性吗?
      

  2.   

    <s:form action="login" validate="true"> 虽然没用过struts2,但我想问题应该是这里
    没有找到action
      

  3.   

    有,这是我form的代码
    <s:form action="login" validate="true">
    <s:textfield label="用户名" name="username"/>
    <s:password label="密码" name="password"></s:password>
    <s:submit value="登录"></s:submit>
    <s:reset value="清空"></s:reset>
    </s:form>
      

  4.   

    看看demo吧,貌似就用过一回,还是刚学的时候
      

  5.   

    1.设置<s:form />标签validate属性为true。
    2.标签theme属性一定不能为simple。
    3.写校验的xml文件。
      

  6.   

    第一第三个我都弄了,第二个我尝试指定为xhtml,还是老样子报错
      

  7.   

    你页面form里onsubmit=“return表单名()”了还有下面引用javascript标签了吗?
      

  8.   

    貌似没什么错啊,你的Login-validation.xml是和Login.action在同一个目录下吗
      

  9.   

    <validators>
    <field name="username">
    <field-validator type="requiredstring">
    <message>用户名不能为空! </message>
    </field-validator> 
    你在到网上查查相关actionName-valudation.xml的写法
      

  10.   

    我写的是validation的客户端验证,要JavaScript标签干嘛?
      

  11.   

    由于是action级的验证。
    所有的struts.xml里面对应这个ACTION的都必须有INPUT类型的返回
    <action>
    <result name="input"></result>
    </action>
      

  12.   

    input我有写,上面的代码我贴出来的部分里有
      

  13.   

    握手啊,
    楼主,我也是这个问题啊!!!!
    一模一样我照着 《Struts2.1权威指南》
    编写例子结果和你的错误一模一样
    一开始,我怀疑是JDK的问题
    因为 控制台 显示
    2009-12-28 18:53:12 freeer.log.JDK14LoggerFactory$JDK14Logger error
    我换成JDK 6.0 还是一样的
    而且还有一个,不知道你遇到过没
    你看看
    http://topic.csdn.net/u/20091225/10/bc6a364a-51b6-4241-90ff-6de38461fd63.html
      

  14.   

    没摸清楚这个问题.
    我给你推荐一个,如果你按着里面的来肯定不会错的.
    http://struts.apache.org/2.1.8.1/docs/bootstrap.html
    Hello World --> We present a page with a simple Welcome message.  
    Using Tags  --> We create a Welcome page with links to other 
    actions in the application.  
    Coding Actions --> We interpret the Logon form, and return a 
    different result code depending on the circumstances.  
    Selecting Results --> We setup different results for different result codes.  
    Validating Input --> We use the validation framework to verify 
    data submitted from a form. 
    Localizing Output --> We move the validation messages to a message resource bundle.  
    到Validating Input这步肯定没问题
      

  15.   

    确实,因为这个不是客户端验证!
    http://struts.apache.org/2.1.8.1/docs/client-validation.html这个才是 客户端验证 的官方文档 中的例子但但是,他依然报错!!!!!!!!!
      

  16.   

    Lz,我发现Struts2.X的客户端验证与Struts1.X的客户端有不同,Struts1.X客户端验证,会以Alert("XXXXXX");的形式弹出来,但Struts2.X不会,它表现出来的效果和服务器验证的是一样.
    if validate="true" 你会发现你的页面上会生成好多的代码,还导入了好几个js文件.
    当我不填写任何信息的时候,我点击submit。我使用抓包工具发现,它并没有向服务器提交,
    但提示出了我的错误"不能为空",与服务器验证一模一样.
    if validate="false"及服务器验证页面源代码完全不同.
    使用抓包工具发现,它每次验证都要请求服务器一次.所以你按最先的配置是没错的.
    抓包工具用的是:httpWatch是一个IE插件.
      

  17.   


    效果一样,但请注意
    action=*****   namespace=/test
    这样配置 form的话, 页面 编译就会出错action=/test/*****.action
    这样配置 form的话, 页面 通过编译
    点击提交注意注意,地址栏 提交了;
    地址栏 变成了 ..../test/*****.action
    这就不是客户端验证了,而变成了 服务器验证了!!!!!
      

  18.   


    你去弄个 js 错误控制台 看看
    提交的时候 js报错,说找不到对象!也就是说,Struts2.1 本应该 在页面生成的一些 用以客户端验证的js 没有生成!
    造成 提交时,js无法找到 客户端验证程序,而浏览器为了客户体验,通常忽略js错误,
    所以 页面提交了,从而也就变成了 服务器端的验证了!!!!!!!
      

  19.   

    客户端验证 还不如用js。 用struts的action,不可避免的要提交到服务器
      

  20.   

    楼主在登录页面看看html源码中的那段js生成没有
    如果是客户端认证,会自动生成一段js验证的
      

  21.   


    我下了
    页面中<head>
        <title>Validation - Basic</title>
        <link rel="stylesheet" href="/struts2/struts/xhtml/styles.css" type="text/css"/>
    <script src="/struts2/struts/utils.js" type="text/javascript"></script>
    </head><body> <script type="text/javascript" src="/struts2/struts/xhtml/validation.js"></script>
    <script type="text/javascript" src="/struts2/struts/utils.js"></script>

    <form id="quizClient" name="quizClient" onsubmit="return validateForm_quizClient();" action="/struts2/docs/quizClient.action" method="post"  onreset="clearErrorMessages(this);clearErrorLabels(this);"
    >
    ………………这里两次 导入
    /struts2/struts/utils.js
    一次导入
    /struts2/struts/xhtml/validation.js最大的问题 就是
    onsubmit="return validateForm_quizClient();" 
    validateForm_quizClient() 这个函数在两个js中都没有定义我前面 想法 是对的!
    Struts的确没有生成 js
      

  22.   


    你看看我的,我的是服务器验证:
    工程:
    Struts2.1.8
      --src
        --tutorial
          --QuizAction.java
          --QuizAction-validation.xml
      --struts.xml
      --WebRoot
        --validate
          --success.jsp
        --validation.jsp QuizAction.java
    package tutorial;import com.opensymphony.xwork2.ActionSupport;public class QuizAction extends ActionSupport { private static final long serialVersionUID = -7505437345373234225L;    String name;
        int age;
        String answer;    public String getName() {
            return name;
        }    public void setName(String name) {
            this.name = name;
        }    public int getAge() {
            return age;
        }    public void setAge(int age) {
            this.age = age;
        }    public String getAnswer() {
            return answer;
        }    public void setAnswer(String answer) {
            this.answer = answer;
        }}
    QuizAction-validation.xml
    <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork 
    Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
    <validators>
    <field name="name">
    <field-validator type="requiredstring">
    <message>You must enter a name</message>
    </field-validator>
    </field>
    <field name="age">
    <field-validator type="int">
    <param name="min">13</param>
    <param name="max">19</param>
    <message>
    Only people ages 13 to 19 may take this quiz
    </message>
    </field-validator>
    </field>
    </validators>
    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="testvalidate" namespace="/validate"
    extends="struts-default">
    <action name="quizClient" class="tutorial.QuizAction">
    <result name="success">success.jsp</result>
    </action>
    <action name="*">
    <result>/{1}.jsp</result>
    </action>
    </package>
    </struts>validation.jsp
    <%@ taglib prefix="s" uri="/struts-tags"%>
    <html>
    <head>
        <title>Validation - Basic</title>
        <s:head/>
    </head><body><s:form method="post" validate="true" action="quizClient" namespace="/validate">
        <s:textfield label="Name" name="name"/>
        <s:textfield label="Age" name="age"/>
        <s:textfield label="Favorite color" name="answer"/>
        <s:submit/>
    </s:form></body>
    </html>
    启动服务器:
    访问:http://localhost:8080/Struts2.1.8/validate/validation页面上会生成js:<html>
    <head>
        <title>Validation - Basic</title>
        <link rel="stylesheet" href="/Struts2.1.8/struts/xhtml/styles.css" type="text/css"/>
    <script src="/Struts2.1.8/struts/utils.js" type="text/javascript"></script>
    </head><body> <script type="text/javascript" src="/Struts2.1.8/struts/xhtml/validation.js"></script> <script type="text/javascript" src="/Struts2.1.8/struts/utils.js"></script>

    <form id="quizClient" name="quizClient" onsubmit="return validateForm_quizClient();" action="/Struts2.1.8/validate/quizClient" method="post"  onreset="clearErrorMessages(this);clearErrorLabels(this);"
    >
    <table class="wwFormTable">
        <tr>
        <td class="tdLabel"><label for="quizClient_name" class="label">Name:</label></td>
        <td
    ><input type="text" name="name" value="" id="quizClient_name"/></td>
    </tr>    <tr>    <td class="tdLabel"><label for="quizClient_age" class="label">Age:</label></td>
        <td
    ><input type="text" name="age" value="" id="quizClient_age"/></td>
    </tr>    <tr>
        <td class="tdLabel"><label for="quizClient_answer" class="label">Favorite color:</label></td>
        <td
    ><input type="text" name="answer" value="" id="quizClient_answer"/></td>
    </tr>    <tr>    <td colspan="2"><div align="right"><input type="submit" id="quizClient_0" value="Submit"/>
    </div></td>
    </tr></table></form><script type="text/javascript">
        function validateForm_quizClient() {
            form = document.getElementById("quizClient");
            clearErrorMessages(form);
            clearErrorLabels(form);        var errors = false;
            var continueValidation = true;
            // field name: name
            // validator name: requiredstring
            if (form.elements['name']) {
                field = form.elements['name'];
                var error = "You must enter a name";
                if (continueValidation && field.value != null && (field.value == "" || field.value.replace(/^\s+|\s+$/g,"").length == 0)) {
                    addError(field, error);
                    errors = true;
                    
                }
            }
            // field name: age
            // validator name: int
            if (form.elements['age']) {
                field = form.elements['age'];
                var error = "\n\t\t\t\tOnly people ages 13 to 19 may take this quiz\n\t\t\t";
                if (continueValidation && field.value != null) {
                    if (parseInt(field.value) <
                         13 ||
                            parseInt(field.value) >
                               19) {
                        addError(field, error);
                        errors = true;
                        
                    }
                }
            }        return !errors;
        }
    </script>
    </body>
    </html>
    绝对是客户端验证;
    可以试试....
      

  23.   

    要注意官方说的这段话:
    Action and Namespace
    A correct action and namespace attributes must be provided to the <s:form> tag. 
    For example, if the action named "quizClient" is defined in the "/validation" namespace, the form must be configured as:
    <s:form method="post" validate="true" action="quizClient" namespace="/validation">
       <s:textfield label="Name" name="name"/>
       <s:textfield label="Age" name="age"/>
       <s:textfield label="Favorite color" name="answer"/>
       <s:submit/>
    </s:form> While the following will "work" in the sense that the form will function correctly, client-side validation will not. That is because Struts must know the exact namespace and action (rather than a URL) to properly support validation.<s:form method="post" validate="true" action="/validation/quizClient.action">
       <s:textfield label="Name" name="name"/>
       <s:textfield label="Age" name="age"/>
       <s:textfield label="Favorite color" name="answer"/>
       <s:submit/>
    </s:form> 
      

  24.   


    你用的Struts 几点几的版本啊?
      

  25.   


    晕,通过Struts跳转 jsp就可以
    直接访问 jsp就不行你试一试直接打开页面
    http://localhost:8080/Struts2.1.8/validation.jsp
      

  26.   


    官网 只说 在<s:form>中 要明确告诉Struts框架 action的名字
    所以 要制定namespace和action
    但为什么 不说明,必须通过Struts跳转到jsp才行
    直接访问jsp就报错呢?
      

  27.   

    我有个问题:
    为什么doubleselect:
    <s:doubleselect label="doubleselect test1" name="menu" list="{'fruit','other'}" doubleName="dishes" doubleList="top == 'fruit' ? {'apple', 'orange'} : {'monkey', 'chicken'}" />页面加载就出现这问题:
    FreeMarker template error!Expression parameters.formName is undefined on line 108, column 43 in template/simple/doubleselect.ftl.
    The problematic instruction:
    ----------
    ==> ${parameters.formName} [on line 108, column 41 in template/simple/doubleselect.ftl]
     in include "/${parameters.templateDir}/simple/doubleselect.ftl" 
    [on line 25, column 1 in template/xhtml/doubleselect.ftl]
    ----------Java backtrace for programmers:
    ----------
    qiuyufeifei请帮忙看下这个问题
      

  28.   


    这个我不太清楚,我还没看到 Struts标签 那去呢!
    不过,上次在官网 看到 2.1.8的BUG列表中有doubleselect 的BUG
    你去看看 bug列表
      

  29.   


    看来 Struts2.1 是想做 总控器啊
    把应用入口 全部由Struts来控制
    struts-->jsp-->struts-->.......原来的习惯都是
    jsp--->struts这样也好,安全性更高,
    全站不会留下多个入口Sql注入 扫描 也不容易找到入口而且,很多 项目实际开发中,把jsp都放到web-inf目录中用servlet或者Struts 做总控器,
    以达到 隐藏 jsp代码的目的。
      

  30.   

    是个Bug
    https://issues.apache.org/struts/browse/WW-3274
    在Struts2.2.0中fix
      

  31.   

    我也遇到了lz的问题。不知道你们有没有解决了。我原来的package是没有加namespace的
        <package name="default" extends="authority">            
            <action name="login" class="loginAction">
                <result name="success" type="redirect">/UserOperations/listAllUsers</result>
                <result name="error">/authorityPages/errors/GeneralError.jsp</result>
                <result name="input">/Login.jsp</result>
            </action>
        </package>
    但是当我加上以后就好了,而且奇怪的是我原本一直好的。
        <package name="default" namespace="/" extends="authority">            
            <action name="login" class="loginAction">
                <result name="success" type="redirect">/UserOperations/listAllUsers</result>
                <result name="error">/authorityPages/errors/GeneralError.jsp</result>
                <result name="input">/Login.jsp</result>
            </action>
        </package>我不知道是不是所有的情况都是这样的情况引起的。为后来人做个参考吧。
      

  32.   

    必须使用一个间接的方法如下:
    定义一个新的action,用于显示该JSP文件,需要在struts.xml中加入
    <action name="showLogin" class="ShowLoginAction">
    <result>/some.jsp</result>
    </action>
    建立一个新的类ShowLoginAction.java,其中的execute()方法就单单返回SUCCESS,而这个页面已经定义为some.jsp(含有验证表单到页面)。
    那么在浏览器的地址栏中就输入,比如说tomcat的localhost:8080/projectname/showLogin.action
    这样就能够显示出some.jsp的内容,而后的客户端验证也顺利进行。
    记得千万把Login-validation.xml与Login.java放在一起,我为此折腾了挺长时间。
    我是从这里学到到
    http://www.google.com/url?sa=t&rct=j&q=struts2+client+validation&source=web&cd=1&ved=0CDAQFjAA&url=http%3A%2F%2Fwww.roseindia.net%2Fstruts%2Fstruts2%2Fstruts-2-client-side-validation-example.shtml&ei=B1KKT_7HJPPciAKgp92wCw&usg=AFQjCNGD5Q9FIgGKF-BFb4k3jHL2zLXtlg