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-Typeheader的正确HttpMessageConverter。在您的情况下,假设默认值,这将导致 MappingJackson2HttpMessageConverter。它将使用 body 转换为枚举。然后它将失败,因为它不是有效的 JSON 字符串(没有引号)。

解释了 JSON 中的字符串 here