MissingServletRequestPartException: Required request part ‘file’ is not present

问题复现

在使用SpringBoot3.2.0版本中使用文件上传一直出现错误:MissingServletRequestPartException: Required request part ‘file’ is not present,检查了接口配置和postman请求都没问题。最后发现是自己的请求封装器有问题

这是我的接口定义还有postman请求截图

    @PostMapping("/upload")
    @Operation(summary = "上传文件", description = "uploadFile")
    public Object upload(@RequestPart(name = "file") MultipartFile multipartFile) {
        return qnyFileService.directUpload(multipartFile);
    }

image-20231217233104870

原因分析

传统的json请求使用的是HttpServletRequest,但是文件上传使用的是MultipartHttpServletRequest

解决方案

在进行请求封装的过滤器里判断下,如果是文件上传请求则不做处理,否则使用我们自定义的请求封装器

public class RequestWrapperFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest newRequest=request;
        //如果不是文件上传请求则进行封装
        if(!StringUtils.startsWithIgnoreCase(request.getContentType(), "multipart/")){
            RequestWrapper requestWrapper=new RequestWrapper(request);
            newRequest=requestWrapper;
        }
        filterChain.doFilter(newRequest,response);
    }
}

自定义的封装器代码如下,主要是为了解决请求体不能多次获取的问题。结果就是这个让我吃了个大亏

public class RequestWrapper extends HttpServletRequestWrapper {

    /**
     * 保存流
     */
    private final byte[] requestBody;

    /**
     * Constructs a request object wrapping the given request.
     *
     * @param request The request to wrap
     * @throws IllegalArgumentException if the request is null
     */
    @SneakyThrows
    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        requestBody = StreamUtils.copyToByteArray(request.getInputStream());
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream basic = new ByteArrayInputStream(requestBody);

        return new ServletInputStream() {

            @Override
            public int read() {
                return basic.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {
                /*
                不需要使用读取监听
                 */
            }
        };
    }

    @Override
    public BufferedReader getReader(){
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
}
  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MissingServletRequestPartException: Required request part 'file' is not present是一个错误,它表示在请求中缺少了名为'file'的必需的参数。 这个错误通常在后端使用@RequestParam或@RequestBody注解来接收文件参数时出现。在前端的请求中必须确保文件上传的参数名与后端接收参数的注解中的参数名保持一致。例如,在前端使用formData.append('file',this.file.raw)来上传文件,则后端的@RequestParam或@RequestBody注解中的参数名应为'file'。 如果错误依然存在,可能是因为在前端的文件input标签中的name字段与后端注解中的参数名不一致导致的。请确保它们的命名一致。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [MissingServletRequestPartException: Required request part ‘file‘ is not present问题](https://blog.csdn.net/weixin_43862596/article/details/118926572)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [MissingServletRequestPartExceptionRequired request part ‘file‘ is not present上传文件报错](https://blog.csdn.net/HQXQ2874760112/article/details/124676049)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值