例如,有一个动作类如下。
@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@InterceptorRefs({@InterceptorRef(value="defaultStack", params={"validation.excludeMethods", "load"})})
public final class TestAction extends ActionSupport implements Serializable, ValidationAware, ModelDriven<Transporter>
{
@Autowired
private final transient TransporterService transporterService=null;
private static final long serialVersionUID = 1L;
private Boolean deleteOneRow=false; //Getter and setter.
private Transporter entity=new Transporter(); //Getter and setter.
private List<Transporter>transporters=new ArrayList<Transporter>();
private String message; //Getter and setter.
private List<Long>chk; //Getter and setter.
@Action(value = "Transporter", results = {@Result(name=ActionSupport.SUCCESS, location="Transporter.jsp"), @Result(name = ActionSupport.INPUT, location = "Transporter.jsp")})
public String load() throws Exception
{
return ActionSupport.SUCCESS;
}
@Validations(
requiredStrings={
@RequiredStringValidator(fieldName="transporterName", type= ValidatorType.FIELD, key = "transporter.name.required"),
@RequiredStringValidator(fieldName="transporterWebsite", type= ValidatorType.FIELD, key = "transporter.website.required")},
stringLengthFields={
@StringLengthFieldValidator(fieldName="transporterName", type= ValidatorType.FIELD, minLength="2", maxLength="45", key="transporter.name.length", messageParams={"2", "45"}),
@StringLengthFieldValidator(fieldName="transporterWebsite", type= ValidatorType.FIELD, minLength="10", maxLength="1000", key="transporter.website.length", messageParams={"10", "1000"})})
@Action(value = "addTransporter",
results = {@Result(name=ActionSupport.SUCCESS, type="redirectAction", location="Transporter.jsp", params={"namespace", "/admin_side", "actionName", "Transporter", "message", "${message}"}),
@Result(name = ActionSupport.INPUT, location = "Transporter.jsp")},
interceptorRefs={@InterceptorRef(value="defaultStack", params={"params.acceptParamNames", "transporterName, transporterWebsite", "validation.validateAnnotatedMethodOnly", "true"})})
public String insert()
{
if(entity.getTransporterId()==null)
{
transporterService.insert(entity.getTransporterName(), entity.getTransporterWebsite());
setMessage(getText("insert.success"));
}
else
{
setMessage(transporterService.update(entity)?getText("update.success", new String[]{String.valueOf(entity.getTransporterId())}) :getText("update.failed", new String[]{String.valueOf(entity.getTransporterId())}));
}
return ActionSupport.SUCCESS;
}
@Validations(requiredFields={@RequiredFieldValidator(fieldName="transporterId", type= ValidatorType.FIELD, key = "delete.id.missing")})
@Action(value = "editTransporter",
results = {
@Result(name=ActionSupport.SUCCESS, location="Transporter.jsp"),
@Result(name = ActionSupport.INPUT, location = "Transporter.jsp")},
interceptorRefs={
@InterceptorRef(value="defaultStack", params={"params.acceptParamNames", "transporterId, transporterName, transporterWebsite", "validation.validateAnnotatedMethodOnly", "true"}),
@InterceptorRef(value="conversionError")})
public String edit()
{
return ActionSupport.SUCCESS;
}
@Action(value = "deleteTransporter",
results = {
@Result(name=ActionSupport.SUCCESS, type="redirectAction", location="Transporter.action", params={"message", "${message}"}),
@Result(name = ActionSupport.INPUT, location = "Transporter.jsp")},
interceptorRefs={
@InterceptorRef(value="defaultStack", params={"params.acceptParamNames", "transporterId, deleteOneRow", "validation.validateAnnotatedMethodOnly", "true"}),
@InterceptorRef(value="conversionError")})
public String deleteTransporter()
{
if(transporterService.delete(entity.getTransporterId()))
{
//Pagination has not not yet been implemented. Hence, it is static.
transporters=transporterService.getList(0, 20);
setMessage(getText("delete.success", new String[]{String.valueOf(entity.getTransporterId())}));
}
else
{
setMessage(getText("delete.failed", new String[]{String.valueOf(entity.getTransporterId())}));
}
return ActionSupport.SUCCESS;
}
@Action(value = "deleteTransporters",
results = {
@Result(name=ActionSupport.SUCCESS, type="redirectAction", location="Transporter.jsp", params={"namespace", "/admin_side", "actionName", "Transporter", "message", "${message}"}),
@Result(name = ActionSupport.INPUT, location = "Transporter.jsp")},
interceptorRefs={
@InterceptorRef(value="defaultStack", params={"params.acceptParamNames", "chk", "validation.validateAnnotatedMethodOnly", "true"}),
@InterceptorRef(value="conversionError")})
public String deleteTransporters()
{
setMessage(transporterService.delete(chk)?getText("delete.multiple.success", new String[]{String.valueOf(chk.size())}) :getText("delete.multiple.failed"));
return ActionSupport.SUCCESS;
}
@Override
public Transporter getModel() {
return entity;
}
public List<Transporter> getTransporters()
{
if(CollectionUtils.isEmpty(transporters))
{
//Pagination has not not yet been implemented. Hence, it is static.
transporters=transporterService.getList(0, 20);
}
return transporters;
}
public void setTransporters(List<Transporter> transporters) {
this.transporters = transporters;
}
@Override
public void validate(){}
}
JSP页面:
<s:form namespace="/admin_side" action="Transporter" id="dataForm" name="dataForm" cssClass="search_form general_form">
<s:if test="hasFieldErrors()">
<s:fielderror fieldName="transporterId"/>
<s:fielderror fieldName="chk"/>
</s:if>
<s:property value="message"/>
<s:hidden id="transporterId" name="transporterId"/>
<s:hidden id="deleteOneRow" name="deleteOneRow"/>
<s:textfield id="transporterName" name="transporterName"/><s:fielderror fieldName="transporterName"/>
<s:textfield id="transporterWebsite" name="transporterWebsite"/><s:fielderror fieldName="transporterWebsite"/>
<s:submit id="btnSubmit" name="btnSubmit" value="Submit" action="addTransporter"/>
<table cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr class="even">
<th style="width: 96px;">Check</th>
<th style="width: 96px;">Id</th>
<th style="width: 96px;">Transporter</th>
<th style="width: 96px;">Website</th>
<th style="width: 96px;">Actions</th>
</tr>
<s:iterator value="transporters" status="loopStatus">
<tr class="<s:if test="#loopStatus.odd == true ">first</s:if> <s:else>second</s:else>">
<td><s:checkbox name="chk" fieldValue="%{transporterId}" value="false"/></td>
<td><s:property value="transporterId" /></td>
<td><s:property value="transporterName" /></td>
<td>
<a href="<s:property value="transporterWebsite" />">Visit</a>
</td>
<td>
<div class='actions'>
<ul>
<li>
<s:url id="editURL" action="editTransporter" escapeAmp="false">
<s:param name="transporterId" value="%{transporterId}"/>
<s:param name="transporterName" value="%{transporterName}"/>
<s:param name="transporterWebsite" value="%{transporterWebsite}"/>
</s:url>
<s:a href="%{editURL}" cssClass="action2"/>
</li>
<li>
<s:url id="deleteURL" action="deleteTransporter" escapeAmp="false">
<s:param name="transporterId" value="%{transporterId}"/>
<s:param name="deleteOneRow" value="%{deleteOneRow}"/>
</s:url>
<s:a href="%{deleteURL}" onclick="return deleteOne(%{transporterId});" cssClass="action4"/>
</li>
</ul>
</div>
</td>
</tr>
</s:iterator>
</tbody>
</table>
<s:submit name="btnDelete" id="btnDelete" action="deleteTransporters" onclick="return getCheckedRows();" />
insert()
方法接受两个参数transporterName
和transporterWebsite
,而edit()
方法只接受一个参数transporterId
,该参数作为查询字符串提供,点击链接时。
insert()
方法由<s:submit>
的操作映射,而edit()
方法由<s:url>
的操作映射,其id
被赋予href
的{{1}}属性。
单击编辑链接<s:a>
时,文本字段<s:a>
和transporterName
都会被不必要地验证,编辑时不得发生这种情况,即应跳过对这些文本字段的验证/单击编辑链接时禁用。
只应验证transporterWebsite
方法接受的transporterId
。单击编辑链接时,不应验证其他字段。
在这种情况下,注释edit()
不起作用。
怎么做?
答案 0 :(得分:1)
这是因为我在我定义的类级别验证拦截器中缺少validateAnnotatedMethodOnly
。
当我将类定义修改为类似以下内容时,它起作用了。
@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@InterceptorRefs({@InterceptorRef(value="defaultStack", params={"validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
public final class TestAction extends ActionSupport implements Serializable, ValidationAware, ModelDriven<Transporter>
{
//...
}
我在方法级别包含validation.validateAnnotatedMethodOnly
但忘记将其包含在班级中。
使用load()
仅在动作类中注释@SkipValidation
方法也是合适的,并完全删除类级@InterceptorRefs
注释。
当使用多个方法来映射相同的不同操作时 class,其中一个用
@Validations
注释,那些 除非它们是,否则将针对所有操作触发验证器 已设置注释@SkipValidation
或validateAnnotatedMethodOnly
在validation
拦截器中为true,如:<interceptor-ref name="validation"> <param name="validateAnnotatedMethodOnly">true</param> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref>