question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Malformed api-docs JSON when custom HttpMessageConverter is used

See original GitHub issue

When custom HttpMessageConverter is used malformed api-docs endpoint produces malformed JSON

Steps to reproduce the behavior:

  • spring-boot version 2.2.6.RELEASE
  • springdoc-openapi 1.3.5-SNAPSHOT
  • the actual result is a JSON String created from the String produced by org.springdoc.webmvc.api.OpenApiResource#openapiJson. The original response is wrapped with a leading and trailing double quote and all the double internal double quotes are escaped: "{\"openapi\":\"3.0.1\",\"info\":{\"title\":\"OpenAPI definition\",\"version\":\"v0\"},\"servers\":[{\"url\":\"http://localhost:8080\",\"description\":\"Generated server url\"}],\"paths\":{\"/get\":{\"get\":{\"tags\":[\"controller\"],\"operationId\":\"getSomeMap\",\"responses\":{\"200\":{\"description\":\"default response\",\"content\":{\"*/*\":{\"schema\":{\"$ref\":\"#/components/schemas/ImmutableMultimapStringString\"}}}}}}}},\"components\":{\"schemas\":{\"ImmutableMultimapStringString\":{\"type\":\"object\",\"properties\":{\"empty\":{\"type\":\"boolean\"}}}}}}"
  • a sample application can be found in https://github.com/Geneea/springdoc-test

Expected behavior

  • I would expect that org.springdoc.webmvc.api.OpenApiResource#openapiJson should not do the conversion from OpenAPI to String. Just return OpenAPI or ResponseEntity<OpenAPI> and leave the serialization for the registered HttpMessageConverter.

Additional context An ugly fix for this problem is https://github.com/Geneea/springdoc-test/blob/master/src/main/java/com/geneea/springdoc/FixApiDocsWithFilter.java registering a Filter what corrects the malformed response.

Same problem is described in https://stackoverflow.com/questions/59393191/endpoint-api-docs-doesnt-work-with-custom-gsonhttpmessageconverter

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:21 (10 by maintainers)

github_iconTop GitHub Comments

15reactions
bnasslahsencommented, May 23, 2020

@sergio11,

You need to add StringHttpMessageConverter to your method configureMessageConverters, (StringHttpMessageConverter has to be the first one):

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    	converters.add(new StringHttpMessageConverter());
        converters.add(new MappingJackson2HttpMessageConverter(provideObjectMapper()));
        converters.add(new ByteArrayHttpMessageConverter());
    }

You can find attached, the working example from the source that you have provided.

spring_open_api_test-corrected.zip

4reactions
micwcommented, Oct 7, 2021

Hello, I wonder why this is closed. IMO, it actually is a bug:

The endpoint returns a ResponseEntity of type “String”. The client requests a application/json. So the string must correctly be a JSON string, meaning that it’s quoted accordingly.

Adding StringHttpMessageConverter (which is by default added with spring boot) changeds this behaviour in an inconsistent way: If the response entity is a string, it is returned as unquoted string (which is, in most cases, invalid json). Returning anything else will be encoded correctly as JSON. So StringHttpMessageConverter introduces buggy behaviour.

So for the following endpoint, the behaviour differs with pressence/absence of StringHttpMessageConverter:

@GetMapping(value = "/test1")
public ResponseEntity<String> test1() {
  return ResponseEntity.ok("Test1");
}

This will always produce text/json. With StringHttpMessageConverter enabled, the response will be an invalid JSON of Test1. Without StringHttpMessageConverter, it will produce a valid JSON if "Test1.

If an endpoint creates a String that is already JSON, It must not rely on that inconsistent behaviour to hopefully deliver this unquoted to the client. A valid implementation of auch an endpoint could look that like:

@GetMapping(value = "/test2", produces = "application/json")
public ResponseEntity<byte[]> test2() {
    return ResponseEntity.ok("Test2".getBytes(StandardCharset.UTF_8));
}

This endpoint will always return Test2, regardless of the pressence/absence of StringHttpMessageConverter.

Edit: it would even better to directly write the JSON directly to HttpServletResponse do de-couple the behaviour from specific message converters.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Understand and configure Spring JSON marshalling ...
With my current project configuration I can't get SpringDoc to return valid OpenAPI JSON when using a custom MappingJackson2HttpMessageConverter ...
Read more >
Understanding HttpMessageConverter in Spring
Http Message Converter is responsible for serializing Java Object to JSON/XML data representation and deserializing JSON/XML data representation ...
Read more >
Openapi Escapes Json Response In Spring Boot Application
When custom HttpMessageConverter is used malformed apidocs endpoint produces malformed JSON. Steps to reproduce the behavior: springboot version 2.2.6.
Read more >
Spring Cloud Data Flow Reference Guide
Spring Cloud Data Flow supports a range of data processing use cases, ... To see the list of REST endpoints, specify the application/json...
Read more >
Messages — Mailgun API documentation
t:variables, A valid JSON-encoded dictionary used as the input for template ... by an arbitrary name allows to attach a custom JSON data...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found