【问题标题】:Rest template ResponseEntity body is changing the types of variables, how to control the types?Rest模板ResponseEntity body是改变变量的类型,如何控制类型?
【发布时间】:2020-06-09 22:20:26
【问题描述】:

我正在从具有以下内容的应用发出 Post 请求

Set<Accounts> set = populateAccounts();
ResponseEntity<Map> responseMap = 
restTemplate.postForEntity("http://localhost:8080/maptest", set, Map.class);
return responseMap.getBody();

然后这个请求会从 responseMap.getBody() 中返回一个 Map;

以下是我收到发布请求的代码

@PostMapping("/maptest")
public ResponseEntity<Map> mapReturn(@RequestBody Set<Accounts> accounts) {
    HashMap<String, Amount> map = new HashMap<String, String>();
    map.put("account1", new Amount(BigDecimal.TEN));
    map.put("account2", new Amount(BigDecimal.ZERO));
    return ResponseEntity.ok(map);
}

问题是,返回的 Map 没有 BigDecimal 值,当我在 responseMap.getbody() 中看到这些 BigDecimal 值时,它们会自动转换为 Integer;

请帮助我了解如何将它们保持为 BigDecimal 值。

另外,实际的代码比上面的要复杂一些,但我想保持简单。我绝对希望将值保留为 BigDecimal,只是不确定如何。

【问题讨论】:

    标签: java rest http spring-restcontroller


    【解决方案1】:

    您可能正在使用 Jackson 作为 RestTemplate 的 marhalling 库。

    当您读取值时,ObjectMapper 将数字读取为整数/双精度等。 您可以使用以下配置属性轻松设置反序列化的行为。

    jackson-databind DeserializationFeature

    USE_BIG_DECIMAL_FOR_FLOATS

    如果只有泛型类型描述(Object 或 Number,或在无类型的 Map 或 Collection 上下文中)可用,则确定是否将 JSON 浮点数反序列化为 BigDecimals 的功能。

    USE_BIG_INTEGER_FOR_INTS

    如果只有泛型类型描述(Object 或 Number,或在无类型的 Map 或 Collection 上下文中)可用,则确定是否将 JSON 整数(非浮点)数反序列化为 BigIntegers 的功能。

    要设置它,您可以按照here 的描述编写

    ObjectReader r = objectMapper.reader(MyType.class);
    // enable one feature, disable another
    MyType value = r
      .with(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
      .without(DeserializationFeature.WRAP_EXCEPTIONS)
      .readValue(source);
    

    或者只是

    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
    
    OptionTransaction transaction = mapper.readValue(jsonString, OptionTransaction.class);
    

    您当然可以编写自己的number deserializers 并使用@JsonDeserialize(using = CustomNumberDeserializer.class) 注释。

    其他 marhalling 库(如 Gson)也可以使用类似的技术

    【讨论】:

    • 谢谢,你是对的,我正在使用 Jackson 数据绑定。我不明白这在我拥有的代码中的位置。 OptionTransaction 部分是否适合我有 postForEntity 的代码?如果是这样,我有点困惑,因为我从响应中得到了一个 Map,而不是一个 json,所以部分 OptionTransaction transaction = mapper.readValue(jsonString, OptionTransaction.class);我不清楚,因为我看到你那里有 jsonString
    • ObjectMapper 可以转换值 - 从一个对象到另一个具有不同类的对象。所以你可以随时convertValue
    • 您也可以使用restTemplate.getMessageConverters().add(0, createMappingJacksonHttpMessageConverter());配置restTemplate,参数类型为MappingJackson2HttpMessageConverter
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 2021-07-25
    • 2022-01-12
    • 1970-01-01
    相关资源
    最近更新 更多