Search code examples
javaspringrestrestlet

RESTful Api - Spring MediaType vs Restlet MediaType


I have an REST client:

import org.restlet.representation.ObjectRepresentation;
import org.restlet.data.MediaType;

ObjectRepresentation<ApprovalResponse> objectRepresentation = (ObjectRepresentation<ApprovalResponse>) cr.post(approvalRequest, MediaType.APPLICATION_JAVA_OBJECT);

And a Spring Boot Service RESTful api:

import org.springframework.http.MediaType;

@PostMapping(value = "/rest/approvals-submit")
public @ResponseBody ApprovalResponse submit(@RequestHeader(name="Authorization") String token, @RequestBody ApprovalRequest approvalRequest) {
    System.out.println("jwt token: "+token);
    System.out.println(approvalRequest.getMessageToEvaluator());
    ApprovalResponse approvalResponse = new ApprovalResponse();
    approvalResponse.setApprovalId("Test approvalResponse from micro service");
    return approvalResponse;
}

The client calls the API successfully. i.e. the System.out.println(approvalRequest.getMessageToEvaluator()); is printed out successfully.

Problem

My issue is that the response object is not getting back to the REST client.

Error Messages

Rest client

org.restlet.resource.ResourceException: Not Acceptable (406) - The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request

Server/Api

Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]

Question

So I think these errors are because the MediaTypes are not defined correctly. Do you know what they should be defined as?


Solution

  • Update after having a direct chat

    We added on the rest endpoint, on the postMapping annotation the following:

    @PostMapping(value = "/rest/approvals-submit")
    public @ResponseBody ApprovalResponse submit(@RequestHeader(name="Authorization") String token, @RequestBody ApprovalRequest approvalRequest, produces={MediaType.APPLICATION_JSON_VALUE,
    MediaType.APPLICATION_XML_VALUE},consumes = MediaType.APPLICATION_JSON_VALUE) {
        System.out.println("jwt token: "+token);
        System.out.println(approvalRequest.getMessageToEvaluator());
        ApprovalResponse approvalResponse = new ApprovalResponse();
        approvalResponse.setApprovalId("Test approvalResponse from micro service");
        return approvalResponse;
    }
    

    This added on the @PostMapping annotation produces={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE},consumes = MediaType.APPLICATION_JSON_VALUE.

    On client side, we change the response type to Representation, and we were able to get the json response:

    ClientResource cr = new ClientResource(endpointUrl);
    ChallengeResponse challengeResponse = new ChallengeResponse(ChallengeScheme.HTTP_OAUTH_BEARER);
    challengeResponse.setRawValue(token);
    cr.setChallengeResponse(challengeResponse);
    
    Request req = cr.getRequest();
    
    Representation representation = cr.post(approvalRequest);
    System.out.println(representation.getText());
    

    Finally, using Jackson Object Mapper the response could be mapped into the Approval response object:

        // now convert the response to java
        ObjectMapper objectMapper = new ObjectMapper();
        ApprovalResponse approvalResponse = objectMapper.readValue(json, ApprovalResponse.class);
        System.out.println(approvalResponse);
        System.out.println(approvalResponse.getApprovalId());
    

    It was a content negotiation issue. The content negotiation it's done via the Content-Type header, for better understanding of it, you could read this blog entry