如何在Spring WebFlux过滤器中读取request body的multipart/form-data内容?
处理multipart/form-data请求体解析(基于DefaultPartHttpMessageReader)
核心逻辑
DefaultPartHttpMessageReader是Spring Web体系中专门用于解析multipart/form-data类型请求的工具类,它能将请求体拆解为Part对象流,支持分别处理表单字段和上传文件。
具体实现步骤
1. 初始化读取器
在过滤器或业务处理类中,直接实例化该类即可:
private final DefaultPartHttpMessageReader partReader = new DefaultPartHttpMessageReader();
2. 包装请求并解析
由于原生HttpServletRequest的请求体只能读取一次,需要先将其包装为ContentCachingRequestWrapper保留请求体内容,再适配为Spring的ServerHttpRequest后交给读取器解析:
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; // 先判断请求类型,非multipart直接放行 if (!httpRequest.getContentType().startsWith(MediaType.MULTIPART_FORM_DATA_VALUE)) { chain.doFilter(request, response); return; } // 包装请求,保证请求体可重复读取 ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(httpRequest); ServerHttpRequest serverHttpRequest = new ServletServerHttpRequest(wrappedRequest); // 解析请求体为Part对象流 Flux<Part> partsFlux = partReader.read(null, serverHttpRequest, Collections.emptyMap()); // 逐个处理Part partsFlux.subscribe(part -> { // 处理普通表单字段 if (part instanceof FormFieldPart formField) { String fieldName = formField.getName(); String fieldValue = formField.getValue(); // 此处添加你的过滤逻辑,比如字段内容校验 System.out.println("表单字段:" + fieldName + " = " + fieldValue); } // 处理上传文件 else if (part instanceof FilePart filePart) { String fileName = filePart.filename(); // 可通过filePart.content()获取文件数据流,做文件类型、内容过滤 System.out.println("上传文件:" + fileName); } }); // 继续执行后续过滤器链 chain.doFilter(wrappedRequest, response); }
3. 关键注意事项
- 必须先校验请求的
Content-Type,避免非multipart请求触发解析异常 - 若使用Spring WebFlux控制器,可直接用
@RequestPart注解自动解析Part,但过滤器场景需手动用DefaultPartHttpMessageReader处理 - 务必使用
ContentCachingRequestWrapper包装请求,否则请求体被读取后,后续控制器将无法获取内容
内容的提问来源于stack exchange,提问作者programmer
相关产品推荐
相关产品推荐

