错误现象:
用户注册处理
stuts.xml:
<action name="userInfo_*" class="com.indexofme.action.UserInfoAction" method="{1}">
<result name="success">/WEB-INF/view/success.jsp</result>
<result name="input">/WEB-INF/view/register.jsp</result>
<result name="error">/WEB-INF/view/register.jsp</result>
</action>
因为使用struts framework xml进行校验,如果直接请求userInfo_register.action将会返回input视图,并显示输入错误的提示信息(因为userInfo_registe.actionr与这个action匹配,com.indexofme.action.UserInfoAction将对这个请求进行处理,在此之前会根据同路径下的UserInfoAction-userInfo_register-validation.xml进行校验,校验失败返回input视图)。因此希望用户能通过请求userInfo_register.action 直接进入注册页面即input视图(相当于使用action做超链接进入注册页),并通过标签 <s:fielderror/>返回类型转换失败及校验失败提示信息。
(后记:直接进入注册页面,可以请求userInfo_input.action 。也可以单独配置action
<action name="userInfo_register">
<result>/WEB-INF/view/user/login.jsp</result>
</action>
不要再让com.indexofme.action.UserInfoAction对其进行处理,否则struts会提前调用与其对应的校验文件进行校验,然后不仅返回input视图还会在你并未曾输入情况下,返回输入错误的提示信息。)
但是请求userInfo_register.action 时出现错误。
1.使用<s:fielderror/>时出现异常:
FreeMarker template error!
Expression eKey is undefined on line 71, column 63 in template/simple/fielderror.ftl. The problematic instruction: ---------- ==> assignment: eValue=fieldErrors[eKey] [on line 71, column 33 in template/simple/fielderror.ftl] ---------- Java backtrace for programmers: ---------- freemarker.core.InvalidReferenceException: Expression eKey is undefined on line 71, column 63 in template/simple/fielderror.ftl.
2.使用<s:fielderror>
<s:param value="%{'email'}" />
<s:param value="%{'pwd'}" />
</s:fielderror>
时异常:
FreeMarker template error!
Expression eKey is undefined on line 32, column 23 in template/simple/fielderror.ftl. The problematic instruction: ---------- ==> if (eKey = fieldErrorFieldName) [on line 32, column 17 in template/simple/fielderror.ftl] ---------- Java backtrace for programmers: ---------- freemarker.core.InvalidReferenceException: Expression eKey is undefined on line 32, column 23 in template/simple/fielderror.ftl.
原因分析:
显然,把userInfo_register.action做超链接使用并用<s:fielderror>显示相应提示的方案不可行。原因就是:第一次请求时因为并未填写过注册页,struts framework或者说freeMarker
获取不到表单域的标识,这个也许是struts framework或者说freeMarker在设计方面没有考虑全面。(这个结论是错误的,详情看下篇文章)
这个问题一定是和fieldError的key相关,可以从一般添加fieldError的方法addFieldError("register","pwd error")知道,一般情况下,应该是struts校验框架的freemarker
模版获取不到key值导致。查看一下validate.xml文件:
<validators>
<validator type="requiredstring">
<param name="fieldname">pwd</param>
<message>password is required.</message>
</validator>
</validators>
这个是参照官网写的。有相应资源文件: pwd 注册密码。
改成:
<field name="pwd">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>${getText("regist_validate.pwd.require")}</message>
</field-validator>
</field>
好使了,参看官方文档:
email validator的两种添加方法
<!-- Plain Validator Syntax --> <validators> <validator type="email"> <param name="fieldName">myEmail</param> <message>Must provide a valid email</message> </validator> </validators>
<!-- Field Validator Syntax -->
<field name="myEmail"> <field-validator type="email"> <message>Must provide a valid email</message> </field-validator> </field>
我自己估计是因为pwd与资源文件中的pwd重名,struts在找“pwd”时直接转换成“注册密码”,导致输出fieldError时找不到 key值,即“pwd”。
但是去掉pwd资源文件,仍然出现同样的错:Expression eKey is undefined on line 71, column 63 in template/simple/fielderror.ftl.。
不知原因,我用的是freemarker-2.3.16.jar
解决办法:
换成一种validator.xml的配置方法。
注意:也有可能是你的fieldname属性写错了,我经常把email写成mail。