4

我有一个带有 spring boot 的项目,我想使用 swagger2 来记录我的 json web 服务。

我有这个配置:

@Configuration
@EnableSwagger2
public class Swagger2Config {

@Bean
public Docket welcomeMessageApi() {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .select()
            .apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.any())
            .build();
}

private ApiInfo apiInfo() {
    return new ApiInfoBuilder()
            .title("My API")
            .description("Lorem Ipsum is simply dummy text of ...")
            .termsOfServiceUrl("an url")
            .contact("contact")
            .license("")
            .licenseUrl("")
            .version("2.0")
            .build();
}

要阅读文档,我使用此链接:http://localhost:9081/v2/api-docs

在招摇的用户界面中,它工作正常。但是当我直接在浏览器中尝试这个链接时,我有这个错误: 在此处输入图像描述

使用 Firebug,我看到它接受 XML 内容而不是 JSON 内容。 在此处输入图像描述

如何修改招摇配置以接受 JSON 内容?

4

3 回答 3

3

您会遇到问题,因为 Spring MVC 默认让服务器在浏览器中呈现 XML 而不是 JSON。 官方文件说:

要让服务器呈现 XML 而不是 JSON,您可能必须发送 Accept: text/xml 标头(或使用浏览器)。

因此,您需要做的就是让服务器在浏览器中呈现 JSON。

当您深入浏览器中的请求时,您会看到请求标头:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

如果你调试到 spring boot 中,你会看到 spring mvc 将默认委托HttpMessageConvertersincludeMappingJackson2XmlHttpMessageConverterMappingJackson2HttpMessageConverter.

MappingJackson2HttpMessageConverter是渲染json,是MappingJackson2XmlHttpMessageConverter渲染xml。

它们都有一个字段supportedMediaTypes,表示支持哪些媒体类型。

supportedMediaTypesin的值为MappingJackson2HttpMessageConverter

在此处输入图像描述

supportedMediaTypesin的值为MappingJackson2XmlHttpMessageConverter

在此处输入图像描述

有一个 'text/xml;charset=UTF-8' 。MappingJackson2XmlHttpMessageConverter这就是为什么浏览器呈现 xml 的原因。

所以你需要添加一个MappingJackson2XmlHttpMessageConverter支持'text/xml'的自定义,例如:

    @Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        List<MediaType> list = new ArrayList<>();
        list.add(MediaType.APPLICATION_JSON_UTF8);
        list.add(new MediaType("text", "html", Charset.forName("UTF-8")));
        list.add(new MediaType("application", "*+json", Charset.forName("UTF-8")));
        converter.setSupportedMediaTypes(list);
        converters.add(converter);
    }
}

试试这个,浏览器将在浏览器中呈现 JSON 而不是 XML,一切正常!

于 2016-03-17T06:59:06.847 回答
0

当我尝试使用网络浏览器读取 Swagger API 时,我遇到了类似的问题。

我用不同的方法解决了它。
如果您尝试使用其他一些工具(例如 PostMan 或 Curl 命令工具)调用端点,它将正确返回 JSON。

看起来它只发生在网络浏览器中。

如果您在 pom.xml 中有 Jackson XML 扩展,您可以尝试这种方法。但如果您需要返回 XML 数据作为响应,请找出另一种解决方案。

这是我的方法,在 Configuration 下面添加将 WebMvcConfigurationSupport 类扩展到项目源代码。

@Configuration
public class MessageConverterConfiguration extends WebMvcConfigurationSupport {
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        HttpMessageConverter<?> target = null;

        for (HttpMessageConverter<?> converter : converters) { 
            if (converter.getClass() == MappingJackson2XmlHttpMessageConverter.class) {
                target = converter;
            }
        }

        if (target != null) {
            converters.remove(target);
        }
    }
}
  1. 对于常规的 GET 类型请求,Web 浏览器向端点发送请求数据,包括请求标头中的“Accept”键,其中包含“xml”值。

  2. 此外,在服务器端,即使响应数据类型是 JSON,即使指定了 JSON 消息转换器,如果它与 JSON 数据兼容,Spring 也会首先选择 XML 消息转换器。

  3. 最重要的是,选择过程基于请求中“接受”值的顺序。

    • 您可以在响应过程中调试 AbstractMessageConverterMethodProcessor,尤其是 writeWithMessageConverters 方法。
  4. 在选择过程中,Spring根据WebMvcConfigurationSupport在系统初始化过程中初始化的注册消息转换器列表,选择一个合适的转换器。

  5. WebMvcConfigurationSupport 提供了 extendMessageConverters 来扩展或修改转换器列表。

  6. 所以我试图从列表中删除那个特殊的 XML 消息转换器,它可以工作。

尽管上述解决方案对我有用,但您可能不会使用这种方法。

如果您需要返回 XML 数据作为响应,请找出另一种解决方案。

于 2020-02-11T20:45:01.530 回答
0

对我有用的是更新 springfox-swagger2 和 springfox-swagger-ui 的 Maven 依赖项。

对我来说最新的工作组合是:

    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.8.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>
于 2018-07-10T11:13:28.077 回答