轉載請注明:TheViperhttp://www.49028c.com/TheViper
基于JSR303注解校驗
問題的出現
一個很常見的場景,對于一個model(pojo) User(屬性有id,name,pwd密碼,email),在登陸注冊頁面中,登陸校驗和注冊校驗
1.需要校驗的屬性不同。登陸只需校驗name和pwd就可以了,不像注冊需要校驗全部屬性。
2.校驗同一屬性的目的不同。比如,注冊的時候,需要校驗name屬性是否為空,還有長度是否符合要求;登陸的時候就只用校驗是否為空就可以了。pwd同理。
3.由于校驗的目的不同,相應的返回的信息也不同。
可以看到此時如果只是在model屬性上單純的用注解是無能為力的,好在spring mvc為我們提供了解決方法。
解決
先看下最終效果
下面從頭到尾說下步驟:
1.下載spring framework,添加spring mvc必須的jar
例子里面沒有用到數據庫,所以少了很多jar.
2.添加org.json包,用于生成json格式字符串。當然也可以用其他可以生成json字符串的包。
3.添加hibernate-validator.jar,validation-api.jar,使spring mvc支持JSR303注解式的校驗
4.添加commons-logging.jar,jboss-logging.jar。否則啟動服務器出現錯誤。
5.添加classmate.jar,否則出現java.lang.ClassNotFoundException: com.fasterxml.classmate.Filter
6.在model上添加校驗注解,并為相應注解分組。比如
public class User { private int id; @NotEmpty(message="用戶名不能為空",groups={LoginCheck.class,RegCheck.class}) @Size(min=3,max=12,message="登錄名必須3-12位",groups={RegCheck.class}) private String name; @NotEmpty(message="密碼不能為空",groups={LoginCheck.class,RegCheck.class}) @Size(min=6,max=16,message="密碼必須6-16位",groups={RegCheck.class}) private String pwd; @NotEmpty(message="郵箱不能為空",groups={RegCheck.class}) @Email(message="不符合郵箱格式",groups={RegCheck.class}) private String email;}
可以看到注冊和登陸分別被”分到“了RegCheck.class和LoginCheck.class。這里的分組必須顯式表明校驗注解所屬于的組。
7.新建LoginCheck類,RegCheck類
public interface RegCheck {}public interface LoginCheck { }
8.在業務類中添加@Validated注解,設置value值表示屬于哪個校驗組,當然前提是參數注入@ModelAttribute到model中
需要注意的地方
1.json字符串的生成,返回用org.json的json.toString()就可以了,不用像網上或書上說的用spring mvc的MappingJackson,還要去設置一下才能用。在返回數據類型上用@ResponseBody String就可以了。spring mvc會自動為響應添Content-Type:application/json。不過這樣返回的json字符串會亂碼
@RequestMapping(value = "/login",produces = {"application/json;charset=UTF-8"})就可以了。當然,也可以用網上說的其他方法。
2.關于錯誤信息的設置,可以到jar包里面設置。本屌這里是寫了個封裝,直接取出用的。
public static JSONObject formatError(List<FieldError> errors) throws JSONException{ JSONObject wrap = new JSONObject(); JSONObject jsonObject= new JSONObject(); for(FieldError fieldError:errors) jsonObject.put(fieldError.getField(),fieldError.getDefaultMessage()); wrap.put("errors", jsonObject); return wrap; }
bindingResult.hasErrors():校驗中是否有錯誤。
bindingResult.getFieldErrors():返回List,里面是FieldError,FieldError類getField()返回校驗的屬性名,getDefaultMessage()返回的就是自定義的錯誤信息。
3.關于注冊中的重復密碼(repwd)的校驗,可以用網上說的實現Validator接口。這里是在User類中定義repwd屬性。
注意,由于要用到@AssertTrue,repwd屬性在這里不能有getter方法,而是isRepwd()
private String repwd; @AssertTrue(message="密碼兩次輸入不一致",groups={RegCheck.class}) private boolean isRepwd() { return this.pwd.equals(this.repwd); }
例子下載
還可以參考http://jinnianshilongnian.VEvb.com/blog/1990081,其實spring mvc3就已經支持JSR303 group注解校驗了。
https://kevinpotgieter.Wordpress.com/2012/02/20/jsr303-spring-mvc-selective-validations/
新聞熱點
疑難解答