You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring MVC(非Spring Boot)项目:SpringDoc集成后String类型JSON响应格式异常的解决问询

我来帮你解决这个棘手的问题——你现在面临的核心矛盾是:为了让SpringDoc返回正确的OpenAPI JSON,不得不添加StringHttpMessageConverter,但这又破坏了业务接口返回String类型时的JSON格式(本该带双引号,现在变成纯文本)。下面给你几个可行的解决方案,按推荐程度排序:

方案一:自定义String转换器,仅处理SpringDoc的请求路径

这个方案最精准,既能保证SpringDoc的输出正常,又不影响业务接口。核心思路是让StringHttpMessageConverter只对SpringDoc的接口生效,其他请求的String类型响应交给Jackson转换器处理(Jackson会自动把String序列化为带双引号的合法JSON字符串)。

步骤如下:

  1. 创建一个自定义的StringHttpMessageConverter子类,重写canWrite方法,通过请求路径判断是否为SpringDoc的接口:
import org.springframework.http.HttpServletRequest;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class SpringDocStringHttpMessageConverter extends StringHttpMessageConverter {
    // 匹配SpringDoc的API文档路径,根据你的实际路径调整
    private static final String SPRINGDOC_API_PATH_PREFIX = "/v3/api-docs";

    @Override
    public boolean canWrite(Class<?> clazz, org.springframework.http.MediaType mediaType) {
        // 只有当请求是SpringDoc的接口,且返回类型是String时,才使用这个转换器
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            if (request.getRequestURI().startsWith(SPRINGDOC_API_PATH_PREFIX) && String.class.isAssignableFrom(clazz)) {
                return super.canWrite(clazz, mediaType);
            }
        }
        // 其他情况,交给后续的转换器处理
        return false;
    }
}
  1. 在你的WebConfig里替换原来的StringHttpMessageConverter为这个自定义版本:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    // 用自定义的String转换器替代默认的,仅处理SpringDoc请求
    converters.add(new SpringDocStringHttpMessageConverter());
    converters.add(jsonConverter());
    // 别忘了添加XML转换器
    converters.add(marshallingConverter());
}

这样一来:

  • 访问/v3/api-docs时,自定义转换器会直接输出SpringDoc返回的JSON字符串,得到正确的OpenAPI JSON结构;
  • 业务接口返回String时,因为自定义转换器的canWrite返回false,会交给Jackson转换器处理,Jackson会自动把String包裹成双引号,输出合法的JSON格式(比如返回"response-string"而不是response-string)。
方案二:升级SpringDoc版本,让它返回OpenAPI对象而非String

如果你使用的SpringDoc版本比较旧,可能存在返回String类型JSON的问题。新版本的SpringDoc(比如springdoc-openapi-webmvc-core的v1.6+)中,OpenApiResource的getOpenApi方法默认返回OpenAPI对象而非String,此时Jackson转换器可以直接将这个对象序列化为正确的JSON,完全不需要添加StringHttpMessageConverter。

升级后,你可以移除configureMessageConverters中的StringHttpMessageConverter,这样:

  • SpringDoc的OpenAPI对象会被Jackson直接序列化为合法的JSON;
  • 业务接口返回的String会被Jackson自动转成带双引号的JSON字符串,完美解决两个问题。
方案三:为业务接口的String返回做包装(应急方案)

如果上面的方案暂时无法实施,你可以临时为业务接口的String返回做包装:比如用ResponseEntity包裹,或者将String封装成一个简单的DTO对象。

比如:

@GetMapping("/your-string-api")
public ResponseEntity<String> getStringResponse() {
    String content = "response-string";
    // 手动将String转成JSON格式的字符串,或者让Jackson处理
    return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body("\"" + content + "\"");
}

不过这个方案需要修改所有相关接口,比较繁琐,只建议作为临时应急使用。

内容的提问来源于stack exchange,提问作者Pieter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 11:24:27