0

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?

Richard
  • 8,193
  • 28
  • 107
  • 228

1 Answers1

2

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

Damian229
  • 482
  • 5
  • 10
  • Thanks. Here is the ApprovalResponse (it has getters and setters): `@XmlAccessorType(XmlAccessType.FIELD) @XmlType( name = "ApprovalResponse", propOrder = {"approvalId"} ) public class ApprovalResponse implements Serializable { private static final long serialVersionUID = 1L; @XmlElement( required = true ) protected String approvalId; public ApprovalResponse() { } public String getApprovalId() { return this.approvalId; } public void setApprovalId(String value) { this.approvalId = value; } }`. – Richard Jun 25 '20 at 16:18
  • add add produces=MediaType.APPLICATION_XML_VALUE on your postMapping tag – Damian229 Jun 25 '20 at 16:26
  • I tried adding the MediaType, `produces=MediaType.APPLICATION_XML_VALUE` but still get: `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 `. – Richard Jun 25 '20 at 16:29
  • This seems to have helped, because I no longer get the error on the server `Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]`. But the client still has the same error. So the consumer cannot resolve the response. – Richard Jun 25 '20 at 16:32
  • On spring, there is a "Content-Type" Header sent by the client, which states the type of content it can process, so the endpoint you're developing should match the same content-type. What is the "Content-Type" header sent by the client? Knowing it, we could add it in the list of produces on PostMapping annotation. – Damian229 Jun 25 '20 at 16:43
  • If I change them both to `"application/xml"`, the client can call the server with no errors on the server. But the client has this error: `org.restlet.resource.ResourceException: Internal Server Error (500) - The server encountered an unexpected condition which prevented it from fulfilling the request` – Richard Jun 25 '20 at 16:49
  • just as a test, could you put on the client request the parameter at the end _?format=json_ ? – Damian229 Jun 25 '20 at 16:51
  • On the endpoint url? i.e. `http://localhost:8081/rest/approvals-submit?format=json`. If I do this, I still get the same error. – Richard Jun 25 '20 at 16:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/216661/discussion-between-damian229-and-richard). – Damian229 Jun 25 '20 at 16:54
  • the answer has been updated accordingly with our chat @Richard – Damian229 Jun 25 '20 at 19:58
  • do you know why I would get this: https://stackoverflow.com/questions/62597822/java-restful-client-cant-call-api-when-running-on-server – Richard Jun 26 '20 at 15:24
  • I was traveling, I will try it on Sunday! Is it ok? – Damian229 Jun 26 '20 at 20:59
  • Thank you. Appreciate your help – Richard Jun 26 '20 at 21:01