在序列化和反序列化 Jackson 中以小写字母响应

Response with lowercase letters in serialization and deserialization Jackson

WS 的响应是首字母大写的 json。我正在尝试将响应封装在首字母小写的新 MyResponse obj 中。

我正在使用 Jackson。

起初我有我的模型:

public class Telephone {

    private String country;
    private String prefix;

    //getters and setters
}

public class Position {

    private String x;
    private String y;

    //getters and setters
}

public class Root  {
    @JsonProperty("Telephone")
    private List<Telephone> telephone;
    @JsonProperty("Position")
    private List<Position> position;

    //getters and setters
}

public class MyResponse {

    private final Root root;
    private final String now;

    public MyResponse(Root root, String now) {
        this.root = root;
        this.now = now;
    }

    //getters
}

正如您在上面看到的,我在 Root class 中使用了 @JsonProperty 因为我想使用第一个小写字母映射我的响应。

现在我有了我的 RestController:

@Controller
public class RestController {

    @GetMapping("/my-controller")
    ResponseEntity<String> myController() {

        //Simulating the request to my ws to get my json string
        String jsonString = "{\n" +
                "   \"Telephone\":[\n" +
                "      {\n" +
                "         \"country\":\"ES\",\n" +
                "         \"prefix\":\"+34\"\n" +
                "      },\n" +
                "      {\n" +
                "         \"country\":\"FR\",\n" +
                "         \"prefix\":\"+33\"\n" +
                "      },\n" +
                "      {\n" +
                "         \"country\":\"EN\",\n" +
                "         \"prefix\":\"+44\"\n" +
                "      }\n" +
                "   ],\n" +
                "   \"Position\":[\n" +
                "      {\n" +
                "         \"x\":\"123.23\",\n" +
                "         \"y\":\"98.93\"\n" +
                "      },\n" +
                "      {\n" +
                "         \"x\":\"250.99\",\n" +
                "         \"y\":\"43.89\"\n" +
                "      }\n" +
                "   ]\n" +
                "}";

        ObjectMapper om = new ObjectMapper();
        Root root = null;
        try {
            root = om.readValue(jsonString, Root.class);
            MyResponse myResponse = new MyResponse(root, LocalDateTime.now().toString());
            String responseAsString = om.writeValueAsString(myResponse);
            return new ResponseEntity<>(responseAsString, HttpStatus.OK);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

正如您在上面的代码片段中看到的,一开始我得到了 json 字符串(在我调用 WS 的真实代码中),我将它反序列化为 Java POJO 使用readValue 方法:

root = om.readValue(jsonString, Root.class);

然后我使用反序列化的 POJO 创建了我的 MyResponse 对象:

MyResponse myResponse = new MyResponse(root, LocalDateTime.now().toString());

最后,我使用 om.writeValueAsString 将 myResponse obj 序列化为 String 并将其返回到我的前端:

String responseAsString = om.writeValueAsString(myResponse);
return new ResponseEntity<>(responseAsString, HttpStatus.OK);

因为 MyResponse obj 是使用我的 Root @JsonProperty (s) 序列化和反序列化的 我得到:

{
   "root":{
      "Telephone":[
         {
            "country":"ES",
            "prefix":"+34"
         },
         {
            "country":"FR",
            "prefix":"+33"
         },
         {
            "country":"EN",
            "prefix":"+44"
         }
      ],
      "Position":[
         {
            "x":"123.23",
            "y":"98.93"
         },
         {
            "x":"250.99",
            "y":"43.89"
         }
      ]
   },
   "now":"2021-06-24T11:18:04.077612"
}

这不是我想要做的:我在回复中将字母大写。 我怎么解决这个问题?我应该使用两种不同的 classes 进行序列化和反序列化吗?

您也可以在 getter 和 setter 上指定您的 Jackson 注释,让它们有不同的行为。像这样:

public class Root  {
    private List<Telephone> telephone;

    @JsonProperty("Telephone")
    private void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    @JsonProperty("telephone")
    private String getTelephone() {
        this.telephone = telephone;
    }
}

我已经尝试了 Felix 的建议。但它没有用,我收到以下错误:

Conflicting/ambiguous property name definitions found multiple explicit names: but also implicit accessor

一段时间后,我能够以这种方式解决我的问题:

public class Root  {

private List<Telephone> telephone;
private List<Position> position;

@JsonCreator
public Root(@JsonProperty("Telephone") List<Telephone> telephon, @JsonProperty("Position") List<Position> position) {
    this.telephon = telephon;
    this.position = position;
}

    //getters and setters

}

注解@JsonCreator仅在反序列化阶段使用。 当反序列化时,Jackson 使用注释为 @JsonCreator 的构造函数。在序列化阶段,Jackson 使用字段名称将 obj 转换为 String。