您的位置:首页 > 编程语言 > Java开发

Struts(二十四):短路验证&重写实现转换验证失败时短路&非字段验证

2017-04-10 18:08 453 查看
[b]短路验证:[/b]

若对一个字段使用多个验证器,默认情况下会执行所有的验证。若希望前面的验证器没有通过,后面的验证器就不再执行,可以使用短路验证。

1、如下拦截器,如果输入字符串,提交表单后,默认是会出现三个错误:字段转换失败、conversion验证失败、取值范围失败。

<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">

<validators>
<field name="age">
<field-validator type="conversion">
<message>Conversion error!</message>
</field-validator>
<field-validator type="int">
<param name="max">180</param>
<param name="min">1</param>
<message key="ageErrorMsg"></message>
</field-validator>
</field>
</validators>


2、如果使用短路验证,则如果输入字符串,提交表单后,默认是会出现两个错误:字段转换失败、conversion验证失败。

<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">

<validators>
<field name="age">
<field-validator type="conversion" short-circuit="true">
<message>Conversion error!</message>
</field-validator>
<field-validator type="int">
<param name="max">180</param>
<param name="min">1</param>
<message key="ageErrorMsg"></message>
</field-validator>
</field>
</validators>


[b]重写实现转换失败时短路:[/b]

若类型转换失败,默认情况下会执行后边的额拦截器,还会进行验证。可以通过修改ConversionErrorInterceptor源代码的方式,实现当类型转换失败时,不再执行后边的验证拦截器,从而直接返回input的result。

  从上边的例子中我们知道,只要我们输入的字段类型不合法必定会在错误信息中包含示:类型转换失败错误信息。

  那么,怎么避免这个错误信息呢?

  首先,从struts2-core.jar根目录下的struts-default.xml中的default-stack(默认拦截器栈)中我们得知,类型转化是通过params(com.opensymphony.xwork2.interceptor.ParametersInterceptor

/*
* Copyright 2002-2007,2009 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0 *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.opensymphony.xwork2.interceptor;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ValidationAware;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.commons.lang3.StringEscapeUtils;

import java.util.HashMap;
import java.util.Map;

/**
* <!-- START SNIPPET: description --> ConversionErrorInterceptor adds
* conversion errors from the ActionContext to the Action's field errors.
*
* <p/>
* This interceptor adds any error found in the {@link ActionContext}'s
* conversionErrors map as a field error (provided that the action implements
* {@link ValidationAware}). In addition, any field that contains a validation
* error has its original value saved such that any subsequent requests for that
* value return the original value rather than the value in the action. This is
* important because if the value "abc" is submitted and can't be converted to
* an int, we want to display the original string ("abc") again rather than the
* int value (likely 0, which would make very little sense to the user).
*
*
* <!-- END SNIPPET: description -->
*
* <p/>
* <u>Interceptor parameters:</u>
*
* <!-- START SNIPPET: parameters -->
*
* <ul>
*
* <li>None</li>
*
* </ul>
*
* <!-- END SNIPPET: parameters -->
*
* <p/>
* <u>Extending the interceptor:</u>
*
* <p/>
*
* <!-- START SNIPPET: extending -->
*
* Because this interceptor is not web-specific, it abstracts the logic for
* whether an error should be added. This allows for web-specific interceptors
* to use more complex logic in the {@link #shouldAddError} method for when a
* value has a conversion error but is null or empty or otherwise indicates that
* the value was never actually entered by the user.
*
* <!-- END SNIPPET: extending -->
*
* <p/>
* <u>Example code:</u>
*
* <pre>
* <!-- START SNIPPET: example -->
* <action name="someAction" class="com.examples.SomeAction">
*     <interceptor-ref name="params"/>
*     <interceptor-ref name="conversionError"/>
*     <result name="success">good_result.ftl</result>
* </action>
* <!-- END SNIPPET: example -->
* </pre>
*
* @author Jason Carreira
*/
public class ConversionErrorInterceptor extends AbstractInterceptor {

public static final String ORIGINAL_PROPERTY_OVERRIDE = "original.property.override";

protected Object getOverrideExpr(ActionInvocation invocation, Object value) {
return escape(value);
}

protected String escape(Object value) {
return "\"" + StringEscapeUtils.escapeJava(String.valueOf(value)) + "\"";
}

@Override
public String intercept(ActionInvocation invocation) throws Exception {

ActionContext invocationContext = invocation.getInvocationContext();
Map<String, Object> conversionErrors = invocationContext.getConversionErrors();
ValueStack stack = invocationContext.getValueStack();

HashMap<Object, Object> fakie = null;

for (Map.Entry<String, Object> entry : conversionErrors.entrySet()) {
String propertyName = entry.getKey();
Object value = entry.getValue();

if (shouldAddError(propertyName, value)) {
String message = XWorkConverter.getConversionErrorMessage(propertyName, stack);

Object action = invocation.getAction();
if (action instanceof ValidationAware) {
ValidationAware va = (ValidationAware) action;
va.addFieldError(propertyName, message);
}

if (fakie == null) {
fakie = new HashMap<Object, Object>();
}

fakie.put(propertyName, getOverrideExpr(invocation, value));
}
}

if (fakie != null) {
// if there were some errors, put the original (fake) values in
// place right before the result
stack.getContext().put(ORIGINAL_PROPERTY_OVERRIDE, fakie);
invocation.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation invocation, String resultCode) {
Map<Object, Object> fakie = (Map<Object, Object>) invocation.getInvocationContext()
.get(ORIGINAL_PROPERTY_OVERRIDE);

if (fakie != null) {
invocation.getStack().setExprOverrides(fakie);
}
}
});
}

Object action = invocation.getAction();
if (action instanceof ValidationAware) {
ValidationAware validationAware = (ValidationAware) action;
if (validationAware.hasFieldErrors() || validationAware.hasActionErrors()) {
return "input";
}
}

return invocation.invoke();
}

protected boolean shouldAddError(String propertyName, Object value) {
return true;
}
}


View Code
  主要修改intercept方法,在返回值之前添加代码:

Object action = invocation.getAction();
         if (action instanceof ValidationAware) {
             ValidationAware validationAware = (ValidationAware) action;
             if (validationAware.hasFieldErrors() || validationAware.hasActionErrors()) {
                 return "input";
             }
         }

return invocation.invoke();


  基于短路验证和上边代码修改,则如果输入字符串,提交表单后,默认是会出现一个错误:字段转换失败。


[b]非字段验证:[/b]

示例:验证密码和确认密码是否一直。

index.jsp

<s:actionerror />

<s:form action="myValidation" method="post">
<s:password name="password" label="Password"></s:password>
<s:password name="password1" label="Password1"></s:password>

<s:submit label="Submit"></s:submit>
</s:form>


MyValidationAction.java

package com.dx.struts2.myvalidations;

import com.opensymphony.xwork2.ActionSupport;

public class MyValidationAction extends ActionSupport {
private static final long serialVersionUID = 1L;

private String password;
private String password1;

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getPassword1() {
return password1;
}

public void setPassword1(String password1) {
this.password1 = password1;
}

@Override
public String execute() throws Exception {

System.out.println("execute...");

return SUCCESS;
}
}


MyValidationAction-myValidation-validation.xml

<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">

<validators>

<validator type="expression">
<param name="expression"><![CDATA[password==password1]]></param>
<message>Password is not equals Password1</message>
</validator>
</validators>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐