Spring Filter中将text/plain请求Content-Type改为multipart/form-data的问题
需求实现可行性
你的需求完全可以实现,当前方案缺少以下几处核心调整:
必要补充内容
- 重写请求包装类的请求头读取方法
Spring读取请求Content-Type本质是调用HttpServletRequest的getContentType()、getHeader()方法,你需要在CryptRequestWrapper中覆盖这两个方法,返回修改后的multipart/form-data值(注意必须携带对应boundary参数),示例如下:
@Override public String getContentType() { // 这里的boundary要和你后续构造multipart请求体时使用的分隔符完全一致 return "multipart/form-data; boundary=yourCustomBoundary"; } @Override public String getHeader(String name) { if ("Content-Type".equalsIgnoreCase(name)) { return getContentType(); } return super.getHeader(name); } // 若有调用getHeaderNames、getHeaders的场景,也需要对应覆盖,保证Content-Type的返回值正确
将解密后的内容封装为标准multipart/form-data格式
仅修改Content-Type头无法生效,你需要把解密后的明文内容,按照multipart格式规范构造为合法的请求体:包含和头信息对应的boundary分隔符、每个part的头声明、内容段、结束分隔符,再把构造好的byte数组传给CryptRequestWrapper。修正请求包装类的流方法实现
你当前ServletInputStream中的isFinished()、isReady()直接返回false会导致流读取异常,调整为:
@Override public boolean isFinished() { return decryptedDataBAIS.available() == 0; } @Override public boolean isReady() { return true; }
- 调整过滤器执行顺序
需要确保你的自定义CustomFilter执行优先级高于Spring自带的MultipartFilter,否则MultipartFilter会提前读取原始的text/plain请求,触发解析失败。如果是Spring Boot项目,可以通过@Order注解设置过滤器优先级,数值越小优先级越高,设置小于Ordered.HIGHEST_PRECEDENCE + 50(MultipartFilter默认优先级)即可。
额外注意事项
如果你的Controller接口使用@RequestParam、@RequestPart接收参数,要保证构造multipart请求体时的part名称和接口参数名称对应,否则会出现参数无法注入的问题。
内容的提问来源于stack exchange,提问作者Uri Ikart
相关产品推荐
相关产品推荐

