Java 如何从fileupload直接处理Inputstream

Java 如何从fileupload直接处理Inputstream,java,jakarta-ee,file-upload,servlet-3.0,Java,Jakarta Ee,File Upload,Servlet 3.0,我使用Spring3.2.5通过控制器处理文件上传。 多部分处理在web.xml中配置 这是密码 @RequestMapping(value = "/{id}", method = RequestMethod.POST) ResponseEntity<Content> uploadFile(final HttpServletRequest request, @PathVariable final String id) throws IOException, Servl

我使用Spring3.2.5通过控制器处理文件上传。 多部分处理在web.xml中配置

这是密码

@RequestMapping(value = "/{id}", method = RequestMethod.POST)
ResponseEntity<Content> uploadFile(final HttpServletRequest request, @PathVariable final String id)
        throws IOException, ServletException {
    for (final Part part : request.getParts()) {
        log.debug("Content-Type: {}", part.getContentType());
        for (final String key : part.getHeaderNames()) {
            log.debug("Header {}: {}", key, part.getHeader(key));
        }
        log.debug("Name: {}", part.getName());
        log.debug("Size: {}", part.getSize());
        final String fileName = getPartName(part);
        log.debug("File name: {}", fileName);

        final DataSource ds = new DataSource() {
            @Override
            public String getContentType() {
                String ct = ContentController.this.getContentType(part.getContentType(), null);
                if (ct == null) {
                    final Pattern p = Pattern.compile("^.+\\.(.+?)$");
                    final Matcher m = p.matcher(fileName);
                    if (m.matches()) {
                        ct = ContentController.this.getContentType(m.group(1), m.group(1));
                    }
                }
                return ct;
            }

            @Override
            public InputStream getInputStream() throws IOException {
                return part.getInputStream();
            }

            @Override
            public String getName() {
                return fileName;
            }

            @Override
            public OutputStream getOutputStream() throws IOException {
                return null;
            }
        };

        final Content content = service.storeFile(ds, id, part.getSize());
        if (content != null) {
            return new ResponseEntity<>(content, IE89PostWorkaround(request), HttpStatus.CREATED);
        }
    }
    return new ResponseEntity<>(new Content(), IE89PostWorkaround(request), HttpStatus.BAD_REQUEST);
}
我想知道为什么在上传整个文件之前,第一个log语句的断点没有达到? 看起来在开始处理之前,请求已被完全读取

是否有办法实现以下行为:

上传开始后,尽快从上传中获取文件信息 获取InputStream并将其通过系统路由到其目标,在此之前不会读取RAM或文件 您的循环调用request.getParts,它返回一个集合,因此需要在您进入循环的第一次迭代之前对浏览器输入进行完全解析。您所谓的文件上载实际上是一个HTTP请求,如下所示:

GET/fileUpload.do 内容类型:多部分/表单数据;边界=-极限 -极限 内容配置:表单数据;名称=描述 内容类型:文本/纯文本 这是文件的描述 -极限 内容配置:表单数据;名称=图像 内容类型:图像/png lksdf82203j1897239481231kadlqcdladaod82y3o98dqjdhdqkdh q9wrcfdhlqhfoqwfn92q38uycrnwehrnqolwhfrnoq83y018yn8cy2 oqwdfopiqweuroq338rquncqwurqwercqfjqwcngreydisajf238jd ... 要获得组成请求的部分的列表,框架必须首先解析整个请求,这可能需要一些时间,具体取决于文件大小和网络速度


您可以通过自己解析request.getInputStream返回的原始InputStream来加快速度,但目前我不知道有哪个库可以让您以流式方式处理多部分信封,比如说,XML文档的SAXAPI。此外,我不完全确定这将如何影响应用程序的可见性能。

我真的很想知道Java中没有事件驱动的文件上载处理。我们目前有Servlet版本3.1。没人要求过吗?在我看来,这似乎是处理真正大的文件或避免文件遭到DOS攻击的唯一方法,因为在拒绝文件之前,它完全由servlet框架处理……实际上这并不令人震惊。您可以设置请求大小的限制,而当事件API能够产生更好的性能时,这种情况并不常见。此外,DOS攻击与文件上传几乎没有关系
@RequestMapping(value = "/{id}", method = RequestMethod.POST)
ResponseEntity<Content> uploadFile(final HttpServletRequest request, @PathVariable final String id)
        throws IOException, ServletException {
    for (final Part part : request.getParts()) {
        log.debug("Content-Type: {}", part.getContentType());
        for (final String key : part.getHeaderNames()) {
            log.debug("Header {}: {}", key, part.getHeader(key));
        }
        log.debug("Name: {}", part.getName());
        log.debug("Size: {}", part.getSize());
        final String fileName = getPartName(part);
        log.debug("File name: {}", fileName);

        final DataSource ds = new DataSource() {
            @Override
            public String getContentType() {
                String ct = ContentController.this.getContentType(part.getContentType(), null);
                if (ct == null) {
                    final Pattern p = Pattern.compile("^.+\\.(.+?)$");
                    final Matcher m = p.matcher(fileName);
                    if (m.matches()) {
                        ct = ContentController.this.getContentType(m.group(1), m.group(1));
                    }
                }
                return ct;
            }

            @Override
            public InputStream getInputStream() throws IOException {
                return part.getInputStream();
            }

            @Override
            public String getName() {
                return fileName;
            }

            @Override
            public OutputStream getOutputStream() throws IOException {
                return null;
            }
        };

        final Content content = service.storeFile(ds, id, part.getSize());
        if (content != null) {
            return new ResponseEntity<>(content, IE89PostWorkaround(request), HttpStatus.CREATED);
        }
    }
    return new ResponseEntity<>(new Content(), IE89PostWorkaround(request), HttpStatus.BAD_REQUEST);
}