SpringBoot接口接收json參數(shù)解析
SpringBoot接口接收json參數(shù)
前言
通常來講,HTTP 方法會映射為 CRUD 動作,但這并不是嚴(yán)格的限制,有時候 PUT 也可以用來創(chuàng)建新的資源,POST 也可以用來更新資源。所以在平時的 Web 開發(fā)中,你可能??吹絤ethod 的值是 GET 和 POST,但是我們需要養(yǎng)成一個好的編碼習(xí)慣。
| CRUD 動作 | HTTP 方法 |
|---|---|
| Create | POST |
| Read | GET |
| Update | PUT(全部資源) 或 PATCH(部分資源) |
| Delete | DELETE |
前提
首先在controller上加上注解:@RestController
@RestController
@RequestMapping("/user")
@Api(tags = "user", description = "用戶控制器")
public class UserController {
// ...
}
詳細(xì)介紹
一、GET
1)@PathVariable 獲取路徑參數(shù)。即 url/{id} 這種形式。
@GetMapping("/getDetail/{id}")
@ApiOperation(value = "根據(jù)id獲取用戶")
public RbacUser getDetail(@PathVariable Long id) {
return userService.getById(id);
}
2)@RequestParam 獲取查詢參數(shù)。即 url?name=xx 這種形式
主要有參數(shù):
value:參數(shù)名字,即入?yún)⒌恼埱髤?shù)名字,如username表示請求的參數(shù)區(qū)中的名字為username的參數(shù)的值將傳入;required:是否必須,默認(rèn)是true,表示請求中一定要有相應(yīng)的參數(shù),否則會報(bào)錯;
@GetMapping("/getByAccount")
@ApiOperation(value = "根據(jù)賬號獲取用戶")
public RbacUser getByAccount(@RequestParam(required = false) String account) {
return userService.getByAccount(account);
}
3) 直接封裝DTO參數(shù)形式
@GetMapping("/find")
@ApiOperation(value = "根據(jù)條件獲取用戶")
public List<RbacUser> find(RbacUserDTO rbacUserDTO) {
return userService.find(rbacUserDTO);
}
二、DELETE
@PathVariable 獲取路徑參數(shù)。即 url/{id} 這種形式。
@DeleteMapping("/delete/{id}")
@ApiOperation(value = "刪除用戶")
public void delete(@PathVariable Long id) {
userService.delete(id);
}
三、POST/PUT/PATCH
@RequestBody 將HTTP請求正文插入方法中,使用適合的 HttpMessageConverter 將請求體寫入某個對象。
@PostMapping("/create")
@ApiOperation(value = "創(chuàng)建用戶")
public RbacUser getByAccount(@RequestBody @Validated RbacUserDTO rbacUserDTO) {
return userService.save(rbacUserDTO);
}
@Validated:對數(shù)據(jù)進(jìn)行校驗(yàn),以下注解報(bào)錯會直接返回,如果校驗(yàn)類中包含一個對象引用屬性,需要在屬性上加上@Valid注解

具體參數(shù)檢驗(yàn)請參看下面
Springboot restFul 參數(shù)檢驗(yàn)
概述
對請求參數(shù)進(jìn)行檢驗(yàn),這在web中開始經(jīng)常能碰到,如果用一個個if/else去做判斷,相信這樣的代碼可讀性會比較差
JSR-303 是java為bean數(shù)據(jù)合法性校驗(yàn)提供的標(biāo)準(zhǔn)框架,是Java EE6中的一項(xiàng)子規(guī)范,叫做BeanValidation。JSR303通過在Bean屬性上標(biāo)注@NotNull、@Max等標(biāo)準(zhǔn)的注解指定校驗(yàn)規(guī)則,并通過這些標(biāo)準(zhǔn)的驗(yàn)證接口對Bean進(jìn)行驗(yàn)證。
規(guī)定一些檢驗(yàn)規(guī)范即校驗(yàn)注解,如@Null, @NotNull, @Pattern,位于javax.validation.constraints包下,只提供規(guī)范 不提供實(shí)現(xiàn)。
在Spring中,有兩種方式可以驗(yàn)證輸入,一是利用Spring自帶的驗(yàn)證框架,二是利用JSR-303的實(shí)現(xiàn),一般建議使用JSR-303的實(shí)現(xiàn),比如Hibernate-Validator。
Hibernate-Validator 是JSR-303的實(shí)現(xiàn)。Hibernate Validator提供了JSR-303規(guī)范中所有內(nèi)置constraint的實(shí)現(xiàn),除此之外還有一些附加的constraint,如@Email, @Length, @Range等,位于org.hibernate,validator.constraints包下。
spring-boot-starter-web包里面已經(jīng)有了hibernate-vlidator包,不需要額外引用hibernate validator依賴。
同時Spring為了給開發(fā)者提供便捷,對Hibernate-Validator進(jìn)行了二次封裝,封裝了LocalValidatorFactorBean作為validator的實(shí)現(xiàn),這個類兼容了Spring的Validation體系和Hibernate的Validation體系,LocalValidatorFactorBean已經(jīng)成為了Validator的默認(rèn)實(shí)現(xiàn)。
說明:JSR-349是JSR-303的升級版,添加了一些新特性
如下圖,是spring boot 2.1.1中hibernate依賴情況:

常用注解
| 屬性 | 描述 | 舉例 |
| @AssertTrue | 應(yīng)用于boolean屬性,該屬性值必須為true |
@AssertTrue boolean isOkay; |
| @AssertFalse | 應(yīng)用于boolean屬性,該屬性值必須為false |
@AssertFalse boolean isOkay; |
| @DecimalMax | 只能小于或等于指定值 |
@DecimalMax("1.1") BigDecimal price; |
| @DecimalMin | 只能大于或等于指定值 |
@DecimalMin("1.1") BigDecimal price; |
| @Digits | 該屬性值必須在指定范圍內(nèi),interger屬性定義該數(shù)值的最大整數(shù)部分,fraction屬性定義該數(shù)值的最大 小數(shù)部分 |
@Digits(integer=5, fraction=2) BigDecimal price; |
| @Future | 檢查該字段是否是屬于未來的日期 |
@Future Date shippingDate; |
| @Max | 該字段的值只能小于或等于該值 |
@Max(20) int age; |
| @Min | 該字段的值只能大于或等于該值 |
@Min(20) int age; |
| @NotNull | 該字段不能為Null |
@NotNull String name; |
| @Null | 該字段必須是Null |
@Null String dest; |
| @Past | 該字段必須是過去的一個日期 |
@Past Date birthDate; |
| @Size | 檢查該字段的size是否在min和max之間,可以是字符串、數(shù)組、集合、Map等 |
@Size(min=2, max=10) String description; |
| @Pattern | 該屬性值必須與指定的常規(guī)表達(dá)式相匹配 |
@Pattern(regexp="\\d{3}") String areaCode; |
| @NotBlank | 只用于String, 不能為Null且trim()之后size>0 |
@NotBlank String src; |
| @NotEmpty | 不能為Null,且size>0 |
@NotEmpty String src; |
| 被注釋的元素必須是電子郵箱地址 | ||
| @Length | 被注釋的字符串String 大小必須在指定范圍內(nèi) |
@Length(min=6, max=12, message="密碼長度必須在6~12") String src; |
| @Range | BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子類型和包裝類型,驗(yàn)證注解的元素值在最小值和最大值之間 | |
| @Valid |
指定遞歸驗(yàn)證(下篇講)關(guān)聯(lián)的對象; 如用戶對象中有個地址對象屬性,如果想在驗(yàn)證用戶對象時一起驗(yàn)證地址對象的話,在地址對象上加@Valid注解即可級聯(lián)驗(yàn)證 |
簡單應(yīng)用舉例
需要檢驗(yàn)的Bean定義:
public class StudentBean implements Serializable{
@NotBlank(message = "用戶名不能為空")
private String name;
@Min(value = 18, message = "年齡不能小于18歲")
private Integer age;
@Pattern(regexp = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手機(jī)號格式錯誤")
private String phoneNum;
@Email(message = "郵箱格式錯誤")
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
返回錯誤字段定義:
public class ArgumentsInvalidResponseBean {
private String argumentName;
private String exceptionMsg;
public ArgumentsInvalidResponseBean() {
}
public ArgumentsInvalidResponseBean(String argumentName, String exceptionMsg) {
this.argumentName = argumentName;
this.exceptionMsg = exceptionMsg;
}
public String getArgumentName() {
return argumentName;
}
public void setArgumentName(String argumentName) {
this.argumentName = argumentName;
}
public String getExceptionMsg() {
return exceptionMsg;
}
public void setExceptionMsg(String exceptionMsg) {
this.exceptionMsg = exceptionMsg;
}
}
全局異常處理:
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public List<ArgumentsInvalidResponseBean> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex){
System.out.println("===================methodArgumentNotValidExceptionHandler Occur============");
List<ArgumentsInvalidResponseBean> argumentsInvalidResponseBeanList = new ArrayList<>();
for (FieldError error : ex.getBindingResult().getFieldErrors()){
ArgumentsInvalidResponseBean bean = new ArgumentsInvalidResponseBean();
bean.setArgumentName(error.getField());
bean.setExceptionMsg(error.getDefaultMessage());
argumentsInvalidResponseBeanList.add(bean);
}
return argumentsInvalidResponseBeanList;
}
測試代碼:
@RestController
public class CheckController {
@PostMapping("stu")
public String addStu(@Valid @RequestBody StudentBean studentBean){
return "add student success";
}
}
在PostMan中測試:

注意這里,年齡和郵箱是有錯誤的,運(yùn)行后查看返回值,具體如下:

自定義校驗(yàn)
新建注解類 MyConstraint:
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {
String message() default "這是一個自定義注解,檢測輸入是否大寫";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
實(shí)現(xiàn)MyConstraintValidator:
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
@Override
public void initialize(MyConstraint constraintAnnotation) {
System.out.println("+++++++++++++myConstraint init");
}
@Override
public boolean isValid(String o, ConstraintValidatorContext constraintValidatorContext) {
if (!o.equals(o.toUpperCase())){
System.out.println("輸入信息必須是大寫");
return false;
}
return true;
}
}
當(dāng)輸入信息不是全大寫字符時,則檢驗(yàn)不通過
使用:
在上面StudentBean中加入檢驗(yàn)
@MyConstraint private String className;
測試:

結(jié)果如下:

這時說明自定義檢驗(yàn)可以工作了
拋出BindException而非MethodArgumentNotValidException
當(dāng)請求中 Content-Type為“application/x-www-form-urlencoded”時,Spring會把數(shù)據(jù)解析成 web form data而非json,會使用 FormHttpMessageConverter來轉(zhuǎn)換post的body 并且異常轉(zhuǎn)為BindException。
如果我們想要Spring把POST數(shù)據(jù)認(rèn)為是json并且使用MappingJackson2HttpMessageConverter來解析數(shù)據(jù),可以把Content-Type設(shè)置成 application/json
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SPRINGMVC JSON數(shù)據(jù)交互如何實(shí)現(xiàn)
這篇文章主要介紹了SPRINGMVC JSON數(shù)據(jù)交互如何實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06
JavaWeb使用mvc模式實(shí)現(xiàn)登錄功能
本文主要介紹了JavaWeb使用mvc模式實(shí)現(xiàn)登錄功能,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
java Arrays快速打印數(shù)組的數(shù)據(jù)元素列表案例
這篇文章主要介紹了java Arrays快速打印數(shù)組的數(shù)據(jù)元素列表案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
Java class文件格式之?dāng)?shù)據(jù)類型(二)_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java class文件格式之?dāng)?shù)據(jù)類型(二)的相關(guān)資料,需要的朋友可以參考下2017-06-06
SpringBoot+MyBatis-Plus實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離的代碼示例
在當(dāng)今互聯(lián)網(wǎng)應(yīng)用中,數(shù)據(jù)庫讀寫分離是提高系統(tǒng)性能和穩(wěn)定性的重要手段之一,通過將讀操作和寫操作分別路由到不同的數(shù)據(jù)庫節(jié)點(diǎn),可以有效減輕數(shù)據(jù)庫服務(wù)器的負(fù)擔(dān),本文將介紹如何利用SpringBoot和MyBatis-Plus框架實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離,需要的朋友可以參考下2023-11-11

