英文:
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<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;
}
}
I have two rest API responses, one which returns a single instance of TestPojo in JSON format:
{
"testId": 1,
"testString": "testStringA",
"testBoolean": false,
"testFloat": 1.0,
"testInt": 1,
"testCollection": [
"testCollectionA",
"testCollectionB"
]
}
The other rest API response returns a map of multiple TestPojo's:
{
"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"
]
}
}
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("http://127.0.0.1:8081/test/getPojoInstance", 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<String, TestPojo> testPojoMap = restTemplate.getForObject("http://127.0.0.1:8081/test/getPojoMap", Map<String, TestPojo>.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<String, TestPojo>
。
你可以使用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<String, TestPojo>
You can use Jackson ObjectMapper
to give 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>>(){});
Or
Without Rest templete
ObjectMapper objectMapper = new ObjectMapper();
Map<String, TestPojo> map = objectMapper.readValue("http://127.0.0.1:8081/test/getPojoMap", new TypeReference<Map<String,TestPojo>>(){});
答案2
得分: 0
我认为这是由于getForObject中的类型问题,我建议使用exchange方法
ResponseEntity<Map<String,TestPojo>> response = template.exchange("http://127.0.0.1:8081/test/getPojoMap",
HttpMethod.GET, null, new ParameterizedTypeReference<Map<String,TestPojo>>() {
});
Map<String,TestPojo> body = response.getBody();
英文:
I think it was because of type problem in getForObject, I would suggest to use exchange method
ResponseEntity<Map<String, TestPojo>> response = template.exchange("http://127.0.0.1:8081/test/getPojoMap",
HttpMethod.GET, null, new ParameterizedTypeReference<Map<String, TestPojo>>() {
});
Map<String, TestPojo> body = response.getBody();
专注分享java语言的经验与见解,让所有开发者获益!
评论