互换的青春
您需要检查您的 MessageConverters 以确保 StringMessageConverter 在 MappingJackson2HttpMessageConverter 之前。否则,将选择 JSON MessageConverter 来序列化字符串并添加额外的双引号。@Componentpublic class MyWebMvcConfigurer implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // check converter order here }}如以下spring源码,流程为:选择消息转换器在 ResponseBodyAdvice 中调用 beforeBodyWrite 方法转换消息AbstractMessageConverterMethodProcessor.java// choose a message converterif (genericConverter != null ? ((GenericHttpMessageConverter) converter).canWrite(targetType, valueType, selectedMediaType) : converter.canWrite(valueType, selectedMediaType)) { // invoke beforeBodyWrite body = getAdvice().beforeBodyWrite(body, returnType, selectedMediaType, (Class<? extends HttpMessageConverter<?>>) converter.getClass(), inputMessage, outputMessage); if (body != null) { Object theBody = body; LogFormatUtils.traceDebug(logger, traceOn -> "Writing [" + LogFormatUtils.formatValue(theBody, !traceOn) + "]"); addContentDispositionHeader(inputMessage, outputMessage); if (genericConverter != null) { genericConverter.write(body, targetType, selectedMediaType, outputMessage); } else { // convert message ((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage); } }事实是我们无法更改 ResponseBodyAdvice 中的 MessageConverter。但我们可以自定义一个Dynamic MessageConverter。例如:public class DynamicMessageConverter implements HttpMessageConverter<Object> { private final HttpMessageConverter<Object> jsonConverter; private final HttpMessageConverter<String> stringConverter; public DynamicMessageConverter(HttpMessageConverter<Object> jsonConverter, HttpMessageConverter<String> stringConverter) { this.jsonConverter = jsonConverter; this.stringConverter = stringConverter; } @Override public boolean canWrite(Class clazz, MediaType mediaType) { return jsonConverter.canWrite(clazz, mediaType) || stringConverter.canWrite(clazz, mediaType); } @Override public List<MediaType> getSupportedMediaTypes() { List<MediaType> jsonMediaTypes = jsonConverter.getSupportedMediaTypes(); List<MediaType> stringMediaTypes = stringConverter.getSupportedMediaTypes(); List<MediaType> all = new ArrayList<>(); all.addAll(jsonMediaTypes); all.addAll(stringMediaTypes); return all; } @Override public void write(Object o, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { if (o instanceof String) { stringConverter.write((String) o, contentType, outputMessage); } else { jsonConverter.write(o, contentType, outputMessage); } } @Override public boolean canRead(Class clazz, MediaType mediaType) { return false; } @Override public Object read(Class clazz, HttpInputMessage inputMessage) throws HttpMessageNotReadableException { throw new UnsupportedOperationException(); }}然后启用它 @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(); DynamicMessageConverter dynamicMessageConverter = new DynamicMessageConverter(jsonConverter, stringConverter); converters.add(0, dynamicMessageConverter); }直接通过response来写似乎更简洁。 @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { response.getHeaders().set("content-type", "text/plain;charset=UTF-8"); //some codes.. String result = "hello"; try (OutputStream stream = response.getBody()) { stream.write(result.getBytes("utf-8")); stream.flush(); } catch (IOException e) { // log ex } return null; }