天天看点

SpringMVC接口----表单参数验证

接口开发,至少面临以下问题: 接口文档、数据验证、 接口安全等等。

关于程序员讨厌写文档的原因,你懂的,程序员的大量精力都投入在接口的开发上,没有精力来撰写相关文档,可以工作的软件胜过面面俱到的文档!

关于数据验证,接触过一些项目,整个系统基本的数据校验都没有,一眼就能找出破绽使项目运行异常。

关于接口安全,完整的接口不仅要保证数据的可靠性,同时也要确保接口的安全性,哪些用户可以访问,哪些人不允许访问。

接口文档  swagger ui 解决你的烦恼,如何集成Swagger到项目中,之前文章已有详细说明 http://blog.csdn.net/dhweicheng/article/details/78160302

/**
 * 
 * @ClassName SwaggerConfig
 * @Description api 管理
 * @author Cheng.Wei
 * @date 2017年11月19日 下午9:29:25
 *
 */
@EnableSwagger2
public class SwaggerConfig {

	@Bean
	public Docket platformApi() {
		return new Docket(DocumentationType.SWAGGER_2).groupName("DEMO").select().apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).build().apiInfo(apiInfo())
				.forCodeGeneration(true);
	}

	private static ApiInfo apiInfo() {
		return new ApiInfoBuilder().title("测试接口").description("api文档")
				.contact(new Contact("Cheng.Wei", "tencent://message/?uin=xxxxx", "[email protected]")).license("Apache License Version 2.0")
				.licenseUrl("https://github.com/abelsilva/SwaggerWCF/blob/master/LICENSE").version("1.0").build();
	}

}
           

参数验证  Bean Validation 集成:(Spring 4.3.5)添加hibernate validator 5依赖

<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.1.0.Final</version>
		</dependency>
           

Spring MVC 配置

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
           

简单参数校验

接口分组

/**
 * @ClassName RoleGroup
 * @Description 角色验证分组  新增、更新
 * @author Cheng.Wei
 * @date 2017年11月19日 下午10:00:42
 * 
 */
public interface  RoleGroup {
	/**新增*/
	public static interface Add{}
	/**更新*/
	public static interface Update{}
	/***更具需要自定义更多*****/
}
           

对象验证规则( get 、set 省略 )

/**
 * @ClassName Role
 * @Description 角色
 * @ApiModel 、 @ApiModelProperty 用来标记属性对应的名称,方便通过Swagger 查看接口文档参数
 * @author Cheng.Wei
 * @date 2017年11月19日 下午8:08:52
 * 
 */
@ApiModel("角色")
public class Role {
	@Null(groups = RoleGroup.Add.class)
	@NotNull(groups = RoleGroup.Update.class)
	@Length(groups = RoleGroup.Update.class, min = 1, max = 10)
	private String id;
	@NotNull(groups = { RoleGroup.Add.class, RoleGroup.Update.class })
	@Length(groups = { RoleGroup.Add.class, RoleGroup.Update.class }, min = 1, max = 10)
	private String name;
}
           

控制器

/**
 * @ClassName RoleController
 * @Description 角色
 * @author Cheng.Wei
 * @date 2017年11月19日 下午10:03:30
 * @see com.jsr.bean.group.RoleGroup 验证分组
 * @see com.jsr.bean.Role 对象参数及分组情况
 */
@Controller
@RequestMapping(value = "/role")
public class RoleController extends BaseController{

	@RequestMapping(method = RequestMethod.POST)
	public ModelAndView add(@Validated(RoleGroup.Add.class) Role role, BindingResult bindingResult) {
		logger.info(">>>>执行新增角色操作:{}", role);
		/**
		 * TODO
		 */
		return getResultMav();
	}
	@RequestMapping(method = RequestMethod.PUT)
	public ModelAndView update(@Validated(RoleGroup.Update.class) Role role, BindingResult bindingResult) {
		logger.info(">>>>执行更新角色操作:{}", role);
		/**
		 * TODO
		 */
		return getResultMav();
	}
}
           

切面

/**
 * @ClassName FormValidationAspect
 * @Description 表单参数验证
 * @author Cheng.Wei
 * @date 2017年11月19日 下午10:45:20
 * 
 */
@Aspect
@Component
public class FormValidationAspect {
	protected static final Logger logger = LogManager.getLogger(FormValidationAspect.class);

	@Around(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping)", argNames = "joinPoint")
	public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
		BindingResult result = null;
		Object[] args = joinPoint.getArgs();
		if (args != null && args.length != 0) {
			for (Object object : args) {
				if (object instanceof BindingResult) {
					result = (BindingResult) object;
					break;
				}
			}
		}
		if (result != null && result.hasErrors()) {
			FieldError fieldError = result.getFieldError();
			logger.info("参数验证失败.控制器:{}, 方法:{}, 属性:{}, 错误编码:{} >>> 消息:{}", joinPoint.getTarget().getClass().getSimpleName(), joinPoint.getSignature().getName(), fieldError.getField(), fieldError.getCode(),fieldError.getDefaultMessage());
			ModelAndView mav = new ModelAndView("jsonView");
			mav.addObject("code", -1);
			mav.addObject("detail", fieldError.getField() + ":"+ fieldError.getDefaultMessage());
			mav.addObject("msg", "数据提交异常");
			return mav;
		}
		return joinPoint.proceed();
	}
}
           

执行效果:

SpringMVC接口----表单参数验证

嵌套验证:

接口分组

/**
 * @ClassName UserGroup
 * @Description 用户分组验证
 * @author Cheng.Wei
 * @date 2017年11月19日 下午10:30:13
 * 
 */
public interface  UserGroup {
	/**新增*/
	public static interface Add{}
	/**更新*/
	public static interface Update{}
	/***更具需要自定义更多*****/
}
           

对象验证规则( get 、set 省略 ;用户 --书  一对多关系)

Book

/**
 * @ClassName Book
 * @Description 书本
 * @author Cheng.Wei
 * @date 2017年11月19日 下午10:26:37
 * 
 */
public class Book {
	@NotNull(groups = { UserGroup.Add.class, UserGroup.Update.class })
	@ApiModelProperty(name = "唯一标识")
	private Integer id;
	
	@NotBlank(groups = { UserGroup.Add.class, UserGroup.Update.class })
	@Length(min = 1, max = 10, groups = { UserGroup.Add.class, UserGroup.Update.class })
	@ApiModelProperty(name = "名称")
	private String name;
}
           

User

/**
 * @ClassName User
 * @Description 人员
 * @ApiModel 、 @ApiModelProperty 用来标记属性对应的名称,方便通过Swagger 查看接口文档参数
 * @author Cheng.Wei
 * @date 2017年11月19日 下午8:07:00
 * 
 */
@ApiModel("人员")
public class User {
	@Null(groups = UserGroup.Add.class)
	@NotBlank(groups = UserGroup.Update.class)
	@ApiModelProperty(name = "标识")
	private String id;
	
	@NotBlank(groups = { UserGroup.Add.class, UserGroup.Update.class })
	@Length(min = 2, max = 10, groups = { UserGroup.Add.class, UserGroup.Update.class })
	@ApiModelProperty(name = "姓名")
	private String name;
	
	@Valid
	private List<Book> book;
}
           

控制器

/**
 * 
 * @ClassName UserController
 * @Description 用户
 * @author Cheng.Wei
 * @date 2017年11月19日 下午8:05:39
 * @see com.jsr.bean.group.UserGroup 接口验证分组
 * @see com.jsr.bean.User 对象信息及分组
 */
@Controller
public class UserController extends BaseController{
	@RequestMapping(value = "/user", method = RequestMethod.POST)
	public ModelAndView add(@Validated(UserGroup.Add.class) @RequestBody User user, BindingResult bindingResult) {
		logger.info(">>>>执行新增操作");
		/**
		 *
		 * TODO
		 */
		return getResultMav();
	}
	
	@RequestMapping(value = "/user", method = RequestMethod.PUT)
	public ModelAndView update(@Validated(UserGroup.Update.class) @RequestBody User user, BindingResult bindingResult) {
		logger.info(">>>>执行更新操作");
		/**
		 * TODO
		 */
		return getResultMav();
	}
}
           

执行效果

SpringMVC接口----表单参数验证

至此,表单参数验证完成,权限验证方面spring security、 shiro 会在今后补充。

继续阅读