代码之家  ›  专栏  ›  技术社区  ›  Casey

从输入流或字节数组构造数据源

  •  5
  • Casey  · 技术社区  · 14 年前

    我正在写一个小文件上传实用程序作为一个大项目的一部分。最初,我使用ApacheCommons文件实用程序类从servlet处理这个问题。以下是我为该服务编写的快速测试客户机的一个片段:

    public static void main(String[] args) {
    
      JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
    
     factory.getInInterceptors().add(new LoggingInInterceptor());
     factory.getOutInterceptors().add(new LoggingOutInterceptor());
     factory.setServiceClass(FileUploadService.class);
     factory.setAddress("http://localhost:8080/FileUploadService/FileUploadService");
     FileUploadService client = (FileUploadService) factory.create();
    
     FileType file = new FileType();
     file.setName("statemo_1256144312279");
     file.setType("xls");
    
     DataSource source = new FileDataSource(new File("c:/development/statemo_1256144312279.xls"));
     file.setHandler(new DataHandler(source));
     Boolean ret = client.uploadFile(file);
     System.out.println (ret);
     System.exit(0);
    

    }

    这是绝对可行的。现在,当我试图替换ApacheCommons实用程序时,问题出现了。在上面的代码中,我从一个具有绝对路径名的文件创建一个数据源。但是,在我的servlet中,我无法获得绝对路径名,并且我通过线路发送的文件是空的。

    以下是servlet代码:

     @SuppressWarnings("unchecked")
        protected void doPost (final HttpServletRequest request, final HttpServletResponse response) 
            throws ServletException, IOException {
    
        // form should have enctype="multipart/form-data" as an attribute
     if (!ServletFileUpload.isMultipartContent (request)) {
      LOG.info("Invalid form attribute");
      return;
     }
    
     //DataInputStream in = new DataInputStream(request.getInputStream());
    
     final DiskFileItemFactory factory = new DiskFileItemFactory ();
     factory.setSizeThreshold(FILE_THRESHOLD_SIZE);
    
     final ServletFileUpload sfu = new ServletFileUpload (factory);
     sfu.setSizeMax(MAX_FILE_SIZE);
    
     final HttpSession session = request.getSession();
    
     final List<FileItem> files = new ArrayList<FileItem>();
    
     final List<String> filesToProcess = new ArrayList<String>();
    
     try {
            final List<FileItem> items = sfu.parseRequest(request);
    
            for (final FileItem f : items) {
                if (!f.isFormField())
                    files.add(f);
            }
    
            /*for (final FileItem f : files) {
             final String absoluteFileName = UPLOAD_DESTINATION + FilenameUtils.getName(f.getName());
    
                //f.write(new File (absoluteFileName));
                filesToProcess.add(absoluteFileName);
            }*/
    
            FileItem f = files.get(0);
    
            LOG.info("File: " + FilenameUtils.getName(f.getName()));
            LOG.info("FileBaseName: " + FilenameUtils.getBaseName(f.getName()));
            LOG.info("FileExtension: " + FilenameUtils.getExtension(f.getName()));
    
            FileUploadServiceClient client = new FileUploadServiceClient();
    
            DataSource source = new FileDataSource(new File(f.getName()));
    
            FileType file = new FileType();
            file.setHandler(new DataHandler(source));
            file.setName(FilenameUtils.getBaseName(f.getName()));
            file.setType(FilenameUtils.getExtension(f.getName()));
    
            Boolean ret = client.uploadFile(file);
    
            LOG.info("File uploaded - " + ret);
    
            filesToProcess.add(UPLOAD_DESTINATION + FilenameUtils.getName(f.getName()));
            session.setAttribute("filesToProcess", filesToProcess);
    
      final RequestDispatcher dispatcher = request.getRequestDispatcher("Validate");
            if (null != dispatcher) {
             dispatcher.forward(request, response);
            }
        } catch (FileUploadException e) {
            LOG.info("Exception " + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            LOG.info("Exception " + e.getMessage());
            e.printStackTrace();
        }
    

    }

    今天早上我一直在做这件事,但什么也没做。即使我完全摆脱了ApacheCommons文件,自己处理请求的解析,我仍然无法适当地构造数据源。

    谢谢!

    3 回复  |  直到 8 年前
        1
  •  3
  •   Casey    14 年前

    实际上,这相当简单,我只是将字节从输入流复制到数据源:

    FileItem f = files.get(0);
    
    // there is a problem here where the file being created is empty, since we only have a
    // partial path:
    DataSource source = new FileDataSource(new File(f.getName()));
    
    // because of the above problem, we are going to copy over the data ourselves:
    byte[] sourceBytes = f.get();
    OutputStream sourceOS = source.getOutputStream();
    sourceOS.write(sourceBytes);
    
        2
  •  2
  •   Bozho Michał Mech    14 年前
    • This 是公共电子邮件代码吗 ByteArrayDataSource
    • 尝试替换ApacheCommons听起来很奇怪-不要,除非你有一个很好的理由
    • 可以 获取servlet中的绝对路径。你可以打电话 getServletContext().getRealPath("/") 它将返回应用程序的绝对路径,然后您可以获取与之相关的文件。
        3
  •  1
  •   Yuriy N.    8 年前

    在我们的应用程序中,有一些对象具有inputstream和name属性。我们正在使用下一个类用这些属性构造数据源。

    public class InputStreamDataSource implements DataSource {
    
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        private final String name;
    
        public InputStreamDataSource(InputStream inputStream, String name) {
            this.name = name;
            try {
                int nRead;
                byte[] data = new byte[16384];
                while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
                  buffer.write(data, 0, nRead);
                }
                inputStream.close();
                buffer.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public String getContentType() {            
            return new MimetypesFileTypeMap().getContentType(name);
        }
    
        @Override
        public InputStream getInputStream() throws IOException {
                return new ByteArrayInputStream(buffer.toByteArray());
        }
    
        @Override
        public String getName() {
           return name;
        }
    
        @Override
        public OutputStream getOutputStream() throws IOException {
            throw new IOException("Read-only data");
        }
    
    }