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

Spring WebFlux中HttpMessageConverter的等价组件是什么?——MVC迁移WebFlux遇406错误问询

Spring WebFlux中HttpMessageConverter的等价组件及解决方案

在Spring WebFlux的响应式模型里,替代Spring MVC中HttpMessageConverter的是**HttpMessageReader和HttpMessageWriter**这一对组件。和MVC里既负责请求读取又负责响应写入的HttpMessageConverter不同,WebFlux把这两个职责拆分成了独立的接口:HttpMessageReader专门处理请求体的解析,HttpMessageWriter负责响应体的序列化,完美适配异步非阻塞的编程模型。

你遇到的HTTP 406错误,本质是WebFlux默认的消息读写器列表里没有你之前自定义的、针对text/plain和text/csv的错误对象转换逻辑,导致框架找不到合适的转换器来处理响应,因此返回了"Not Acceptable"的状态码。

下面针对你的场景(错误对象转文本/CSV格式),给出具体的实现和配置方案:


1. 自定义HttpMessageWriter处理响应转换

因为你需要的是把错误对象转换成text/plain或text/csv格式的响应,所以重点实现HttpMessageWriter接口即可:

第一步:实现自定义Writer

import org.springframework.core.ResolvableType;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import reactor.core.publisher.Mono;
import java.util.List;

public class ErrorObjectHttpMessageWriter implements HttpMessageWriter<YourErrorObject> {

    @Override
    public boolean canWrite(ResolvableType elementType, MediaType mediaType) {
        // 校验是否是目标错误对象类型,且支持指定的媒体类型
        return YourErrorObject.class.isAssignableFrom(elementType.resolve())
                && (MediaType.TEXT_PLAIN.isCompatibleWith(mediaType) 
                    || MediaType.parseMediaType("text/csv").isCompatibleWith(mediaType));
    }

    @Override
    public Mono<Void> write(Publisher<? extends YourErrorObject> inputStream, 
                           ResolvableType elementType, 
                           MediaType mediaType, 
                           ServerHttpRequest request, 
                           ServerHttpResponse response) {
        // 处理错误对象到文本/CSV的转换逻辑
        return inputStream.next()
                .map(errorObj -> {
                    if (MediaType.TEXT_PLAIN.isCompatibleWith(mediaType)) {
                        return errorObj.toPlainText(); // 假设你的错误对象有生成纯文本的方法
                    } else {
                        return errorObj.toCsvString(); // 生成CSV格式字符串的方法
                    }
                })
                .flatMap(formattedText -> {
                    response.getHeaders().setContentType(mediaType);
                    return response.writeWith(Mono.just(response.bufferFactory().wrap(formattedText.getBytes())));
                });
    }

    @Override
    public List<MediaType> getWritableMediaTypes() {
        // 声明该Writer支持的媒体类型
        return List.of(MediaType.TEXT_PLAIN, MediaType.parseMediaType("text/csv"));
    }
}

第二步:注册到WebFlux配置

通过WebFluxConfigurer把自定义Writer加入到框架的codec列表中:

import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.config.WebFluxConfigurer;

@Configuration
public class WebFluxCustomCodecConfig implements WebFluxConfigurer {

    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        // 注册自定义的错误对象Writer
        configurer.customCodecs().register(new ErrorObjectHttpMessageWriter());
        // 如果需要让自定义Writer优先被选中,可以调整顺序
        // configurer.customCodecs().order(0);
    }
}

2. 结合全局异常处理直接指定响应格式

如果你的错误对象是在全局异常处理器中返回的,也可以直接在异常处理方法里手动指定媒体类型和转换逻辑,不需要单独实现Writer:

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

@RestControllerAdvice
public class GlobalErrorHandler {

    @ExceptionHandler(YourBusinessException.class)
    public Mono<ServerResponse> handleBusinessException(YourBusinessException ex) {
        YourErrorObject errorObj = new YourErrorObject(ex.getErrorCode(), ex.getMessage());
        
        // 根据请求的Accept头动态返回格式,或者手动指定
        return ServerResponse.status(ex.getHttpStatus())
                .contentType(MediaType.TEXT_PLAIN) // 换成text/csv即可返回CSV格式
                .bodyValue(errorObj.toPlainText());
    }
}

补充说明

和MVC的HttpMessageConverter相比,WebFlux的HttpMessageReader/HttpMessageWriter是完全基于响应式流设计的,所有处理逻辑都返回Mono或Flux,适配异步非阻塞的场景。如果你的原有转换器同时处理请求和响应,那需要分别实现HttpMessageReader和HttpMessageWriter;但针对你的场景,只需要处理响应转换,所以HttpMessageWriter就足够了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 21:24:05