SpringBoot校验请求Json参数
spring boot 校验请求json参数
在后端开发中,通过接口和参数传输来进行与前端交互,才可以让一个项目成型。
由于全后端隔离的方式,所以有时候需要不那么信任前端,也就是在验证当前操作是否有权限同时,校验前端传来的参数的合理性也是必不可少的。
这里只记录post json数据时候的校验方法。
以下代码中使用到的依赖,以及工具类,在结果的git链接中可以找到
一般的校验方法
代码:
// 测试接口
@RestController
@RequestMapping("/simple")
public class SimpleController { // 开发中建议另外定义一个类来接受=收
// 可以使用内部类, 不过不要写太多
@Data
private static class TestParam {
private int num;
private String str;
} @PostMapping("/test")
public R<?> test(@RequestBody(required = false) TestParam param) { if (StringUtils.isNull(param)
|| StringUtils.isEmpty(param.getStr()) || param.getNum() <= 0) {
return R.paramErr();
} // TODO 逻辑处理 return R.ok(new JSONObject());
}
}
测试参数:
{ }
or
{
"str": 1
}
or
{
"num": 2
}
结果:
{
"code": "1001",
"msg": "参数格式错误",
"data": null
}
结果以及分析:
- 表述不清楚,不管是缺少,还是不符合格式,全部返回格式错误(单独判断很冗余)。
- 在str传输数字时候可以通过(给数字类型传纯字符串的处理方法在2.2第第二个处理器)
接下来记录springboot提供的参数校验注解
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.5.6</version>
</dependency>
参数注解
@Data
private static class TestParam {
@Min(value = 1L, message = "数字参数最小值不能小于1")
@NotNull(message = "缺少数字参数")
private int num; @NotNull(message = "缺少字符串参数")
private String str; @NotNull(message = "对象参数不能为空")
@Valid
private TestObjParam obj;
} @Data
public static class TestObjParam {
@NotNull(message = "对象参数内,参数不能为空")
// 若还有内部对象,继续使用 @Valid 注解即可
private String param; @NotEmpty(message = "数组不能为空")
private List<String> stringList; @Size(max = 2, min = 0, message = "性别参数必须在0-2之间")
private int gender;
} @PostMapping(value = "/test")
Object test(@RequestBody @Validated TestParam param) {
return "通过测试";
}
与之配套使用的
@RestControllerAdvice
public class ControllerAdvice { /**
* 拦截JSON参数校验
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> bindException(MethodArgumentNotValidException e) { BindingResult bindingResult = e.getBindingResult(); String msg = Objects.requireNonNull(
bindingResult.getFieldError()).getDefaultMessage(); Map<String, String> result = new HashMap<>(); result.put("code", "1001");
result.put("msg", msg);
result.put("data", null); return result;
} /**
* 拦截类型不匹配。也即需要字段传对象,数字传字符串和对象的情况
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(HttpMessageNotReadableException.class)
public R<?> bindException(HttpMessageNotReadableException e) { return R.paramErr("参数中有不符合目标格式的");
}
}
结果分析
- 大大减少了在进行逻辑开发前的手动参数校验
- 同时前端在对接口时候也可以准确地清楚参数缺少和不符合要求的情况。
常用的参数,完整版可以在包
javax.validation.constraints中注解 解释 所修饰类型 @NotNull 被注解的元素不能为null 修饰所有类型参数 @NotEmpty 不能为空 数组 @Min(value) 被注解元素的最小值等于value 数字类型 @Max(value) 被注解的元素的最大值等于value 数字类型 @Size(max, min) 大小注解 数组 @Pattern(value) 正则表达式做鉴定 git地址: springboot-param-validate
补充:
- @Range校验数字范围
- @Length校验字符串长度
- @Size校验String和数组长度
- @Digits(integer = 6, fraction = 0, message = "") 修饰数字(整数位数和小数位数)
- @BigDecimalMax和min可配合Digits
参考资料:
- 如何使用springboot优雅地校验请求参数
- Spring方法级别数据校验:@Validated + MethodValidationPostProcessor优雅的完成数据校验动作
- @Validated注解详解,分组校验,嵌套校验,@Valid和@Validated 区别,Spring Boot @Validated
- @Validated和@Valid的区别?校验级联属性(内部类)
- 【参数校验框架】@Validated 嵌套校验的使用
- validation校验规则
- springboot项目中自定义注解的使用总结、java自定义注解实战(常用注解DEMO)
- Spring和SpringBoot常用注解
2022-11-17 补充分组
@Validated与@Validate的简要区别:
@Validated校验的对象中如果有对象类型的属性, 该属性上需要用@Validate, 可进行校验传递@Validated可进行分组校验,@Validate无分组校验.
分组:
import javax.validation.GroupSequence;
/**
* 至于interface与@interface在此处的区别, 并未得知
* 参考:
* <a href="https://blog.csdn.net/weixin_45941064/article/details/124192836">Java @interface和interface的区别</a>
* <a href=" https://reflectoring.io/bean-validation-with-spring-boot">Validation with Spring Boot - the Complete Guide</a>
* <a href="https://nullbeans.com/how-to-use-java-bean-validation-in-spring-boot/">How to use Java Bean Validation in Spring Boot</a>
* <a href="https://gitee.com/bootx/bootx-platform">bootx-platform, @cn.bootx.common.core.validation</a>
*
* @author wangXiaoMing
* @date 2022/11/14 17:51
*/
public interface ValidationGroup {
/**
* 参数校验分组:添加
*/
@interface create {
}
/**
* 参数校验分组:修改
*/
@interface update {
}
/**
* 参数校验分组:添加修改 - 也可使用序列
*/
@interface createUpdate {
}
/**
* 参数校验分组:删除
*/
@interface delete {
}
/**
* 参数校验分组:查询
*/
@interface query {
}
/**
* 先校验update, 再校验delete, 然后时create
* 代表校验顺序, 和需要校验的分组
* <p>
* 参考:
* <a href="https://blog.csdn.net/qq_17586821/article/details/104661914">validation-api中@GroupSequence的使用</a>
* <a href="https://blog.csdn.net/chepeng3577/article/details/100719210">@GroupSequence自定义验证顺序</a>
* <a href="https://blog.csdn.net/linxingliang/article/details/122044749">validation数据校验之分组校验怎么玩?</a>
*/
@GroupSequence({update.class, delete.class, create.class})
@interface order {
}
}
使用:
多个分组时需要使用{}, 单个时可省略
@NotNull(message = "id不能为空1", groups = {ValidationGroup.create.class})
Controller中使用时@Validated({ValidationGroup.create.class})进行校验
分组序列@GroupSequence的使用:
- 指定包含的分组(其他分组不会校验, 如上面的
query和createUpdate) - 以及校验的对应的顺序
SpringBoot校验请求Json参数的更多相关文章
- 逐层解析请求json参数字符串【我】
import net.sf.json.JSONObject; 逐层解析请求json参数字符串: InputStream inStream =null; BufferedReader br =null; ...
- SpringBoot获取请求的参数
说明 SpringBoot 为我们封装了许多,简便的获取请求参数的方法! 1.获取无注解获取请求参数 请求地址:http://192.168.0.115:8080/myproject/test/noA ...
- SpringBoot:自定义注解实现后台接收Json参数
0.需求 在实际的开发过程中,服务间调用一般使用Json传参的模式,SpringBoot项目无法使用@RequestParam接收Json传参 只有@RequestBody支持Json,但是每次为了一 ...
- SpringBoot配置Swagger实例(POST接收json参数)
工程目录结构: 首先,引入jar包,只需要以下两个即可 <dependency> <groupId>io.springfox</groupId> <artif ...
- play framework接收post请求json格式的参数
大家在用play framework框架开发第三方调用你的接口的时候并且用json格式的参数post请求 ,参数接收是个问题 ,因为play对表单提交post请求有处理: 有两种方法: 1.直接形参列 ...
- C# ContentType: "application/json" 请求方式传json参数问题
处理Http请求时遇到的ContentType为application/json方式,记录下这种Post请求方式下如何传json参数: var request = (HttpWebRequest)We ...
- ②HttpURLConnection通过Json参数方式提交Post请求
之前的文章介绍过通过报文的方式HttpURLConnection提交post请求,今天介绍下通过Json参数的方法提交Post请求,先上代码 public static HttpResponse se ...
- ReadyAPI/soapUI发送post请求json格式(带有中文字符),后台获取参数为空
解决:请求编码格式默认为空,在"TestCase"的指定Step的Request Properties中, 改Encoding编码格式为UTF-8. 原文:soapUI发送post ...
- curl 使用 post 请求,传递 json 参数,下载文件
curl -X POST http://ip:8888/nacos/v1/cs/file/download -H "Accept: application/octet-stream" ...
- 1. 处理静态资源 2. controller如何接受请求得参数 3. 如何把controller得数据保存到view. 4. 在controller如何完成重定向到指定路径 5. controller返回json数据
1. 1. 处理静态资源2. controller如何接受请求得参数3. 如何把controller得数据保存到view.4. 在controller如何完成重定向到指定路径5. controller ...
随机推荐
- Markers pg walkthrough Intermediate
发现是个md 变成pdf 的功能站 上网查exp 发现先了一个有用的 https://security.snyk.io/vuln/SNYK-JS-MARKDOWNPDF-5411358 能够任意文件读 ...
- C# WebAPI 插件热插拔
背景 WebAPI 插件热插拔是指在不重启应用程序的情况下,能够动态地加载.更新或卸载功能模块(即插件)的能力.这种设计模式在软件开发中非常有用,尤其是在需要频繁更新或扩展功能的大型系统中.通过实现插 ...
- Qemu-KVM基本工作原理介绍
本文分享自天翼云开发者社区<Qemu-KVM基本工作原理介绍>,作者:郑****文 1.KVM与Qemu关系 Qemu本身并不是KVM的一部分,而是一整套完整的虚拟化解决方案,它是纯软件实 ...
- Codeforces 11D A Simple Task 题解 [ 蓝 ] [ 状压 dp ]
思路不难想,细节比较多. 思路 观察到 \(n \le 19\) ,首先想到状压 dp . 于是自然地定义 \(dp[j][i]\) 为:抵达点的状态为 \(i\) ,且此时在点 \(j\) 时,简单 ...
- .NET中 泛型 + 依赖注入 的实现与应用
在.NET中,注入泛型依赖项是一个常见的场景. 在依赖注入(DI)中使用泛型可以使得应用程序更加模块化.易于测试和扩展. 在ASP.NET Core中注册泛型服务 假设我们有一个需要注入的泛型接口 I ...
- [ABC297F] Minimum Bounding Box 2 题解
容斥真有趣. 有一个性质: 两个相同的子矩阵,对答案的贡献一定相同. 所以就只需要枚举矩阵大小即可. 我们设当前矩阵长 \(i\) 宽 \(j\)(对应的,\(H\) 为长,\(W\) 为宽),假如要 ...
- autMan奥特曼机器人-自建autMan插件市场
一.自建市场配置 配置参数 二.上架设置 设置哪些插件上架,哪些不上架 三.检测是否成功 怎样检查是否成功了?订阅一下自己,然后看应用市场上是否显示 四.用户怎样购买插件 用户想买自建市场作者的插件, ...
- Typecho添加一个当前页面加载完成速度时间
判断当前页面加载是否快速,通常是直接在浏览器中访问网站,看自己的直观感受是否快速.而客观的方法则是计算具体的页面加载时间并显示出来给看. 1.在当前主题的functions.php文件添加下面的代码: ...
- 标题Spark Mavem项目在本地测试报错 : Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/SparkConf
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/SparkConf at S ...
- C#语法糖foreach语句和using语句联合使用
foreach语句可以和using语句联合使用,比如你需要对多个相机设备进行一些设置,设置完就调用 Dispose() 释放相机资源, 这时可以这样写: 模拟的设备类: class Device : ...