0

I'm consuming a REST service, that returns a JSON formatted string, but in the header gives the content-type "text/string". I tried to go to the source of the problem, but the code seems to no longer be maintained. If there is no better solution, I need to fork the spaCy Rest Services project and put it in a container of some sort myself...

I have tried all of these solutions already, but the methods used are either deprecated or the solutions don't work for some other reason:

Spring reactive WebClient GET json response with Content-Type "text/plain;charset=UTF-8"

Reactive WebClient GET Request with text/html response

The exception I receive is always: org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'text/string' not supported

My code is this:

public class SpacyClient {

    WebClient webClient;

    public SpacyClient() {
        webClient = WebClient.builder()
                .baseUrl("http://localhost:8081")
                .build();
    }

    public List<NamedEntity> spacyNamedEntities(String text) {

        HashMap<String, String> requestBody = new HashMap<>();
        requestBody.put("text", text);
        requestBody.put("model", "en_core_web_lg");

        Mono<List<NamedEntity>> responseMono = webClient.post()
                .uri("/ent")
                .accept(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(requestBody))
                .exchangeToMono( response -> {
                   Mono<List<NamedEntity>>  = response.bodyToMono(new ParameterizedTypeReference<List<NamedEntity>>() {});
                   return lalala;
                });
        List<NamedEntity> entities = responseMono.block();
        return entities;

    }

}
Chris
  • 834
  • 1
  • 10
  • 23

2 Answers2

4

You can register a specific decoder for a custom Mime type on your WebClient instance by using the ClientCodecConfigurer.

        WebClient webClient = WebClient.builder()
                .baseUrl("http://localhost:8090")
                .codecs(clientCodecConfigurer -> clientCodecConfigurer.customCodecs()
                        .register(new Jackson2JsonDecoder(new ObjectMapper(), new MimeType("text", "string"))))
                .build();

Further details on both the client and server codecs provided by spring can be found in the reference documentation

Michael McFadyen
  • 2,675
  • 11
  • 25
0

Here's the workaround I did, just deserializing the string explicitly using Jackson. It's not pretty, but it does work.

    public List<NamedEntity> spacyNamedEntities(String text) {

        HashMap<String, String> requestBody = new HashMap<>();
        requestBody.put("text", text);
        requestBody.put("model", "en_core_web_lg");

        Mono<String> responseMono = webClient.post()
                .uri("/ent")
                .body(BodyInserters.fromValue(requestBody))
                .retrieve()
                .bodyToMono(String.class);
        String json = responseMono.block();

        ObjectMapper objectMapper = new ObjectMapper();

        List<NamedEntity> entities = new ArrayList<>();
        try {
            entities = objectMapper.readerForListOf(NamedEntity.class).readValue(json);
        } catch (JsonProcessingException e) {
            // ToDo: show information in frontend
        }

        return entities;

    }
Chris
  • 834
  • 1
  • 10
  • 23