2013-03-16 145 views
2

我的問題是,我有一個具有HTML選擇元素與一些選擇的選項值&我想用驗證這些價值的一種形式:Spring MVC的表單驗證

org.hibernate.validator.constraints 
or 
javax.validation.constraints 

註解。這是我的選擇元件:

<select name="status" id="tbSelect"> 
    <option value="ACTIVE">ACTIVE</option> 
    <option value="LISTEN">LISTEN</option> 
    <option value="DOWN">DOWN</option> 
</select> 

如何我可以通過使用註釋驗證我在上面提到例如驗證的選項(DOWN,LISTEN,ACTIVE)選擇元素內的值?

我的形式是這樣的:

<form:form action="../agents/add" method="POST" commandName="myAgent"> 
    <form:select id="tbSelect" path="state"> 
      <form:option value="ACTIVE" path="state">ACTIVE</form:option> 
      <form:option value="LISTEN" path="state">LISTEN</form:option> 
      <form:option value="DOWN" path="state">DOWN</form:option> 
    </form:select> 

我已經定義我的控制器的方法是這樣的:

@RequestMapping(value = "agents/add", method = RequestMethod.POST) 
    public String addAgentSubmit(@ModelAttribute("myAgent") @Valid final AgentValidator agent, BindingResult result, RedirectAttributes redirect) { 
     if (result.hasErrors()) { 
     return "admin/agent/add"; 
     } 
     ... 
    } 

和我還限定的ModelAttribute這樣的:

@ModelAttribute("myAgent") 
public AgentValidator getLoginForm() { 
    return new AgentValidator(); 
} 

這裏是我的AgentValidator類還:

public class AgentValidator { 
    @NotEmpty(message = "your state can not be empty !") 
    private String state; 
+0

向我們展示你的命令對象。 – Ralph 2013-03-16 13:58:48

+0

對不起,我沒有提供足夠的信息,我改變了問題與更多的信息,請現在檢查出來! – Mehdi 2013-03-17 07:14:03

回答

2

由於您state現場看起來更像是一個枚舉,首先我會建議改變state場進枚舉,讓Spring MVC到綁定字段,只使用@NotNull註釋:

public class AgentValidator { 
    @NotNull(message = "your state can not be empty !") 
    private AgenState state; 

AgentState是:

public enum AgentState { 
    DOWN,LISTEN,ACTIVE 
} 

但是如果因爲某些原因你不能改變你的模型,那麼你可以使用custom constraints

特殊需要創建您的註釋AgentStateConstraint

@Target({ METHOD, FIELD, ANNOTATION_TYPE }) 
@Retention(RUNTIME) 
@Constraint(validatedBy = AgentStateConstraintValidator.class) 
@Documented 
public @interface AgentStateConstraint { 

    String message() default "Some message"; 

    Class<?>[] groups() default {}; 

    Class<? extends Payload>[] payload() default {}; 

} 

然後,你需要創建驗證AgentStateConstraintValidator

public class AgentStateConstraintValidator implements ConstraintValidator<AgentStateConstraint, String> { 

    //Accepted values 
    private static final Set<String> ACCEPTED_VALUES = new HashSet<String>(
      Arrays.asList(
        "DOWN", 
        "LISTEN", 
        "ACTIVE" 
      ) 
    ); 

    public void initialize(AgentStateConstraint constraintAnnotation) { 
    } 

    public boolean isValid(String object, ConstraintValidatorContext constraintContext) { 
     return ACCEPTED_VALUES.contains(object); 
    } 

} 
+0

...很感謝! – Mehdi 2013-03-17 10:41:35

+0

只是一個問題,當我注入一個錯誤的值驗證工程,但與默認的錯誤消息:無法將屬性值類型java.lang.String轉換爲所需的類型tm.sys.validator.AgentState屬性狀態;嵌套異常是org.springframework.core.convert.ConversionFailedException:未能從類型java.lang.String轉換爲類型@ javax.validation.constraints.NotNull tm.sys.validator.AgentState的值爲ACTIVE3;嵌套異常是java.lang.IllegalArgumentException:沒有枚舉常量tm.sys.validator.AgentState.ACTIVE3 如何2更改def消息並把我自己的消息? – Mehdi 2013-03-17 10:57:39

+1

爲了處理這個,你需要爲'org.springframework.core.convert.ConversionFailedException'定義'@ ExceptionHandler'或者用'@ InitBinder'指定你自己的轉換策略。但是由於用戶通過下拉菜單輸入'status',我相信這些事情根本不應該發生。 – n1ckolas 2013-03-17 11:05:56