Play框架提供十分便捷的校验注解机制,结合@before拦截器标签可以实现便利的拦截机制,不需要逐个类去编写校验代码了,这里结合上一章的功能测试实现一个增加的校验。 首先要用到两个models类 App/models/Heart.java:
package models; import java.util.Date; import java.util.List; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; import org.codehaus.jackson.map.annotate.JsonFilter; import play.data.validation.Email; import play.data.validation.Match; import play.data.validation.MaxSize; import play.data.validation.Required; import play.data.validation.Valid; @Entity @Table(name = "heart")public class Heart extends BaseModel { @Id public Long id; @Required @MaxSize(value = 12) public String code; public String nick; @MaxSize(value = 12) public String passwd; @Email public String qqmail; @Match(value = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}") public String ip; @Valid @Transient public List box; public Long intime; public Long ontime; }App/models/Guess.java:package models; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import play.data.validation.MaxSize; import play.data.validation.Range; import play.db.jpa.GenericModel; @Entity @Table(name = "guess") public class Guess extends BaseModel { @Id public Long id; @Range(max = 5, min = 1) public Integer type; @MaxSize(value = 256) public String idea; }然后是controller层面,需要实现一个基类,抽象出一些共用的方法: App/controllers/Application.java:package controllers; import play.*; import play.mvc.*; import util.JsonUtil; import java.util.*; public class Application extends Controller { @Before public static void validateInterceptor(){ if(validation.hasErrors()){ response.status = 550; renderText(JsonUtil.object2JsonString(validation.errors())); } } }具体的controller类: App/controllers/Hearts.java:package controllers; import javax.persistence.Query; import play.data.validation.Min; import play.data.validation.Valid; import play.db.jpa.JPA; import play.db.jpa.JPABase; import util.JsonUtil; import models.Heart; public class Hearts extends Application{ public static void add(@Valid Heart heart){ boolean result = heart.create(); renderText(JsonUtil.object2JsonString(result)); } public static void load(@Min(value = 1)Long id) { Heart heart = Heart.findById(id); renderText(JsonUtil.object2JsonString(heart)); } }需要映射的url: Conf/routes:POST /heart Hearts.add测试需要用到的两个yaml文件: Test/yml/db/heart.yml:Heart(h1): id: 1001 code: pony nick: 小马哥 passwd: pony123 qqmail: [email protected] ip: 192.168.0.123 box[0].id: 1 box[0].type: 1 box[0].idea: 马哥有点肥 box[1].id: 2 box[1].type: 2 box[1].idea: 有钱人 box[2].id: 3 box[2].type: 3 box[2].idea: 汝甚吊 Heart(h2): id: 1002 code: robin nick: 小李子 passwd: robin100 qqmail: [email protected] ip: 192.168.0.122 box[0].id: 1 box[0].type: 1 box[0].idea: 小李子不厚道 box[1].id: 2 box[1].type: 4 box[1].idea: 大气桶 box[2].id: 3 box[2].type: 3 box[2].idea: 汝甚吊 Heart(h2): id: 1002 code: robin nick: 小李子 passwd: robin100 qqmail: [email protected] ip: 192.168.0.122 box[0].id: 4 box[0].type: 1 box[0].idea: 小李子不厚道 box[1].id: 5 box[1].type: 4 box[1].idea: 大气桶 box[2].id: 6 box[2].type: 3 box[2].idea: 汝甚吊Test/yml/request/heart.yml:add_normal: heart.id: '1003' heart.code: jack heart.nick: 老马 heart.passwd: jack2 heart.qqmail: [email protected] heart.ip: 192.168.1.122 heart.box[0].id: '7' heart.box[0].type: '1' heart.box[0].idea: 老马太瘦了 heart.box[1].id: '8' heart.box[1].type: '5' heart.box[1].idea: 矮矬富 heart.box[2].type: '3' heart.box[2].idea: 汝甚吊 add_errors: heart.id: '1003' heart.code: jack12345678900 heart.nick: 老马 heart.passwd: jack2 heart.qqmail: 200qq.com heart.ip: 192.168.1.122 heart.box[0].id: '7' heart.box[0].type: '21' heart.box[0].idea: 老马太瘦了 heart.box[1].id: '8' heart.box[1].type: '5' heart.box[1].idea: 矮矬富 heart.box[2].type: '3' heart.box[2].idea: 汝甚吊测试类: Test/function/HeartsTest.java:package function; import java.util.Map; import org.junit.Before; import org.junit.Test; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import models.Heart; import play.db.jpa.JPA; import play.db.jpa.JPABase; import play.mvc.Http.Response; import play.test.Fixtures; import play.test.FunctionalTest; public class HeartsTest extends BasisTest{ Map rootmap =null; @Before public void init(){ rootmap=(Map)Fixtures.loadYamlAsMap("yml/request/hearts.yml"); if(!JPA.em().getTransaction().isActive()){ JPA.em().getTransaction().begin(); } Fixtures.delete(Heart.class); Fixtures.loadModels("yml/db/heart.yml"); JPA.em().getTransaction().commit(); } @Test public void testAddNormal(){ int beforeRequestSize = Heart.findAll().size(); Map map = rootmap.get("add_normal"); Response response = POST("/heart", map); assertIsOk(response); int afterRequestSize = Heart.findAll().size(); assertEquals(beforeRequestSize, afterRequestSize - 1); Heart heart = Heart.findById(Long.parseLong(map.get("heart.id"))); assertNotNull(heart); String result = response.out.toString(); assertEquals("true", result); } @Test public void testAddParamErrors(){ int beforeRequestSize = Heart.findAll().size(); Map map = rootmap.get("add_errors"); Response response = POST("/heart", map); assertStatus(550, response);; int afterRequestSize = Heart.findAll().size(); assertEquals(beforeRequestSize, afterRequestSize); Heart heart = Heart.findById(Long.parseLong(map.get("heart.id"))); assertNull(heart); String result = response.out.toString(); assertFalse("".equals(result)); assertFalse("null".equals(result)); JSONArray parseArray = JSON.parseArray(result); assertEquals(6, parseArray.size()); } }错误时返回的信息:[{"key":"heart.box[0].type","message":"validation.range","variables":["1.0","5.0"]},{"key":"heart.box[0]","message":"validation.object","variables":[]},{"key":"heart.code","message":"validation.maxSize","variables":["12"]},{"key":"heart.qqmail","message":"validation.email","variables":[]},{"key":"heart.box","message":"validation.object","variables":[]},{"key":"heart","message":"validation.object","variables":[]}]当然play给出的错误信息都是英语的,如果想要在前台展现正文,可以借助play国际化的机制,这个在下一篇中会提到。