SpringBoot校验框架Validation及项目的国际化_javax.validation.constraints.notnull国际化-程序员宅基地

技术标签: spring boot  restful  SpringBoot  后端  

一、概述

虽然前端系统对后台API接口调用之前都会做数据的校验,但是考虑到很多API接口是直接暴露在外网中,后台接口对传入的参数做校验是不可缺少的。比如判断字段非空,字段长度限制,邮箱格式验证等,这时就可以用到Validation。

二、创建Spring Boot工程

三、创建类

3.1  UserVo类

package com.anron.vo;

import lombok.Data;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.List;

/**
 * @Author: Anron
 * @Date: 2020/3/29 17:30
 */
@Data
public class UserVo implements Serializable {
    private static final long serialVersionUID = 3869883763128105939L;

    @NotEmpty(message="{vo.UserVo.NAME_NOT_EMPTY}")
    private String name;

    @Min(value=18, message="{vo.UserVo.AGE_MUST_GREATERTHAN_18}")
    private int age;

    @NotEmpty(message="{vo.UserVo.HOBILLES_NOT_EMPTY}")
    private List<String> hobbies;

    @NotBlank(message="{vo.UserVo.ACCOUNT_NOT_EMPTY}")
    private String account;

    @NotNull(message="{vo.UserVo.PLATENO_NOT_EMPTY}")
    private String plateNo;

    @NotBlank(message="{vo.UserVo.ADDRESS_NOT_EMPTY}")
    private String address;

    @Size(min=6, max=20, message="{vo.UserVo.PASSWORD_SIZE}")
    @NotBlank(message="{vo.UserVo.PASSWORD_NOT_EMPTY}")
    private String password;

    @Email(message="{vo.UserVo.EMAIL_ERROR_FORMAT}")
    @NotBlank(message="{vo.UserVo.EMAIL_NOT_EMPTY}")
    private String email;
}

3.2  AppController类

package com.anron.controller;

import com.anron.dto.BaseDto;
import com.anron.util.WebControllerUtil;
import com.anron.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;

/**
 * @Author: Anron
 * @Date: 2020/3/29 17:32
 */
@Slf4j
@Controller
@RequestMapping(value = "/app")
public class AppController {

    @RequestMapping(value = "/addUser.do")
    @ResponseBody
    public BaseDto addUser(@RequestBody @Validated UserVo vo, BindingResult bindingResult, HttpServletRequest request) {
        log.info("---addUser start---vo:{}", vo.toString());
        WebControllerUtil.buildErrorMsg(bindingResult, request);
        return new BaseDto(true);
    }
}

3.3  BaseDto类

package com.anron.dto;

import lombok.Data;
import java.io.Serializable;

/**
 * @Author: Anron
 * @Date: 2020/3/29 17:34
 */
@Data
public class BaseDto implements Serializable {
    private static final long serialVersionUID = -1423147470994861814L;

    private String code;
    private String message;

    public BaseDto(boolean success) {
        if (success) {
            this.code = "0";
            this.message = "OK";
        }else {
            this.code = "500";
            this.message = "";
        }
    }
}

3.4  WebControllerUtil类

package com.anron.util;

import com.anron.exception.ServiceException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import javax.servlet.http.HttpServletRequest;

/**
 * @Author: Anron
 * @Date: 2020/3/29 17:37
 */
public class WebControllerUtil {

    public static void buildErrorMsg(BindingResult bindingResult, HttpServletRequest request) {
        if (bindingResult.hasErrors()) {
            String errorMsg = "";
            for (ObjectError error : bindingResult.getAllErrors()) {
                errorMsg += error.getDefaultMessage() + ",";
            }
            throw new ServiceException(errorMsg.substring(0, errorMsg.length() - 1));
        }
    }
}

3.5  ServiceException类

package com.anron.exception;

import lombok.Data;

/**
 * @Author: Anron
 * @Date: 2020/3/29 17:38
 */
@Data
public class ServiceException extends RuntimeException {
    private static final long serialVersionUID = 5412240839931206939L;

    private int code;
    private String msg;

    public ServiceException(String msg){
        super();
        this.code = 501;
        this.msg = msg;
    }
}

3.6  ControllerExceptionHandler类

package com.anron.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;

/**
 * @Author: Anron
 * @Date: 2020/3/29 17:46
 */
@ControllerAdvice
public class ControllerExceptionHandler {
    private static final int RESPONSE_STATUS = 200;

    @ExceptionHandler(ServiceException.class)
    public String handleException(HttpServletRequest request, HttpServletResponse response, ServiceException e) throws Exception {
        response.getOutputStream().write(e.toString().getBytes(StandardCharsets.UTF_8));
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        response.setStatus(RESPONSE_STATUS);
        response.getOutputStream().flush();
        return null;
    }
}

四、创建资源文件

4.1 ValidationMessages.properties

vo.UserVo.NAME_NOT_EMPTY=姓名不能为空
vo.UserVo.AGE_NOT_EMPTY=年龄不能为空
vo.UserVo.AGE_MUST_GREATERTHAN_18=年龄必须大于等于18岁
vo.UserVo.HOBILLES_NOT_EMPTY=兴趣爱好不能为空
vo.UserVo.ACCOUNT_NOT_EMPTY=账号不能为空
vo.UserVo.PLATENO_NOT_EMPTY=车牌号码不能为空
vo.UserVo.ADDRESS_NOT_EMPTY=地址不能为空
vo.UserVo.PASSWORD_SIZE=密码的长度应该在6和20之间
vo.UserVo.PASSWORD_NOT_EMPTY=密码不能为空
vo.UserVo.EMAIL_ERROR_FORMAT=邮箱格式错误
vo.UserVo.EMAIL_NOT_EMPTY=邮箱不能为空

4.2 ValidationMessages_zh_TW.properties

vo.UserVo.NAME_NOT_EMPTY=姓名不能為空
vo.UserVo.AGE_NOT_EMPTY=年齡不能為空
vo.UserVo.AGE_MUST_GREATERTHAN_18=年齡必須大於等於18嵗
vo.UserVo.HOBILLES_NOT_EMPTY=興趣愛好不能爲空
vo.UserVo.ACCOUNT_NOT_EMPTY=賬號不能爲空
vo.UserVo.PLATENO_NOT_EMPTY=車牌號碼不能爲空
vo.UserVo.ADDRESS_NOT_EMPTY=地址不能爲空
vo.UserVo.PASSWORD_SIZE=密碼的長度應該在6和20之間
vo.UserVo.PASSWORD_NOT_EMPTY=密碼不能爲空
vo.UserVo.EMAIL_ERROR_FORMAT=郵箱格式錯誤
vo.UserVo.EMAIL_NOT_EMPTY=郵箱不能爲空

4.3 ValidationMessages_en.properties

vo.UserVo.NAME_NOT_EMPTY=The name cannot be empty
vo.UserVo.AGE_NOT_EMPTY=The age cannot be empty
vo.UserVo.AGE_MUST_GREATERTHAN_18=Must be at least 18 years old
vo.UserVo.HOBILLES_NOT_EMPTY=A hobby cannot be empty
vo.UserVo.ACCOUNT_NOT_EMPTY=The account cannot be empty
vo.UserVo.PLATENO_NOT_EMPTY=The license plate number cannot be blank
vo.UserVo.ADDRESS_NOT_EMPTY=The address cannot be empty
vo.UserVo.PASSWORD_SIZE=The length of the password should be between 6 and 20
vo.UserVo.PASSWORD_NOT_EMPTY=The password cannot be empty
vo.UserVo.EMAIL_ERROR_FORMAT=Mailbox format error
vo.UserVo.EMAIL_NOT_EMPTY=The mailbox cannot be empty

五、创建http测试文件

5.1 AppController.addUser.http

POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json
Accept-Language: zh-CN;q=0.9,zh;q=0.8

{

}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json
Accept-Language: en,zh-CN;q=0.9,zh;q=0.8

{
"age":17
}


###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json
Accept-Language: zh-CN;q=0.9,zh;q=0.8

{
"age":18
}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json
Accept-Language: zh-TW;q=0.9,zh;q=0.8

{
"age":18,
"hobbies": []
}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"]
}


###@NotEmpty(message="姓名不能为空"),所以"name": " "也通过
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"],
"name": " "
}

###@NotBlank(message="账号不能为空"),所以"account": " "不通过
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"],
"name": "anron",
"account": " "
}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"],
"name": "anron",
"account": "admin"
}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"],
"name": "anron",
"account": "admin",
"address": "shenzhen, china"
}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"],
"name": "anron",
"account": "admin",
"address": "shenzhen, china",
"plateNo": ""
}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"],
"name": "anron",
"account": "admin",
"address": "shenzhen, china",
"plateNo": "",
"password": "12"
}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"],
"name": "anron",
"account": "admin",
"address": "shenzhen, china",
"plateNo": "",
"password": "123456"
}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"],
"name": "anron",
"account": "admin",
"address": "shenzhen, china",
"plateNo": "",
"password": "123456",
"email": "error email address"
}

###
POST http://localhost:8080/app/addUser.do
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
"age":18,
"hobbies": ["sport", "food"],
"name": "anron",
"account": "admin",
"address": "shenzhen, china",
"plateNo": "",
"password": "123456",
"email": "[email protected]"
}

 

项目代码结构如下图:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/anron/article/details/105180879

智能推荐

注册表禁用计算机管理,Win7注册表编辑器被管理员禁用的解除方法-程序员宅基地

文章浏览阅读2.7k次。熟悉Win7系统的朋友都知道,注册表编辑器是更改Win7系统设置的好工具。在注册表中可以完成控制面板中不能修改的设置。但是有些用户打开注册表编辑器的时候却被提示,注册表编辑器已被管理员禁用,这是怎么回事呢?如何解除Win7对注册表编辑器的限制呢?一、Win7打开注册表的方法1 Win+R键打开Win7系统的运行,在运行数输入regedit点击确定。二、注册表被禁用解除方法Win7注册表编辑器被管理..._注册表编辑器禁用和解除原因

mysql innodb 源码_【InnoDB源码分析】Redo log-程序员宅基地

文章浏览阅读502次。【版本:mysql-8.0.12】1. Mini Transaction(mtr)InnoDB会将事务执行过程拆分为若干个Mini Transaction(mtr),每个mtr包含一系列如加锁,写数据,写redo,放锁等操作。举个例子:void btr_truncate(const dict_index_t *index) {... ...page_size_t page_size(space-&..._mysql innodb 源代码 解读

matlab背景设置_preferences: path: c:\users\administrator\appdata\-程序员宅基地

文章浏览阅读515次。打开C:\Users\Administrator\AppData\Roaming\MathWorks\MATLAB\R2015b\matlab.prf修改为#MATLAB Preferences#Sat Jul 11 15:54:49 CST 2020Editor.VariableHighlighting.Color=C-6931898EditorMRUSize=I8ReplaceSearchText19=SReplaceSearchText18=SReplaceSearchText17=S_preferences: path: c:\users\administrator\appdata\roaming\mathworks\matlab\c

谁说技术男不浪漫!90后程序员2天做出情绪...-程序员宅基地

文章浏览阅读75次。点击上方[全栈开发者社区]→右上角[...]→[设为星标]点击领取全栈资料:全栈资料9月1日,一则关于#程序员2天做出猫咪情绪识别软件#的话题登上微博热搜,参与阅读的人数达到了82..._程序员自研

解决SpringBoot整合redis下的键值序列化的问题_spring boot redis 查询序列化key-程序员宅基地

文章浏览阅读1.3k次。文章目录思考redis实现键值序列化自定义一个序列化转换器编写redis配置文件编写application.properties编写User类编写controller编写service测试思考为什么键值要序序列化呢?​ 不同平台之间的数据传输,深拷贝,浅拷贝,如果不采用序列化,很容易在传输过程中出现各种错误,无法正常使用Redis的序列化到底是什么?​ 简单的是说 就是 key ..._spring boot redis 查询序列化key

tooltip ajax,浅谈AJAX中的Tooltip偏移量——offset-程序员宅基地

文章浏览阅读993次。现在大家上网,看到好多网站上,鼠标放到图片,他的相应信息出现在他的左侧或右侧。这就是AJAX的tooltip(关于tooltip的例子,此处不列举了)。而其中控制新的提示div位置的用到的就是offset。其中包括offsetWidth,offsetHeight,offsetLeft,offsetTop及offsetParent。前四个很好理解。本次主要谈谈offsetParent。offset是..._tooltip offset

随便推点

Android对数据按照时间排序,Android实现数据按照时间排序-程序员宅基地

文章浏览阅读748次。经常遇见一个列表,两个接口的情况,两个接口属于两个不同的表数据,那么数据拼接回来之后,并不是按照时间排序的,看起来就相当混乱,所以记录一下如何对数据按照时间排序。步骤一:格式化日期public static Date stringToDate(String dateString) {ParsePosition position = new ParsePosition(0);SimpleDateFo..._安卓代码实现聊天记录根据时间排序

华硕固件默认ip,新路由3 newifi d2刷机刷华硕固件教程-程序员宅基地

文章浏览阅读4.9k次。新路由3默认的功能非常的少,所以不刷个好固件简直就是浪费硬件性能,恢复出厂后默认的路由器IP就是192.168.99.1。准备下面几个工具和固件上面工具准备好以后,下面开始刷机:一. 开启固件 SSH1、开启路由器,进入管理界面 (假设路由器 IP 地址是 192.168.99.1)2、 在浏览器中输入 http://192.168.99.1/newifi/ifiwen_hss.html 并进入3..._路由器刷华硕固件之后默认ip

org.apache.maven.plugins:maven-compiler-plugin not found 问题解决_plugin 'org.apache.maven.plugins:maven-compiler-pl-程序员宅基地

文章浏览阅读3.1k次,点赞2次,收藏3次。<dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version></dependency>//把版本号改为3.1就好了//改后<dependency> <grou._plugin 'org.apache.maven.plugins:maven-compiler-plugin:3.1' not found

html轮播代码 圆点,关于JQuery和html+css实现带小圆点和左右按钮的轮播图分享-程序员宅基地

文章浏览阅读550次。本文主要为大家带来一篇JQuery和html+css实现带小圆点和左右按钮的轮播图实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。是的!你没看错!还是轮播图。这次的JQuery的哟!!CSS代码:/*轮播图 左右按钮 小白点*/#second_p{margin-top: 160px;}.img_box{overflow: hidden;widt..._html如何制作轮播图的小白色按钮

matlab计算涡度的函数_计算涡度的新方法-程序员宅基地

文章浏览阅读940次。计算涡度的新方法蔡其发;黄思训;高守亭;钟科;李自强【期刊名称】《物理学报》【年(卷),期】2008(057)006【摘要】提出应用一维数值微分算法求取观测风场的涡度场,并与中央差分方法作了比较.结果表明,一维数值微分算法稳定、可行且计算精度较高,对较小尺度的天气系统具有较强的识别能力.【总页数】8页(3912-3919)【关键词】数值微分;吉洪诺夫正则化;正则化解【作者】蔡其发;黄思训;高守亭;..._matlab 绝对涡度

Python如何安装OpenCV库_opencv安装-程序员宅基地

文章浏览阅读10w+次,点赞124次,收藏397次。OpenCV的概念可百度,在此不再赘述。 https://baike.baidu.com/item/opencv/10320623本文教大家在Window系统下Python如何安装OpenCV库。因为有强大的pip,所以只需要两步就可安装OpenCV库,步骤见下:第一步:win+R 打开命令行窗口,看到如下界面: 第二步:直接输入pip install opencv-pytho..._opencv安装

推荐文章

热门文章

相关标签