0

Any Help please !!

I receive this error when I'm calling my endpoint which call Feign in the background :

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of 
`org.springframework.http.ResponseEntity` (no Creators, like default constructor, exist): cannot deserialize 
from Object value (no delegate- or property-based Creator)
 at [Source: (BufferedReader); line: 1, column: 2]

This is my endpoint inside Controller :

@RestController
@RequestMapping(Routes.URI_PREFIX)
public class CartoController {

@Autowired
private ReadCartographyApiDelegate readCartographyApiDelegate;

@GetMapping(value = "/cartographies/{uid}", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseWrapper<ReadCartographyResponse> readCarto(HttpServletRequest request,
                                            @PathVariable(name = "uid") String uid) {
   ResponseEntity<ReadCartographyResponse> result ;
   try {
      result = readCartographyApiDelegate.readCartography(uid);
   }catch (Exception e){
      throw new TechnicalException("Error during read Carto");
   }
   return responseWrapperWithIdBuilder.of(result.getBody());
   }
 }

Interface ReadCartographyApiDelegate generated automatically by openApi from yaml file :

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "...")
public interface ReadCartographyApiDelegate {

    default Optional<NativeWebRequest> getRequest() {
        return Optional.empty();
    }
    default ResponseEntity<ReadCartographyResponse> readCartography(String uid) {
        getRequest().ifPresent(request -> {
            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
                    String exampleString = "null";
                    ApiUtil.setExampleResponse(request, "application/json", exampleString);
                    break;
                }
            }
        });
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);

    }

}

This my ReadCartoApiDelegateImpl which implements ReadCartographyApiDelegate interface :

@Service
public class ReadCartographyApiDelegateImpl implements ReadCartographyApiDelegate {

    private EcomGtmClient ecomGtmClient;

    public ReadCartographyApiDelegateImpl(EcomGtmClient ecomGtmClient) {
        this.ecomGtmClient = ecomGtmClient;
    }

    @Override
    public ResponseEntity<ReadCartographyResponse> readCartography(String uid) {
        ResponseEntity<ReadCartographyResponse> response = ecomGtmClient.readCartography(uid);
        return response;
    }
}

This is the feign client :

@FeignClient(name = "ecomGtmSvc", url = "http://localhost/")
public interface EcomGtmClient {
    @GetMapping(value = "/read-carto/{uid}")
    ResponseEntity<ReadCartographyResponse> readCartography(@PathVariable("uid") String uid);
}

The problem is that ResponseEntity (spring class) class doesn't contain default constructor which is needed during creating of instance. is there Any config to resolve this issue ?

M4R1KU
  • 710
  • 7
  • 22

2 Answers2

1

The Response Output was the correct Object that I have to put, cause every time I need to check the status from my feign client endpoint to do différent logic

@FeignClient(name = "ecomGtmSvc", url = "http://localhost/")
public interface EcomGtmClient {
    @GetMapping(value = "/read-carto/{uid}")
    ReadCartographyResponse readCartography(@PathVariable("uid") String uid);
}
0

If you want access to the body or headers on feign responses, you should use the feign.Response class. ResponseEntity does not work with feign because it is not meant to. I think it is best if you just return Response from your feign client method. You should then be able to pass the body to the ResponseEntity instance in the Controller.

What is your reason to even use the response-wrapper, i can't really figure that out from your code?

Sadly I couldn't find any documentation on the Response class, but here's the link to the source on GitHub. https://github.com/OpenFeign/feign/blob/master/core/src/main/java/feign/Response.java

My Suggestion would be

@FeignClient(name = "ecomGtmSvc", url = "http://localhost/")
public interface EcomGtmClient {
    @GetMapping(value = "/read-carto/{uid}")
    ReadCartographyResponse readCartography(@PathVariable("uid") String uid);
}
@RestController
@RequestMapping(Routes.URI_PREFIX)
public class CartoController {

@Autowired
private ReadCartographyApiDelegate readCartographyApiDelegate;

@GetMapping(value = "/cartographies/{uid}", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseWrapper<ReadCartographyResponse> readCarto(HttpServletRequest request,
                                            @PathVariable(name = "uid") String uid) {
   ReadCartographyResponse result ;
   try {
      result = readCartographyApiDelegate.readCartography(uid);
   }catch (Exception e){
      throw new TechnicalException("Error during read Carto");
   }
   // I don't know where you get the builder from, so I assume it does something import and is needed
   return responseWrapperWithIdBuilder.of(result);
   }
 }

Of course you'd also have to change all intermediate classes.

M4R1KU
  • 710
  • 7
  • 22
  • Ok thank you so much, that is work without generic just Response (try to update your answer). But another error was appeared : Can't cast the body of Response to my custom class ReadCartographyResponse. Any idea to resolve that ? – Wijdane KHATTAT Oct 26 '22 at 16:25
  • Thanks for the edit. Response of feign is of course non-generic and you also cannot cast it to your custom class, because they are not in the same inheritance tree. For clarification, the Response class is only used, when you need to access the body through an input stream, or you want to read it with a reader or you want access to headers or other http related stuff. Since you do none of that, I would suggest you just use your ReadCartographyResponse as a return value and you then pass it to the response entity or directly return it in the controller. – M4R1KU Oct 26 '22 at 16:33
  • For my case, I think Response is the correct Output that I have to put, cause every time I need to check the status from my feign client endpoint to do différents logic – Wijdane KHATTAT Oct 31 '22 at 16:13