简体   繁体   English

Spring 引导 @RequestBody 默认 POJO 映射行为?

[英]Spring boot @RequestBody default POJO mapping behavior?

I have a java class with uppercase field names and some of them with under scroll, like this:我有一个 java class 带有大写字段名称,其中一些带有下滚动,如下所示:

public class DATADto {
  private String UPPERCASE;
  private String UNDER_SCROLL;

  public String getUPPERCASE() { return UPPERCASE; }
  public void setUPPERCASE(String s) { UPPERCASE = s; }
  ...//setters and getters
}

and I used this in a rest endpoint that accepts json in a spring rest controller: and I used this in a rest endpoint that accepts json in a spring rest controller:

@RestController
@RequestMapping({"/api/path"})
public class MyRestController {
   @PostMapping(path = {"/Data"}, consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)

    public ResponseEntity<?> useDATADto(@RequestBody DATADto aDATADto ) {
     //do something
    }
}

what JSON fields do I need to send by default and why?我需要默认发送哪些 JSON 字段,为什么?

It will depend on the Jackson property naming strategy.这将取决于 Jackson 属性命名策略。 The default is LOWER_CAMEL_CASE , so your request body should look like this:默认值为LOWER_CAMEL_CASE ,因此您的请求正文应如下所示:

{
    "uppercase": "test",
    "under_scroll": "test"
}

For all possible configurations of the naming strategy for Jackson please refer to the document «Class PropertyNamingStrategy»有关 Jackson 命名策略的所有可能配置,请参阅文档«Class PropertyNamingStrategy»

If you're using Spring, you may use this property to configure the naming strategy:如果您使用的是 Spring,您可以使用此属性来配置命名策略:

spring.jackson.property-naming-strategy

Another possible way will be the bean configuration:另一种可能的方式是 bean 配置:

@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
     Jackson2ObjectMapperBuilder jacksonMapper = new Jackson2ObjectMapperBuilder();
     jacksonMapper.propertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE);
     return jacksonMapper;
}

Additional note:附加说明:

Your current naming approach doesn't follow the Java Code Conventions.您当前的命名方法不遵循 Java 代码约定。 If you need to process JSON with some specific naming format better to use the @JsonProperty annotation on the fields of your POJO.如果您需要使用某些特定命名格式处理 JSON,最好在 POJO 的字段上使用@JsonProperty注释。

Please see the example below:请看下面的例子:

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

@Data
public class DATADto {
    @JsonProperty("UPPERCASE")
    private String uppercase;
    @JsonProperty("UNDER_SCROLL")
    private String underScroll;
}

You should send post request to /api/path/data with this request body:您应该使用此请求正文向/api/path/data发送发布请求:

{
    "uppercase": "YOUR_VALUE",
    "under_scroll": "YOUR_VALUE"
}

The story goes like this..故事是这样的。。

Spring Boot by default uses Jackson ObjectMapper to serialize and deserialize Java objects. Spring Boot 默认使用 Jackson ObjectMapper 对 Java 对象进行序列化和反序列化。

In this context, by serialization we mean the conversion of java objects into json, deserialization is the reverse process.在这种情况下,序列化是指将 java 对象转换为 json,反序列化是相反的过程。

Regarding the @RequestBody annotation, the following is written in the documentation :关于@RequestBody注解, 文档中写了以下内容:

Annotation indicating a method parameter should be bound to the body of the web request.指示方法参数的注释应绑定到 web 请求的主体。 The body of the request is passed through an HttpMessageConverter to resolve the method argument depending on the content type of the request.请求的主体通过 HttpMessageConverter 传递,以根据请求的内容类型解析方法参数。 Optionally, automatic validation can be applied by annotating the argument with @Valid.或者,可以通过使用 @Valid 注释参数来应用自动验证。

In short, @RequestBody annotation tells Spring to deserialize an incoming request body into an object passed as a parameter to the handler method.简而言之, @RequestBody注释告诉 Spring 将传入的请求正文反序列化为作为参数传递给处理程序方法的 object。 Spring achieves this using MessageConverter Spring 使用MessageConverter实现此目的

Since Spring Boot uses Jackson by default for serializing and deserializing request and response objects in your REST APIs, and Jackson uses MappingJackson2HttpMessageConverter , so that will be message converter implementation that spring will use. Since Spring Boot uses Jackson by default for serializing and deserializing request and response objects in your REST APIs, and Jackson uses MappingJackson2HttpMessageConverter , so that will be message converter implementation that spring will use. You can read more about that here .您可以在此处阅读更多相关信息。

The important thing is that Jackson uses Java Bean naming conventions to figure out the json properties in a Java class. The important thing is that Jackson uses Java Bean naming conventions to figure out the json properties in a Java class. Acutally it uses default PropertyNamingStrategy . Acutally 它使用默认的PropertyNamingStrategy Here is what is written in documentation:以下是文档中写的内容:

In absence of a registered custom strategy, default Java property naming strategy is used, which leaves field names as is, and removes set/get/is prefix from methods (as well as lower-cases initial sequence of capitalized characters).在没有注册的自定义策略的情况下,使用默认的 Java 属性命名策略,它保留字段名称,并从方法中删除 set/get/is 前缀(以及小写的大写字符的初始序列)。

So, since you didn't set any naming strategy, it will use default one.因此,由于您没有设置任何命名策略,它将使用默认策略。

Beacause of that, if you send payload like this:因此,如果您发送这样的有效负载:

{
    "uppercase": "YOUR_VALUE",
    "under_scroll": "YOUR_VALUE"
}

That won't work, you will get exception, since there jackson won't find under_scroll property in your class, it will look for under_SCROLL , therefore this payload:那行不通,你会得到异常,因为 jackson 不会在你的 class 中找到under_scroll属性,它会寻找under_SCROLL ,因此这个有效载荷:

{
    "uppercase": "YOUR_VALUE",
    "under_SCROLL": "YOUR_VALUE"
}

will work.将工作。

To change default PropertyNamingStrategy check this article.要更改默认PropertyNamingStrategy ,请查看这篇文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM