Dubbox 基本特性之参数验证

Dubbo作为史上功能最全的RPC框架并不是浪得虚名,在能保证性能的基础上,有这么多的特性,的确是很强,我们先来列举一下dubbo的特性:


本章将会抽选出一些比较常用的一些特性,给出具体的代码实现,方便大家的理解。例如参数验证,结果缓存等给出具体的栗子,当然dubbox对dubbo进行了增强了,我们也会给出对restful,序列化等栗子,方便大家一起学习

3.1 Dubbo参数验证

 

我们都知道,在普通接口开发的时候,都会有参数验证,比如某个值不能为空,数字类型的大小必须是在某个区间,某个字段的长度有限制,某个字段比如email必须满足某个正则表达式等等,dubbo支持接口参数的验证,我们不需要写多于的代码就可以完成这些功能。

 

3.1.1 首先增加Maven的依赖(必须依赖)

<dependency>
				<groupId>javax.validation</groupId>
				<artifactId>validation-api</artifactId>
				<version>1.0.0.GA</version>
			</dependency>
			<dependency>
				<groupId>org.hibernate</groupId>
				<artifactId>hibernate-validator</artifactId>
				<version>4.2.0.Final</version>
			</dependency>

3.1.2 定义一个参数的入参ValidationParameter.java和接口ValidationService.java(服务提供者和消费者都需要编写,同路径)

自定义Annotation的Save和Update是配合原生的annotation使用的,比如在email这个字段上,增加了@NotNull的Annotation,后面跟进了group(ValidationService.Save.class),表示这个annotation生效的场景->表示在save的时候,进入是否为空的判断,其他方法不需要进行空校验

package org.bazinga.service;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.bazinga.service.pojo.ValidationParameter;


public interface ValidationService {

	@interface Save {
	}

	void save(ValidationParameter parameter);

	@interface Update {
	}

	void update(ValidationParameter parameter);

	void delete(
			@Min(value=1,message="id must bigger than 1") long id,
			@NotNull @Size(min = 2, max = 16) @Pattern(regexp = "^[a-zA-Z]+$") String operator);

}

ValidationParameter.java

package org.bazinga.service.pojo;

import java.io.Serializable;
import java.util.Date;

import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.bazinga.service.ValidationService;

/**
 * 验证demo的pojo
 * @author lyncc
 *
 */
public class ValidationParameter implements Serializable {

	private static final long serialVersionUID = 1119411448459221069L;
	
	@NotNull // 不允许为空
    @Size(min = 2, max = 20) // 长度或大小范围
    private String name;

    @NotNull(groups = ValidationService.Save.class) // 保存时不允许为空,更新时允许为空 ,表示不更新该字段
    @Pattern(regexp = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$")
    private String email;

    @Min(18) // 最小值
    @Max(100) // 最大值
    private int age;

    @Past // 必须为一个过去的时间
    private Date loginDate;

    @Future // 必须为一个未来的时间
    private Date expiryDate;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Date getLoginDate() {
		return loginDate;
	}

	public void setLoginDate(Date loginDate) {
		this.loginDate = loginDate;
	}

	public Date getExpiryDate() {
		return expiryDate;
	}

	public void setExpiryDate(Date expiryDate) {
		this.expiryDate = expiryDate;
	}

	@Override
	public String toString() {
		return "ValidationParameter [name=" + name + ", email=" + email
				+ ", age=" + age + ", loginDate=" + loginDate + ", expiryDate="
				+ expiryDate + "]";
	}


}

服务提供者该服务接口的具体实现:

package org.bazinga.service.impl;

import org.bazinga.service.ValidationService;
import org.bazinga.service.pojo.ValidationParameter;

/**
 * 
 * @author lyncc
 *
 */
public class ValidationServiceImpl implements ValidationService {

	public void save(ValidationParameter parameter) {
		System.out.println(parameter);
		System.out.println("save successfully");
	}

	public void update(ValidationParameter parameter) {
		System.out.println(parameter);
		System.out.println("update successfully");
	}

	public void delete(long id, String operator) {
		System.out.println(id+""+operator);
		System.out.println("delete successfully");
	}

}

3.1.3 服务消费者和提供者的spring配置文件

spring-dubbo-provider-validation.xml,我们是进行服务提供端进行验证,所以在注意配置validation=”true”,这样才会进行参数验证

<?xml version="1.1" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans.xsd  
       http://code.alibabatech.com/schema/dubbo  
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
       
    <dubbo:application owner="lyncc" name="bazinga-app" />
    <!--zookeeper注册中心 -->
    <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"/> 
    
    <dubbo:protocol name ="dubbo" port="20880" />
    <!-- 发布这个服务 服务端验证 -->
    <dubbo:service  protocol="dubbo" interface ="org.bazinga.service.ValidationService" ref="validationService" validation="true"/>       
    <!-- 和本地bean一样实现服务 -->
    <bean id="validationService" class="org.bazinga.service.impl.ValidationServiceImpl" />
    
</beans>

spring-dubbo-consumer-validation.xml的配置方式跟上篇demo的消费端的配置是一模一样的,因为我们验证模块是在提供者端进行的,所以消费端没有多余的配置

<?xml version="1.1" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans.xsd  
       http://code.alibabatech.com/schema/dubbo  
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
       
    <dubbo:application owner="lyncc" name="bazinga-consumer" />
    <!--zookeeper注册中心 -->
    <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"/> 
    
    <dubbo:reference id="validationService" interface="org.bazinga.service.ValidationService"/> 
    
</beans>

3.1.4 编写测试代码测试:

服务提供者的启动类

package org.bazinga.service.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 
 * dubbo 参数验证功能的提供者端测试类
 * @author lyncc
 *
 */
public class DubboxProviderValidationDemoService {
	
	public static void main(String[] args) throws InterruptedException {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				"spring-dubbo-provider-validation.xml");
		context.start();
		Thread.sleep(2000000l);
	}

}

测试1:服务消费者保存的时候,正确的入参的测试类DubboConsumerValidationService_1.java

package org.bazinga.service.test;

import java.util.Date;

import org.bazinga.service.ValidationService;
import org.bazinga.service.pojo.ValidationParameter;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/**
 * 保存的时候,所有参数都会验证
 * @author lyncc
 *
 */
public class DubboConsumerValidationService_1 {

	public static void main(String[] args) throws InterruptedException {
		
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				"spring-dubbo-consumer-validation.xml");
		context.start();
		ValidationService validationService = (ValidationService) context
				.getBean("validationService");

		ValidationParameter parameter = new ValidationParameter();
		parameter.setName("lyncc");  //not null
		parameter.setEmail("lyncc@163.com"); //email格式正确
		parameter.setAge(50);  //[18,100]
		parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000)); //时间必须是过去的时间
		parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));//时间必须是未来的时间
		validationService.save(parameter); //save
		System.out.println("Validation Save OK");
		
		Thread.sleep(2000000l);
		
	}

}

测试结果:

提供者控制台输出:



消费者控制台输出:



没有问题,参数验证通过,可以调用

 

 

测试二:调用更新的时候,根据配置email字段可以为空,测试类:DubboConsumerValidationService_2.java

package org.bazinga.service.test;

import java.util.Date;

import org.bazinga.service.ValidationService;
import org.bazinga.service.pojo.ValidationParameter;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/**
 * 更新的时候,email可以为空
 * @author lyncc
 *
 */
public class DubboConsumerValidationService_2 {

	public static void main(String[] args) throws InterruptedException {
		
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				"spring-dubbo-consumer-validation.xml");
		context.start();
		ValidationService validationService = (ValidationService) context
				.getBean("validationService");

		ValidationParameter parameter = new ValidationParameter();
		parameter.setName("lyncc");  //not null
		parameter.setAge(50);  //[18,100]
		parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000)); //时间必须是过去的时间
		parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));//时间必须是未来的时间
		validationService.update(parameter); //save
		System.out.println("Validation update OK");
		
		Thread.sleep(2000000l);
		
	}

}

测试结果:

提供者控制台输出:



消费者控制台输出:


没有问题,参数验证通过,可以调用更新

 

 

测试三:保存的时候,age参数小于18,参数验证不通过,调用报错,测试类DubboConsumerValidationService_3.java

package org.bazinga.service.test;

import java.util.Date;

import org.bazinga.service.ValidationService;
import org.bazinga.service.pojo.ValidationParameter;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/**
 * 保存的时候,年龄小于18,报错
 * @author lyncc
 *
 */
public class DubboConsumerValidationService_3 {

	public static void main(String[] args) throws InterruptedException {
		
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				"spring-dubbo-consumer-validation.xml");
		context.start();
		ValidationService validationService = (ValidationService) context
				.getBean("validationService");

		ValidationParameter parameter = new ValidationParameter();
		parameter.setName("lyncc");  //not null
		parameter.setEmail("lyncc@163.com"); //email格式正确
		parameter.setAge(17);  //error [18,100]
		parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000)); //时间必须是过去的时间
		parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));//时间必须是未来的时间
		validationService.save(parameter); //save
		System.out.println("Validation Save OK");
		
		Thread.sleep(2000000l);
		
	}

}

测试结果:

提供者控制台输出:

消费者控制台没有输出,验证不通过,服务提供者调用报错

 

 

测试4:远程调用删除操作的时候,id小于规定的1,验证失败报错,测试类DubboConsumerValidationService_4.java

package org.bazinga.service.test;

import org.bazinga.service.ValidationService;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/**
 * 删除的时候,id小于规定的1,调用报错
 * @author lyncc
 *
 */
public class DubboConsumerValidationService_4 {

	public static void main(String[] args) throws InterruptedException {
		
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				"spring-dubbo-consumer-validation.xml");
		context.start();
		ValidationService validationService = (ValidationService) context
				.getBean("validationService");

		validationService.delete(-1, "lyncc");
		
		Thread.sleep(2000000l);
		
		
	}

}

测试结果:

提供者控制台输出:

消费者控制台没有输出,验证不通过,服务提供者调用报错,提示id必须大于1

 

 

 

3.1.5关于validation模块的小结,参数验证,其实与RPC并没有任何直接的联系,不过并不是所有的RPC框架都支持参数验证的,但是如果支持参数验证,可以大大方便我们的编码,dubbo的参数验证也是很简单,只需要在配置文件中加入”validation=true”,这样的说明,然后引入相对应的maven依赖,按照我们平时的使用方式,就能够达到参数验证的功能








  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值