Spring RestTemplate getForObject 方法映射到 Map<String, POJO> 类

huangapple 未分类评论52阅读模式
英文:

Spring RestTemplate getForObject Map<String, POJO> class mapping

问题

我有以下的POJO:

class TestPojo {
    
    private Long testId = null;
    private String testString = null;
    private boolean testBoolean = false;
    private Float testFloat = null;
    private int testInt = 0;
    private Collection<String> testCollection = new TreeSet();
    
    Long getTestId() {
        return testId;
    }

    void setTestId(Long testId) {
        this.testId = testId;
    }

    String getTestString() {
        return testString;
    }

    void setTestString(String testString) {
        this.testString = testString;
    }

    boolean getTestBoolean() {
        return testBoolean;
    }

    void setTestBoolean(boolean testBoolean) {
        this.testBoolean = testBoolean;
    }

    Float getTestFloat() {
        return testFloat;
    }

    void setTestFloat(Float testFloat) {
        this.testFloat = testFloat;
    }

    int getTestInt() {
        return testInt;
    }

    void setTestInt(int testInt) {
        this.testInt = testInt;
    }

    Collection<String> getTestCollection() {
        return testCollection;
    }

    void setTestCollection(Collection<String> testCollection) {
        this.testCollection = testCollection;
    }
}

我有两个REST API响应,一个返回单个TestPojo实例的JSON格式:

{
  "testId": 1,
  "testString": "testStringA",
  "testBoolean": false,
  "testFloat": 1.0,
  "testInt": 1,
  "testCollection": [
    "testCollectionA",
    "testCollectionB"
  ]
}

另一个REST API响应返回多个TestPojo的映射:

{
  "TestPojoA": {
    "testId": 1,
    "testString": "testStringA",
    "testBoolean": false,
    "testFloat": 1.0,
    "testInt": 1,
    "testCollection": [
      "testCollectionA",
      "testCollectionB"
    ]
  },
  "TestPojoB": {
    "testId": 2,
    "testString": "testStringB",
    "testBoolean": true,
    "testFloat": 1.1,
    "testInt": 2,
    "testCollection": [
      "testCollectionC",
      "testCollectionB"
    ]
  }
}

我的Rest Template与MappingJackson2HttpMessageConverter可以正确返回第一个JSON的POJO:

RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
TestPojo testPojo = restTemplate.getForObject("http://127.0.0.1:8081/test/getPojoInstance", TestPojo.class);

然而,我无法正确地将映射中的POJO转换出来。我尝试过各种方法,我以为以下的代码会起作用,但它只返回一个带有两个字符串值的映射,而不是String和POJO:

RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
Map<String, TestPojo> testPojoMap = restTemplate.getForObject("http://127.0.0.1:8081/test/getPojoMap", Map<String, TestPojo>.class);

我知道在接收响应后,我可以将映射中的字符串值转换为TestPojo,但我只是想知道是否在第一种情况下有什么我没有做对的地方?

英文:

I have the following POJO:

class TestPojo {
    
    private Long testId = null;
    private String testString = null;
    private boolean testBoolean = false;
    private Float testFloat = null;
    private int testInt = 0;
    private Collection&lt;String&gt; testCollection = new TreeSet();
    
    Long getTestId() {
        return testId;
    }

    void setTestId(Long testId) {
        this.testId = testId;
    }

    String getTestString() {
        return testString;
    }

    void setTestString(String testString) {
        this.testString = testString;
    }

    boolean getTestBoolean() {
        return testBoolean;
    }

    void setTestBoolean(boolean testBoolean) {
        this.testBoolean = testBoolean;
    }

    Float getTestFloat() {
        return testFloat;
    }

    void setTestFloat(Float testFloat) {
        this.testFloat = testFloat;
    }

    int getTestInt() {
        return testInt;
    }

    void setTestInt(int testInt) {
        this.testInt = testInt;
    }

    Collection&lt;String&gt; getTestCollection() {
        return testCollection;
    }

    void setTestCollection(Collection&lt;String&gt; testCollection) {
        this.testCollection = testCollection;
    }
}

I have two rest API responses, one which returns a single instance of TestPojo in JSON format:

{
  &quot;testId&quot;: 1,
  &quot;testString&quot;: &quot;testStringA&quot;,
  &quot;testBoolean&quot;: false,
  &quot;testFloat&quot;: 1.0,
  &quot;testInt&quot;: 1,
  &quot;testCollection&quot;: [
    &quot;testCollectionA&quot;,
    &quot;testCollectionB&quot;
  ]
}

The other rest API response returns a map of multiple TestPojo's:

{
  &quot;TestPojoA&quot;: {
    &quot;testId&quot;: 1,
    &quot;testString&quot;: &quot;testStringA&quot;,
    &quot;testBoolean&quot;: false,
    &quot;testFloat&quot;: 1.0,
    &quot;testInt&quot;: 1,
    &quot;testCollection&quot;: [
      &quot;testCollectionA&quot;,
      &quot;testCollectionB&quot;
    ]
  },
  &quot;TestPojoB&quot;: {
    &quot;testId&quot;: 2,
    &quot;testString&quot;: &quot;testStringB&quot;,
    &quot;testBoolean&quot;: true,
    &quot;testFloat&quot;: 1.1,
    &quot;testInt&quot;: 2,
    &quot;testCollection&quot;: [
      &quot;testCollectionC&quot;,
      &quot;testCollectionB&quot;
    ]
  }
}

My Rest Template with MappingJackson2HttpMessageConverter correctly returns the POJO for the first JSON:

RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
TestPojo testPojo = restTemplate.getForObject(&quot;http://127.0.0.1:8081/test/getPojoInstance&quot;, TestPojo.class);

I can't get the POJO in the map to correctly convert though however? I've tried various ways, I thought the following would work but this just returns a map with two string values instead of String & POJO:

RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
Map&lt;String, TestPojo&gt; testPojoMap = restTemplate.getForObject(&quot;http://127.0.0.1:8081/test/getPojoMap&quot;, Map&lt;String, TestPojo&gt;.class);

I know I can convert the string value in my map to a TestPojo after I receive the response but I'm just curious if it's something I'm not doing correctly in the first instance?

答案1

得分: 0

RestTemplate可以将JSON反序列化成java.util.Map,而不是java.util.Map&lt;String, TestPojo&gt;

你可以使用Jackson ObjectMapper和TypeReference来实现:

String testPojoMap = restTemplate.getForObject("http://127.0.0.1:8081/test/getPojoMap", String.class);
ObjectMapper objectMapper = new ObjectMapper();
Map<String, TestPojo> map = objectMapper.readValue(testPojoMap, new TypeReference<Map<String, TestPojo>>(){});

或者,如果不使用RestTemplate:

ObjectMapper objectMapper = new ObjectMapper();
Map<String, TestPojo> map = objectMapper.readValue("http://127.0.0.1:8081/test/getPojoMap", new TypeReference<Map<String, TestPojo>>(){});
英文:

RestTemplate can deserialize JSON like you have into a java.util.Map not into java.util.Map&lt;String, TestPojo&gt;

You can use Jackson ObjectMapper to give TypeReference

String testPojoMap = restTemplate.getForObject(&quot;http://127.0.0.1:8081/test/getPojoMap&quot;, String.class);
ObjectMapper objectMapper = new ObjectMapper();
Map&lt;String, TestPojo&gt; map = objectMapper.readValue(testPojoMap, new TypeReference&lt;Map&lt;String,TestPojo&gt;&gt;(){});

Or

Without Rest templete

ObjectMapper objectMapper = new ObjectMapper();
Map&lt;String, TestPojo&gt; map = objectMapper.readValue(&quot;http://127.0.0.1:8081/test/getPojoMap&quot;, new TypeReference&lt;Map&lt;String,TestPojo&gt;&gt;(){});

答案2

得分: 0

我认为这是由于getForObject中的类型问题,我建议使用exchange方法

ResponseEntity&lt;Map&lt;String,TestPojo&gt;&gt; response = template.exchange(&quot;http://127.0.0.1:8081/test/getPojoMap&quot;, 
         HttpMethod.GET, null, new ParameterizedTypeReference&lt;Map&lt;String,TestPojo&gt;&gt;() {
});

Map&lt;String,TestPojo&gt; body = response.getBody();
英文:

I think it was because of type problem in getForObject, I would suggest to use exchange method

ResponseEntity&lt;Map&lt;String, TestPojo&gt;&gt; response = template.exchange(&quot;http://127.0.0.1:8081/test/getPojoMap&quot;, 
         HttpMethod.GET, null, new ParameterizedTypeReference&lt;Map&lt;String, TestPojo&gt;&gt;() {
});

Map&lt;String, TestPojo&gt; body = response.getBody();

huangapple
  • 本文由 发表于 2020年4月10日 21:02:39
  • 转载请务必保留本文链接:https://java.coder-hub.com/61140840.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定