gpt4 book ai didi

java - SpringBoot RestTemplate 交换存在 ResponseEntity 的 ParameterizedTypeReference 转换问题

转载 作者:太空宇宙 更新时间:2023-11-04 09:50:58 24 4
gpt4 key购买 nike

我正在构建两个应该相互通信的微服务。我使用 Eureka 作为服务注册中心。

微服务 1 -Microservice1.java

@SpringBootApplication
public class Microservice1Application {
public static void main(String[] args) {
SpringApplication.run(Microservice1Application.class, args);
}
}

Microservice1Controller.java

@RestController
@RequestMapping("/getdata")
public class Microservice1Controller {
@GetMapping(value = "/")
public ResponseEntity<Microservice1ResponseWrapper<List<Customer1>>> getAll() {
List<Customer1> list = //get data from repository

return new ResponseEntity<Microservice1ResponseWrapper<List<Customer1>>>(new Microservice1ResponseWrapper<List<Customer1>>(Microservice1ResponseStatus.SUCCESS,list);
}
}

Microservice1ResponseWrapper.java - 这是通用包装器

public class Microservice1ResponseWrapper<T> {
private Microservice1ResponseStatus status;
private T data;
//constructor, getter and setters
}

applicationProperties.yaml

spring:
application:
name: microservice1

server:
port: 8073

微服务2Microservice2将从Microservice1获取数据

@SpringBootApplication
public class Microservice2Application {
public static void main(String[] args) {
SpringApplication.run(Microservice2Application.class, args);
}
}

@Configuration
class Config {

@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

Microservice2Controller.java

@RestController
@RequestMapping("/fetchdata")
public class Microservice2Controller {
@Autowired
private RestTemplate restTemplate;


@GetMapping(value = "/")
public ResponseEntity<Microservice2ResponseWrapper<List<Customer2>>> getAll() {
String getAllUrl = "http://microservice1/getdata/";
ParameterizedTypeReference<Microservice2ResponseWrapper<List<Customer2>>> parameterizedTypeReference =
new ParameterizedTypeReference<Microservice2ResponseWrapper<List<Customer2>>>(){};

ResponseEntity<Microservice2ResponseWrapper<List<Customer2>>> listData =
restTemplate.exchange(getAllUrl, HttpMethod.GET, null,parameterizedTypeReference);
return listData;
}
}

Microservice2ResponseWrapper.java - 这是通用包装器

public class Microservice2ResponseWrapper<T> {
private Microservice2ResponseStatus status;
private T data;
//constructor, getter and setters
}

applicationProperties.yaml

spring:
application:
name: microservice2

server:
port: 8074

Customer1(在微服务1中)和Customer2(微服务2)几乎是相同的对象。

public class Customer1 implements Serializable {

private static final long serialVersionUID = 1L;

private Long custId;

private String custName;

private String firstName;

private String lastName;

private Long age;

public Customer1() {
}

public Customer1(String custName, String firstName, String lastName, Long age) {
this.custName = custName;
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}

public Customer1(Long custId, String custName, String firstName, String lastName, Long age) {
this.custId = custId;
this.custName = custName;
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}

//getter, setter and toString
}

微服务2中的Customer2.java

public class Customer2 implements Serializable {

private static final long serialVersionUID = 1L;

private Long custId;

private String custName;

private String firstName;

private String lastName;

private Long age;

public Customer2() {
}

//getter, setter and toString
}

当我运行 Microservice1 时:http://localhost:8073/getdata它从数据库获取数据并且工作正常。这是我在屏幕上看到的响应:

<Microservice1ResponseWrapper>
<status>SUCCESS</status>
<data>
<custId>1</custId>
<custName>string1</custName>
<firstName>string1</firstName>
<lastName>string1</lastName>
<age>30</age>
</data>
</Microservice1ResponseWrapper>

当我运行 Microservice2 时:http://localhost:8074/fetchdata它应该转到微服务 1 并获取数据。

但是,我收到如下错误:

org.springframework.web.client.RestClientException: Error while extracting response for type
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:117)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:994)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:977)

Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.rest.Customer2` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('1'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.rest.Customer2` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('1')
at [Source: (PushbackInputStream); line: 1, column: 61] (through reference chain: com.rest.wrapper.Microservice2ResponseWrapper["data"]->java.util.ArrayList[0])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:245)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:227)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:102)
... 77 more

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.rest.Customer2` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('1')
at [Source: (PushbackInputStream); line: 1, column: 61] (through reference chain: com.rest.wrapper.Microservice2ResponseWrapper["data"]->java.util.ArrayList[0])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1032)
at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:371)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:323)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1373)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:171)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3084)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:239)

我在 ParameterizedTypeReference 或 Resttemplate 交换调用中犯了任何错误吗?

注意:如果我在没有 Eureka 注册表的情况下运行这两个微服务,它们绝对可以正常工作。但是当我引入 Eureka 并向 Eureka 注册这两个服务时,我遇到了上述问题。为此,我刚刚对 Miroservice2 Controller 进行了更改:String getAllUrl = "http://localhost:8073/getdata/ ";

<小时/>

更新 - 2019 年 2 月 22 日

这是我尝试过的

更新了 Microservice1Controller-getAll() 如下:

    @GetMapping(value = "/") 
public ResponseEntity<List<Customer1>> getAll() {
List<Customer1> list = //get data from repository

return new ResponseEntity<List<Customer1>>(list);
}

更新了 Microservice2Controller-getAll() 方法

    @GetMapping(value = "/")
public ResponseEntity<List<Customer2>> getAll() {
String getAllUrl = "http://microservice1/getdata/";
ParameterizedTypeReference<List<Customer2>> parameterizedTypeReference =
new ParameterizedTypeReference<List<Customer2>>(){};

ResponseEntity<List<Customer2>> listData =
restTemplate.exchange(getAllUrl, HttpMethod.GET, null,parameterizedTypeReference);
return listData;
}

这工作得很好——如前面的描述所述,从微服务2调用微服务1。Microservice1 将 ResponseEntity> 返回到 Microservice2,Microservice2 将其转换为 ResponseEntity>。

但是,微服务1返回ResponseEntity<Microservice1ResponseWrapper<List<Customer1>>>到 Microservice2 并且 Microservice2 无法转换为 ResponseEntity<Microservice2ResponseWrapper<List<Customer2>>> .

<小时/>

更新 2019 年 6 月 28 日

如果我在 Microservice2 Controller 中进行以下更改,那么我会看到 2 个问题:

  1. 开始出现 LinkedHashMap 错误。java.lang.ClassCastException:java.util.LinkedHashMap无法转换为java.util.List
  2. 它不会提取所有记录,它只是从列表中提取最后一个元素。例如有 2 个用户,那么它只显示最后一个用户,而不是全部。
ParameterizedTypeReference<Microservice2ResponseWrapper>  parameterizedTypeReference = 
new ParameterizedTypeReference<Microservice2ResponseWrapper>(){};

ResponseEntity<Microservice2ResponseWrapper> listData =
restTemplate.exchange(getAllUrl, HttpMethod.GET, null,parameterizedTypeReference);
List ls = (List) listData.getBody().getData();

//if I print listData.getBody().getData() then it just shows only one record of users.

最佳答案

您需要为 Customer2 类创建一个默认构造函数。客户2(){}

关于java - SpringBoot RestTemplate 交换存在 ResponseEntity 的 ParameterizedTypeReference 转换问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54758577/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com