@JsonProperty 不适用于内容类型:application/x-www-form-urlencoded

Vin*_*gla 5 java rest jackson spring-restcontroller

当 REST API 映射到 Java 对象时,它采用输入内容类型:application/x-www-form-urlencoded,例如

 public class MyRequest {

    @JsonProperty("my_name")
    private String myName;

    @JsonProperty("my_phone")
    private String myPhone;

    //Getters and Setters of myName and myPhone.

    }
Run Code Online (Sandbox Code Playgroud)

在表单输入请求中,我设置了 my_name 和 my_phone 的值,但 MyRequest 对象的 myName 和 myPhone 为 null。

我正在使用 Jackson-annotations 2.3 jar

有什么建议可能有什么问题吗?

小智 6

我最近使用 SpringMVC 和 Jackson 遇到了同样的问题!

在 Spring 中,当您显式配置端点以仅使用application/x-www-form-urlencoded请求时,Spring 能够序列化到您的 POJO 类,但它不使用 Jackson,因为它不是 JSON。

因此,为了让这些 Jackson 注释使用 POJO 工作,您必须:

  1. 以地图形式获取您的数据
  2. 使用 Jackson 的 ObjectMapper 解析您的数据图

就我而言,使用 Spring 我可以使用以下代码解决此问题:

@RequestMapping(
        value = "/rest/sth",
        method = RequestMethod.POST
)
public ResponseEntity<String> create(@RequestBody MultiValueMap paramMap) { ... }
Run Code Online (Sandbox Code Playgroud)

当您从注释中删除“consume”属性时,@RequestMapping您必须使用@RequestBody该属性,否则 Spring 将无法将您的映射识别为有效参数。

您可能会注意到的一件事是,这MultiValueMap不是一张常规地图。每个元素值是一个LinkedList因为 http 表单数据可以重复值,因此这些值将被添加到该链接列表中。

考虑到这一点,下面是一个简单的代码,用于获取第一个元素并创建另一个映射以转换为 POJO:

    HashMap<String, Object> newMap = new HashMap<>();
    Arrays.asList(new String[]{"my_name", "my_phone"})
            .forEach( k -> newMap.put(k, ((List<?>) paramMap.get(k)).get(0)));

    MyRequest myrequest = new ObjectMapper().convertValue(newMap, MyRequest.class);
Run Code Online (Sandbox Code Playgroud)

我希望它能帮助你它如何帮助我:)