openfeign of pit diary

Posted by zilem on Tue, 08 Feb 2022 10:23:57 +0100

   I feel like I haven't written an article for a long time. Ha ha, ha ha, a pit I stepped on yesterday afternoon has been solved this morning. I'm very happy, but I'm happy and clearly aware of my shortcomings, that is, when I encounter a bug I rarely encounter or even haven't encountered before, it's difficult to quickly locate and solve it. So from today on, I will open a special topic to record my mining experience.
Let's briefly describe my scene simulation:
  I have opened five services: two Eureka service registries (one cluster), two service providers (one cluster), and one consumer. Two of the payment providers are registered in the service registry.
And what I stepped on was this pit:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception 
[Request processing failed; nested exception is feign.codec.DecodeException: 
Error while extracting response for type [com.hua.springcloud.entities.CommonResult<com.hua.springcloud.entities.Payment>]
 and content type [application/json]; 
 nested exception is org.springframework.http.converter.HttpMessageNotReadableException: 
 JSON parse error: Cannot construct instance of `com.hua.springcloud.entities.Payment` 
 (although at least one Creator exists): no String-argument constructor/factory method 
 to deserialize from String value ('8002Payment(id=1, serial=Xiaohua)'); 
 nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException:
  Cannot construct instance of `com.hua.springcloud.entities.Payment` 
  (although at least one Creator exists): no String-argument constructor/factory method 
  to deserialize from String value ('8002Payment(id=1, serial=Xiaohua)')
 at [Source: (PushbackInputStream); line: 1, column: 92] 
 (through reference chain: com.hua.springcloud.entities.CommonResult["data"])] with root cause

In fact, after solving the problem, the truth is quite simple. Let's take a brief look at some of my codes:
Consumer:

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService
{
    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);

}
@RestController
public class OrderFeignController
{
    @Resource
    private PaymentFeignService paymentFeignService;
    @GetMapping(value = "/consumer/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id)
    {
        return paymentFeignService.getPaymentById(id);
    }
}

Service provider:

@RestController
public class PaymentController {
    @Resource
    private PaymentService paymentService;
    @Value("${server.port}")
    private String serverPort;//Get service port dynamically
    @Resource  //Automatic injection
    private DiscoveryClient discoveryClient;
    @GetMapping("/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);
        log.info("*****Query results:"+payment);
        if(payment!=null){
            return new CommonResult(200,"query was successful,serverPort:",serverPort+payment);
        }else {
            return new CommonResult(444,"No corresponding record, query ID: "+id,null);
        }
    }
}

Here, I believe that leaders with experience in the development of micro services should have seen the problem long ago. In fact, the problem lies in:
   the return value of the interface provided by the service provider is tired because it does not specify the CommonResult of the specific generic object, but the type I use to receive at the consumer side specifies the generic object CommonResult < payment >. Because the previous one does not specify the specific generic object type, the other one has a specification, which is inconsistent, resulting in its serialization The data obtained from the conversion between json and objects is different. Therefore, when the consumer wants to receive data, it is reported that it cannot find the specific corresponding structure to construct the object of the data, thus exposing this error. The simple solution is to remove the specific generics on the consumer side
   in the process of microservice development, it is particularly important to design efficient solutions for specific application scenarios. At the same time, the consistency of data transmission and data reception of the interface is also very critical and basic.

Topics: Exception