Play 1.x框架学习之二:统一校验机制 (common way to validate in play framework)

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国际化的机制,这个在下一篇中会提到。

你可能感兴趣的:(play,1.x)