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

来源:互联网 发布:java 日期格式化 星期 编辑:程序博客网 时间:2024/06/05 19:55

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

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

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

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

接口文档  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 * */@EnableSwagger2public class SwaggerConfig {@Beanpublic 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", "xxxxxxx@163.com")).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@Componentpublic 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();}}

执行效果:




嵌套验证:

接口分组

/** * @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;@Validprivate 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 对象信息及分组 */@Controllerpublic 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();}}

执行效果




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