0

I'm trying to consume a RESTful Web Service with Spring and my reference code is the one in this guide. The service that I'm interrogating returns JSON like the following:

{ "id": 1,
  "content": [
    { "dependencies": [
      { "parent": 0, "child": 1, "type": "PUNCT" },
      { "parent": 0, "child": 2, "type": "NPADVMOD" },
      { "parent": 0, "child": 3, "type": "PUNCT" } ], 
      "tokens": [
      { "ent": "", "index": 0, "lemma": "hello", "pos": "INTJ", "tag": "UH", "text": "Hello" },
      { "ent": "", "index": 1, "lemma": ",", "pos": "PUNCT", "tag": ",", "text": "," },
      { "ent": "PERSON", "index": 2, "lemma": "world", "pos": "PROPN", "tag": "NNP", "text": "World" },
      { "ent": "", "index": 3, "lemma": "!", "pos": "PUNCT", "tag": ".", "text": "!" } ]
    } ]
}

I have created the following objects (all their methods are omitted for brevity):

@JsonIgnoreProperties(ignoreUnknown = true)
public class Token {
    private String ent;
    private int index;
    private String lemma;
    private String pos;
    private String tag;
    private String text;
}

@JsonIgnoreProperties(ignoreUnknown = true)
public class Dependency {
    private int parent;
    private String type;
    private int child;
}

@JsonIgnoreProperties(ignoreUnknown = true)
public class Content {
    private List<Token> tokens;
    private List<Dependency> dependencies;
}

@JsonIgnoreProperties(ignoreUnknown = true)
public class Message {
    private long id;
    private List<Content> content;
}

With the following code, I can successfully deserialise a Message object:

@RequestMapping("/message")
public String message() {
    return "{\"content\": [{\"dependencies\": [{\"child\": 1,\"type\": \"PUNCT\",\"parent\": 0},{\"child\": 2,\"type\": \"NPADVMOD\",\"parent\": 0},{\"child\": 3,\"type\": \"PUNCT\",\"parent\": 0}],\"tokens\": [{\"index\": 0,\"text\": \"Hello\",\"tag\": \"UH\",\"lemma\": \"hello\",\"pos\": \"INTJ\",\"ent\": \"\"},{\"index\": 1,\"text\": \",\",\"tag\": \",\",\"lemma\": \",\",\"pos\": \"PUNCT\",\"ent\": \"\"},{\"index\": 2,\"text\": \"World\",\"tag\": \"NNP\",\"lemma\": \"world\",\"pos\": \"PROPN\",\"ent\": \"PERSON\"},{\"index\": 3,\"text\": \"!\",\"tag\": \".\",\"lemma\": \"!\",\"pos\": \"PUNCT\",\"ent\": \"\"}]}],\"id\": 1}";
}

@RequestMapping("/decode")
public Boolean decode() {
    RestTemplate restTemplate = new RestTemplate();

    Message response = restTemplate.getForObject("http://localhost:8080/message", Message.class);
    logger.info("I got: {}", response);

    return Boolean.TRUE;
}

as I can see in the log:

17:26:34.609 [qtp990226843-17] INFO a.c.j.controllers.ExampleController - Message[content = [Content[dependencies = [Dependency[child = 1, parent = 0, type = PUNCT], Dependency[child = 2, parent = 0, type = NPADVMOD], Dependency[child = 3, parent = 0, type = PUNCT]], tokens = [Token[ent = , index = 0, lemma = hello, pos = INTJ, tag = UH, text = Hello], Token[ent = , index = 1, lemma = ,, pos = PUNCT, tag = ,, text = ,], Token[ent = PERSON, index = 2, lemma = world, pos = PROPN, tag = NNP, text = World], Token[ent = , index = 3, lemma = !, pos = PUNCT, tag = ., text = !]]]], id = 1]

If I try to connect directly to the RESTful Web Service with the following code:

@RequestMapping("/remote")
public Boolean remote() {
    RestTemplate restTemplate = new RestTemplate();

    Map<String, String> env = System.getenv();
    String host = env.getOrDefault("MY_HOST", "localhost");
    String port = env.getOrDefault("MY_HOST", "7890");
    String url = String.format("http://%s:%s", host, port);

    String content = "Hello, World!";

    URI uri = UriComponentsBuilder.fromHttpUrl(url).queryParam("content", content).build().encode().toUri();
    Message response = REST_TEMPLATE.getForObject(uri, Message.class);
    logger.info("I got: {}", response);

    return Boolean.TRUE;
}

I observe the following error:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Jun 02 16:53:42 BST 2017
There was an unexpected error (type=Internal Server Error, status=500).
org.springframework.web.util.NestedServletException: Request processing failed; 
nested exception is org.springframework.web.client.RestClientException: 
Could not extract response: no suitable HttpMessageConverter found for response 
type [class ai.context_scout.joshi.model.Message] and content type 
[text/plain;charset=utf-8]

I search online and in this site to find a solution, but I couldn't think of any keyword that led to meaningful results... any help?

Why I get this error? How to fix it?

Thanks!

PS: I just tried to implement a dumb service that connects to the remote service and returns the JSON received by that service as a String, and I modified the decode service that was already able to deserialise the JSON to get the data from the dumb service rather than the remote service and it works! I'm flabbergasted! It doesn't make sense! Anyway, for reference, the code is as follows (please let me know if it is possible to avoid to use the dumb service):

@RequestMapping("/dumb")
public String dumb() {
    Map<String, String> env = System.getenv();
    String host = env.getOrDefault("SPACY_HOST", "localhost");
    String port = env.getOrDefault("SPACY_HOST", "7890");
    String url = String.format("http://%s:%s", host, port);

    String content = "Hello, World!";

    URI uri = UriComponentsBuilder.fromHttpUrl(url).queryParam("content", content).build().encode().toUri();

    RestTemplate restTemplate = new RestTemplate();

    String response = restTemplate.getForObject(uri, String.class);
    logger.info("I got: {}", response);

    return response;
}

@RequestMapping("/decode")
public Boolean decode() {
    RestTemplate restTemplate = new RestTemplate();

    Message response = restTemplate.getForObject("http://localhost:8080/dumb", Message.class);
    logger.info("I got: {}", response);

    return Boolean.TRUE;
}
Stefano Bragaglia
  • 622
  • 1
  • 8
  • 25
  • Inject a RestTemplate to your controller, do not create it for every request. The problem is that you have no registered message converters in your instance of RestTemplate. – Rafal G. Jun 02 '17 at 18:12
  • Can you please provide some code? I tried to extend the example without success... Thank you! – Stefano Bragaglia Jun 02 '17 at 20:27

0 Answers0