zoukankan      html  css  js  c++  java
  • spring boot输入数据校验(validation)


    Spring Boot 集成教程


    web项目中,用户的输入总是被假定不安全不正确的,在被处理前需要做校验。本文介绍在spring boot项目中实现数据校验的过程。

    项目内容

    实现一个简单的用户注册接口,演示怎样进行数据校验。

    要求

    • JDK1.8或更新版本
    • Eclipse开发环境

    如没有开发环境,可参考 [spring boot 开发环境搭建(Eclipse)]。

    项目创建

    创建spring boot项目

    打开Eclipse,创建spring boot的spring starter project项目,选择菜单:File > New > Project ...,弹出对话框,选择:Spring Boot > Spring Starter Project,在配置依赖时,勾选web,完成项目创建。

    image

    项目依赖

    pom.xml的内容

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.1.1.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    	<groupId>com.qikegu</groupId>
    	<artifactId>springboot-validation-demo</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>springboot-validation-demo</name>
    	<description>Demo project for Spring Boot</description>
    
    	<properties>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    </project>
    
    

    代码实现

    项目目录结构如下图,添加了几个类,下面将详细介绍。

    image

    创建RegisterRequest

    用户注册时,要求输入手机号、密码、昵称,创建RegisterRequest类来接受前端传过来的数据,同时校验数据,校验都是通过注解的方式实现。

    
    public class RegisterRequest {
    	
    	@SuppressWarnings("unused")
    	private static final org.slf4j.Logger log = LoggerFactory.getLogger(RegisterRequest.class);
    	
    	@NotNull(message="手机号必须填")
    	@Pattern(regexp = "^[1]([3][0-9]{1}|59|58|88|89)[0-9]{8}$", message="账号请输入11位手机号") // 手机号
    	private String mobile;
    	
    	@NotNull(message="昵称必须填")
    	@Size(min=1, max=20, message="昵称1~20个字")
    	private String nickname;
    	
        @NotNull(message="密码必须填")
        @Size(min=6, max=16, message="密码6~16位")
    	private String password;
    
    	public String getMobile() {
    		return mobile;
    	}
    
    	public void setMobile(String mobile) {
    		this.mobile = mobile;
    	}
    
    	public String getNickname() {
    		return nickname;
    	}
    
    	public void setNickname(String nickname) {
    		this.nickname = nickname;
    	}
    
    	public String getPassword() {
    		return password;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
        	
    }
    

    说明

    RegisterRequest类有3个成员变量:mobilenicknamepassword,这些变量都带有注解:

    • @NotNull 表示必填
    • @Size 字符串长度必须符合指定范围
    • @Pattern 输入字符串必须匹配正则表达式

    创建控制器

    我们创建AuthController控制器类,实现一个用户注册的接口:

    package com.qikegu.demo.controller;
    
    import javax.validation.Valid;
    
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.qikegu.demo.common.util.MiscUtil;
    import com.qikegu.demo.common.util.Result;
    import com.qikegu.demo.model.RegisterRequest;
    
    @RestController
    @RequestMapping("/auth")
    public class AuthController {
    	
        @RequestMapping(value = "/register", method = RequestMethod.POST, produces="application/json")
        public ResponseEntity<Result> register(
        	@Valid @RequestBody RegisterRequest register, 
        	BindingResult bindingResult
        ) {
    		if(bindingResult.hasErrors()) {	
    			//rfc4918 - 11.2. 422: Unprocessable Entity
    //			res.setStatus(422);
    //			res.setMessage("输入错误");
    //			res.putData("fieldErrors", bindingResult.getFieldErrors());
    			
    			Result res1 = MiscUtil.getValidateError(bindingResult);
    			
    			return new ResponseEntity<Result>(res1, HttpStatus.UNPROCESSABLE_ENTITY);
    		}
        	
    		Result res = new Result(200, "ok");
            return ResponseEntity.ok(res);
        }
    }
    

    说明

    方法register有2个参数

    • @Valid @RequestBody RegisterRequest register @RequestBody 表明输入来自请求body,@Valid表明在绑定输入时作校验
    • BindingResult bindingResult 这个参数存放校验结果

    辅助类 MiscUtil,Result

    直接返回bindingResult过于复杂,使用MiscUtil.getValidateError简化校验结果

    	static public Result getValidateError(BindingResult bindingResult) {
    		
    		if(bindingResult.hasErrors() == false) 
    			return null;
    		
    		Map<String,String> fieldErrors = new HashMap<String, String>();
    		
    		for(FieldError error : bindingResult.getFieldErrors()){
    			fieldErrors.put(error.getField(), error.getCode() + "|" + error.getDefaultMessage());
    		}
    		
    		Result ret = new Result(422, "输入错误"); //rfc4918 - 11.2. 422: Unprocessable Entity
    		ret.putData("fieldErrors", fieldErrors);
    		
    		return ret;
    	}
    

    Result是结果封装类,[spring boot 接口返回值封装] 那一篇中已经介绍过。

    运行

    Eclipse左侧,在项目根目录上点击鼠标右键弹出菜单,选择:run as -> spring boot app 运行程序。 打开Postman访问接口,运行结果如下:

    输入错误的情况

    image

    输入正确的情况

    image

    总结

    完整代码

  • 相关阅读:
    5分钟带你了解Kafka的技术架构
    聊聊我的知识体系
    你分得清楚Maven的聚合和继承吗?
    为抖音而生的多闪,如何获取抖音的用户数据?
    消息中间件系列第3讲:使用消息队列需要考虑的几个问题
    消息中间件系列第2讲:如何进行消息队列选型?
    消息中间件系列第1讲:为什么要用消息队列?
    JVM规范系列开篇:为什么要读JVM规范?
    安全编码实践之三:身份验证和会话管理防御
    安全编码实践之二:跨站脚本攻击防御
  • 原文地址:https://www.cnblogs.com/jinbuqi/p/11014415.html
Copyright © 2011-2022 走看看