当前位置: 首页 > 知识库问答 >
问题:

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

凌和悦
2023-03-14

我正在构建两个微服务,它们应该互相对话。我正在使用尤里卡作为服务注册表。

微服务1-microservice1.java

@SpringBootApplication
public class Microservice1Application {
    public static void main(String[] args) {
        SpringApplication.run(Microservice1Application.class, args);
    }
}
@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);
    }
}
public class Microservice1ResponseWrapper<T> {
private Microservice1ResponseStatus status;
private T data;
//constructor, getter and setters
}
spring:
  application:
    name: microservice1

server:
  port: 8073

Microservice2将从Microservice1获取数据的Microservice2

@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
}
spring:
  application:
    name: microservice2

server:
  port: 8074
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
}
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时,它应该转到microservice1并获取数据。

然而,我得到了这样的错误:

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控制器进行了更改:字符串getAllUrl=“http://localhost:8073/getData/”;

更新-02/22/19

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

        return new ResponseEntity<List<Customer1>>(list);
    }
    @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;
    }   

这很好地工作--如前面的描述所述,从Microservice2调用Microservice1。Microservice1将ResponseEntity>返回到Microservice2,Microservice2将其转换为ResponseEntity>。

但是,将responseEntity > 返回到Microservice2和Microservice2的Microservice1无法转换为responseEntity >

更新06/28/19

如果我在Microservice2控制器中做了以下更改,那么我会看到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.

共有1个答案

曹渝
2023-03-14

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

 类似资料:
  • 我试图返回一个列表,并将该响应重定向到我的模型类。 例如:如果我使用,它工作得很好,但我不想为每个模型编写响应方法。 方法 错误 出现错误(Type=内部服务器错误,状态=500)。创建名为“index”的bean时出错:调用init方法失败;嵌套异常为java.lang.ClassCastException:java.util.LinkedHashMap不能强制转换为com.xxx.Applic

  • 我有一个带有POST REST API的SpringBoot2.2 webservice。我正在使用Okhttp客户机向第三方服务发出请求。我希望将第三方服务的确切响应返回给我的WebService的调用者。所有okhttp食谱都参考: 我尝试在api中返回okhttp响应,但我只返回调用方示例: 有人知道如何将Okhttp响应对象转换为Spring ResponseEntity对象以便返回htt

  • 我可以使用现在已弃用的方法将WebClient响应转换为响应实体。 请建议实现相同结果的其他方法。下面是我的代码。

  • 有人能帮助我为什么过渡没有得到应用吗? HTML 萨斯 我在这里有一个工作代码:https://codepen.io/loganlee/pen/rwnjpdz?editors=1100 我希望.box__faces-front和.box__faces-back的rotateY转换都要转换,并且我将转换放在父元素上,在本例中是.box__faces。 多谢了。

  • 我有一个场景,我需要执行一系列流程,每个步骤都在独立的应用程序中完成和扩展。我正在为所有交换使用主题交换。当前拓扑如下所示: P- 我们正在“版本化”队列,以处理可能影响消息结构的需求更改。绑定可能如下所示: 步骤1。exchange绑定到步骤1。v1。使用绑定键step1排队。v1 步骤1。exchange绑定到步骤1。v2。使用绑定键step1排队。v2级 还有其他与版本无关的绑定模式也使局部

  • 问题内容: 这是我的问题:鉴于这些课程 此代码编译: 并且这不: 是什么赋予了? 更新: 此代码可在Java 8中编译。显然是由于“改进的类型推断”。 问题答案: 在第一个示例中,调用的推断类型为,显然可以将其分配给相同类型的变量。 在第二个示例中,右侧的类型为。虽然 是 分配给, 不 分配给。它可以分配给。 其原因与a 不可分配给的原因相同。如果是这样,它将使以下(非类型安全的)代码成为可能: