Spring Boot - Json RequestBody, String/Enum with/without 引号
Spring Boot - Json RequestBody, String/Enum with/without quotation marks
我遇到了一个奇怪的问题。为什么第一个代码接受不带引号的输入,而第二个不接受?
说实话,第二个说得有道理。但是为什么第一个接受不带引号的输入呢?
我真的很想知道为什么做出这个决定。
package com.example.corntest;
import lombok.extern.log4j.Log4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE;
@SpringBootApplication
@RestController
public class CornTestApplication {
public static void main(String[] args) {
SpringApplication.run(CornTestApplication.class, args);
}
//works - does NOT remove quotation marks
//curl 'http://localhost:8080/test' -X POST -H 'Content-Type: application/json' --data-raw '"SunGoesUp"' -vv
//works - but doesnt make sense - in comp. to code made in the bottom
//curl 'http://localhost:8080/test' -X POST -H 'Content-Type: application/json' --data-raw 'SunGoesUp' -vv
@PostMapping(value = "/test", consumes = APPLICATION_JSON_VALUE)
void mytestPost(@RequestBody String myString){
System.out.println(myString);
}
enum Test {
TESTA,
TESTB,
TESTC
}
//works
//curl 'http://localhost:8080/testEnum' -X POST -H 'Content-Type: application/json' --data-raw '"TESTA"' -vv
//does not work
//curl 'http://localhost:8080/testEnum' -X POST -H 'Content-Type: application/json' --data-raw 'TESTA' -vv
//Why
@PostMapping(value = "/testEnum", consumes = APPLICATION_JSON_VALUE)
void myTestEnum(@RequestBody Test myEnumValue){
System.out.println(myEnumValue);
}
}
在您使用 @RequestBody String myString
的情况下,http 请求的有效负载放在 as-is 中。所以无论你发送什么都会放在那里。 content-type 无关紧要,因为它将按原样复制请求的有效负载。
在第二种情况下,需要实际的 JSON 字符串才能转换为枚举。基于 JSON 的字符串需要有引号,否则它不是 JSON 字符串。字符串以外的内容无法转换为枚举。
要从 body 的有效负载转换为请求的 object Spring,请使用 [HttpMessageConverter
]。它将select基于Content-Type
header的正确HttpMessageConverter
。在您的情况下,假设默认值,这将导致 MappingJackson2HttpMessageConverter
。它将使用 body 转换为枚举。然后它将失败,因为它不是有效的 JSON 字符串(没有引号)。
解释了 JSON 中的字符串 here。
我遇到了一个奇怪的问题。为什么第一个代码接受不带引号的输入,而第二个不接受?
说实话,第二个说得有道理。但是为什么第一个接受不带引号的输入呢?
我真的很想知道为什么做出这个决定。
package com.example.corntest;
import lombok.extern.log4j.Log4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE;
@SpringBootApplication
@RestController
public class CornTestApplication {
public static void main(String[] args) {
SpringApplication.run(CornTestApplication.class, args);
}
//works - does NOT remove quotation marks
//curl 'http://localhost:8080/test' -X POST -H 'Content-Type: application/json' --data-raw '"SunGoesUp"' -vv
//works - but doesnt make sense - in comp. to code made in the bottom
//curl 'http://localhost:8080/test' -X POST -H 'Content-Type: application/json' --data-raw 'SunGoesUp' -vv
@PostMapping(value = "/test", consumes = APPLICATION_JSON_VALUE)
void mytestPost(@RequestBody String myString){
System.out.println(myString);
}
enum Test {
TESTA,
TESTB,
TESTC
}
//works
//curl 'http://localhost:8080/testEnum' -X POST -H 'Content-Type: application/json' --data-raw '"TESTA"' -vv
//does not work
//curl 'http://localhost:8080/testEnum' -X POST -H 'Content-Type: application/json' --data-raw 'TESTA' -vv
//Why
@PostMapping(value = "/testEnum", consumes = APPLICATION_JSON_VALUE)
void myTestEnum(@RequestBody Test myEnumValue){
System.out.println(myEnumValue);
}
}
在您使用 @RequestBody String myString
的情况下,http 请求的有效负载放在 as-is 中。所以无论你发送什么都会放在那里。 content-type 无关紧要,因为它将按原样复制请求的有效负载。
在第二种情况下,需要实际的 JSON 字符串才能转换为枚举。基于 JSON 的字符串需要有引号,否则它不是 JSON 字符串。字符串以外的内容无法转换为枚举。
要从 body 的有效负载转换为请求的 object Spring,请使用 [HttpMessageConverter
]。它将select基于Content-Type
header的正确HttpMessageConverter
。在您的情况下,假设默认值,这将导致 MappingJackson2HttpMessageConverter
。它将使用 body 转换为枚举。然后它将失败,因为它不是有效的 JSON 字符串(没有引号)。
解释了 JSON 中的字符串 here。