Spring中使用JSR303请求约束判空的实现

1. 适用场景

有时候我们在表单里提交一系列参数, 到后台封装成一个对象, 要对对象的属性做各种字段值的约束; 这时候, 当然可以if-else一个一个的判断, 有更简洁的做法, 就是使用 JSR303+spring的validation:

2. 使用方法步骤(分3步)

  • 实体类加字段约束注解
  • Controller类中@Valid标注启用(@Validated也兼容@Valid)
  • BindingResult获取报错信息

2.1 实体类加字段约束注解

如我们要收集前端表单的字段数据到Person实体中:

对需要约束的字段进行注解标注;

示例:

2.1.1 Person.java

package com.niewj.demo.model;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.URL;
import javax.validation.constraints.*;
import java.util.List;

@Data
public class Person {
  @Length(min = 4, max = 10)
  @NotNull(message = "name不能为空")
  private String name;

  @Min(0)
  @Max(40)
  @NotNull(message = "age不能为空")
  private Integer age;

  @NotBlank
  @NotBlank
  @URL(message = "logo必须是URL格式")
  private String logo;

  @NotEmpty(message = "hobbies不能为空")
  private List<String> hobbies;

  @Email
  @NotNull(message = "email不能为空!")
  private String mail;
}

@NotNull 约束字段不可为空;

@NotEmpty 约束集合/map等不能为空不能为0元素

@Email 约束是 email格式

@URL 约束必须是url的格式

message属性可以修改默认错误说明

2.2 Controller类中@Valid标注启用(@Validated兼容@Valid)

2.2.1 HelloController.java

package com.niewj.demo.controller;

import com.google.gson.Gson;
import com.niewj.demo.common.Result;
import com.niewj.demo.model.Person;
import com.niewj.demo.service.TestService1;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * test
 *
 * @author niewj
 * @since 2020/11/16 15:22
 */
@Controller
public class HelloController {

  /**
   * @param person
   * @param bindingResult
   * @return
   */
  @PostMapping("/test")
  @ResponseBody
  public Result doSth(@Valid @RequestBody Person person, BindingResult bindingResult) {
    Map<String, String> map = new HashMap<>();
    if (bindingResult.hasErrors()) {
      bindingResult.getFieldErrors().stream().forEach(fe-> map.put(fe.getField(), fe.getDefaultMessage()));
      System.out.println(bindingResult.getFieldError().getDefaultMessage());
      return Result.withErrorParamData(map);
    }

    return Result.withSuccessData(person);
  }
}

@RequestBody可以将body中的请求流信息(Request.getInputStream)通过HttpMessageConverter自动转换为目标java类型:

  • 如果前端 Content-Type为application/json, 就使用 JSON消息转换器 帮你转为JSON对象;
  • 如果前端 Content-Type为application/xml, 就使用 XML消息转换器 帮你转为xml;
  • 如果前端 Content-Type为text/plain, 就是用 String消息转换器 帮你转成 String; (只有类型为String时才可以转换)

2.2.2 Result.java:

package com.niewj.demo.common;

import lombok.Data;

import java.io.Serializable;
import java.util.Map;

/**
 * 返回结果模板封装
 *
 * @author niewj
 * @since 2020/12/17 18:05
 */
@Data
public class Result<T> implements Serializable {
  private int code;
  private String msg;
  private T data;

  public Result(int code, String msg, T data) {
    this(code, msg);
    this.data = data;
  }

  public Result(int code, String msg) {
    this.msg = msg;
    this.code = code;
  }

  public static <T> Result<T> withData(ResponseEnum responseCode, T data) {
    Result<T> re = new Result(responseCode.getCode(), responseCode.getMsg());
    re.data = data;
    return re;
  }

  public static Result<String> withSuccessNoData() {
    Result re = new Result(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg());
    re.data = "";
    return re;
  }

  public static <T> Result<T> withSuccessData(T data) {
    Result re = new Result(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg());
    re.data = data;
    return re;
  }

  public static Result<Map<String, String>> withErrorParamData(Map<String, String> data) {
    Result re = new Result(ResponseEnum.BAD_REQUEST.getCode(), ResponseEnum.BAD_REQUEST.getMsg());
    re.data = data;
    return re;
  }
}

2.2.3 ResponseEnum.java

package com.niewj.demo.common;

/**
 * 通用响应码
 */
public enum ResponseEnum {

  SUCCESS(200, "成功"),
  BAD_REQUEST(400, "请求参数不合规");

  /**
   * 错误码
   */
  private Integer code;
  /**
   * 错误信息
   */
  private String msg;

  ResponseEnum(Integer code, String msg) {
    this.code = code;
    this.msg = msg;
  }

  public String getMsg() {
    return msg;
  }

  public Integer getCode() {
    return code;
  }
}

2.3 BindingResult获取报错信息

  • BindingResult用来收集约束字段的错误信息, 可通过 bindingResult.hasErrors()的 true来过滤错误信息;
  • bindingResult.getFieldErrors() 会返回 List<FieldError>;
  • FieldError 得到字段名: getField(); 得到错误信息: getDefaultMessage()

3. 调用测试:

http://localhost:8888/test

3.1 请求用例1: 字段为空

header: Content-Type: application/json

{
  "name": "1"
}

响应:

{
  "code": 400,
  "msg": "请求参数不合规",
  "data": {
    "mail": "email不能为空!",
    "hobbies": "hobbies不能为空",
    "name": "长度需要在4和10之间",
    "logo": "不能为空",
    "age": "age不能为空"
  }
}

3.2 请求用例2: list无元素/email/url格式不对

header: Content-Type: application/json

{
  "name": "1234",
  "hobbies": [],
  "mail": "niewj",
  "logo": "niewj.com"
}

响应:

{
  "code": 400,
  "msg": "请求参数不合规",
  "data": {
    "mail": "不是一个合法的电子邮件地址",
    "hobbies": "hobbies不能为空",
    "logo": "logo必须是URL格式",
    "age": "age不能为空"
  }
}

3.3 请求用例3: 完整字段信息

header: Content-Type: application/json

{
  "name": "1234",
  "hobbies": ["running"],
  "mail": "hi@niewj.com",
  "logo": "http://niewj.com",
  "age": 40
}

响应:

{
  "code": 200,
  "msg": "成功",
  "data": {
    "name": "1234",
    "age": 40,
    "logo": "http://niewj.com",
    "hobbies": [
      "running"
    ],
    "mail": "hi@niewj.com"
  }
}

到此这篇关于Spring中使用JSR303请求约束判空的实现的文章就介绍到这了,更多相关Spring JSR303请求约束判空内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot集成JSR303参数校验的方法实现

    JSR303 是一套 JavaBean 参数校验的标准 1.pom导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> 2.注解类型 (1)空检查 @Null 验证对象是否为null @NotNull 验证对象是否不为null,

  • SpringBoot使用jsr303校验的实现

    依赖添加 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> 一些较老版本的SpringBoot需要添加相关依赖,我使用的2.1.4发行版不用这个操作. 验证使用对象接收参数的情况 public class PointDeductSet

  • SpringBoot结合JSR303对前端数据进行校验的示例代码

    一.校验分类 数据的校验一般分为**前端校验.后端校验** 二.前端校验 前端校验是最为明显的,先说一下: ① HTML 非空校验 如 HTML5 新增的属性required="true",一旦没有填写就输入框就显示红色,具体使用如: <input type="text" id="name" name="name" required="true"/> ② JS 同时在提交表单发送 Ajax请求

  • Spring Boot利用JSR303实现参数验证的方法实例

    简介 JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation. 在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情.应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的.在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成.很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等.为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定. Bean Va

  • Spring中使用JSR303请求约束判空的实现

    1. 适用场景 有时候我们在表单里提交一系列参数, 到后台封装成一个对象, 要对对象的属性做各种字段值的约束; 这时候, 当然可以if-else一个一个的判断, 有更简洁的做法, 就是使用 JSR303+spring的validation: 2. 使用方法步骤(分3步) 实体类加字段约束注解 Controller类中@Valid标注启用(@Validated也兼容@Valid) BindingResult获取报错信息 2.1 实体类加字段约束注解 如我们要收集前端表单的字段数据到Person实体

  • 浅谈Java8 判空新写法

    目录 引言 API介绍 1.Optional(),empty(),of(),ofNullable() 2.orElse(),orElseGet()和orElseThrow() 3.map()和flatMap() 4.isPresent()和ifPresent(Consumer<? super T> consumer) 5.filter(Predicate<? super T> predicate) 实战 例一 例二 例三 引言 在开发过程中很多时候会遇到判空校验,如果不做判空校验则

  • spring中@Reference注入为空的解决方法

    线上发生事故了 前天晚上上线一波,发生了一个挺有意思的事,昨天复盘了一下,今天分享一下. 晚上的时候,我负责的系统和收银系统同时上线一波(用的是Dubbo).然后很神奇的事情发生了,收银系统用@Reference注解注入我的接口,然后这个接口的实现类居然为空. 其实我们当时没排查出来是什么原因? 重启了一下就好了,毕竟重启大法好. 但本着不能给用户充钱的路上造成阻碍,还是要排查一波这个代理对象为空是如何造成的. 线上dubbo的版本为2.8.9,注意包名是(com.alibaba) 为了方便大家

  • 详解java 中Spring jsonp 跨域请求的实例

    详解java 中Spring jsonp 跨域请求的实例 jsonp介绍 JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏览器的跨域数据访问的问题.由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外.利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSO

  • Spring MVC中处理ajax请求的跨域问题与注意事项详解

     前言 有时候前后台做数据交互,会遇到烦人的跨域请求问题,如果你还是一枚编程小白来说,无疑来说是很痛苦的事. 当然网上也肯定会有一些解决方法.但自身实力有限,不一定会看的懂,能把问题解决了.所以下面这篇文章就来给大家总结介绍在Spring MVC中处理ajax请求的跨域问题与一些注意事项,话不多说了,来一起看看详细的介绍吧. 为何跨域 简单的说即为浏览器限制访问A站点下的js代码对B站点下的url进行ajax请求.假如当前域名是www.abc.com,那么在当前环境中运行的js代码,出于安全考虑

  • 如何在Java中优雅地判空详解

    前言 整天都是在跟Java打交道.我在Java开发中最常用的一段代码就是用object != null在使用对象之前判断是否为空.这么做是为了避免NullPointerException.但是我发现这样检测代码实在是太丑了,而且及其不可读. 那有没有一种优雅的替代方法呢? 判空灾难 作为搬砖党的一族们,我们对判空一定再熟悉不过了,不要跟我说你很少进行判空,除非你喜欢NullPointerException. 不过NullPointerException对于很多猿们来说,也是Exception家族

  • Spring Boot中扩展XML请求与响应的支持详解

    前言 在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一个对象呢? 什么是xml文件格式 我们要给对方传输一段数据,数据内容是"too young,too simple,sometimes naive",要将这段话按照属性拆分为三个数据的话,就是,年龄too young,阅历too simple,结果sometimes naive.

  • Spring中注解方式的异步请求

    一.Servlet3.0异步请求 @WebServlet(value = "/async", asyncSupported = true) public class HelloAsyncServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //

  • spring cloud gateway中如何读取请求参数

    spring cloud gateway读取请求参数 1. 我的版本: spring-cloud:Hoxton.RELEASE spring-boot:2.2.2.RELEASE spring-cloud-starter-gateway 2. 请求日志 import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springfram

  • JDK8中Optional类巧用之判空操作

    前言 相信大家肯定所有的开发者都对Java8里面的所有的东西都感兴趣,虽然目前的 JDK 已经更新到 JDK17 了,但是我相信,现在很多公司使用的还都是 JDK8 甚至是 JDK7,但是,就算是有些公司已经升级到 JDK8 但是对于 JDK8 里面的一些东西的使用,却没有使用的淋漓尽致. 今天就给大家放出几个 JDK8 里面比较好用的. JDK8 大家都是知道 JDK8 就开始使用 Lambda 表达式,但是很多不管是在教程上还是在其他的书籍上,都没有说在实际开发的时候去使用上这个 Lambd

随机推荐