@JsonProperty不适用于Content-Type:application / x-www-form-urlencoded

时间:2016-08-04 03:18:31

标签: java rest jackson spring-restcontroller

当REST API映射到Java对象时,REST API采用输入内容类型: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.

    }

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

我正在使用Jackson-annotations 2.3 jar

任何建议可能出错?

2 个答案:

答案 0 :(得分:3)

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

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

所以,为了让那些杰克逊注释使用你的POJO工作,你必须:

  1. 将您的数据作为地图
  2. 使用Jackson的ObjectMapper
  3. 解析您的数据地图

    在我的情况下,使用Spring我可以使用以下代码解决此问题:

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

    当您从@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);
    

    我希望它可以帮助你对我的帮助:)。

答案 1 :(得分:1)

我认为非常简单的解决方案是使用“_”将变量与变量相关联。

public class MyRequest {

    @JsonProperty("my_name")
    private String myName;

    @JsonProperty("my_phone")
    private String myPhone;

    //Getters and Setters of myName and myPhone.

    //Setters for application/x-www-form-urlencoded
    public void setMy_name(String name) {
        setMyName(name);
    }
    ......
}

还有更多解决方案。请参阅link