Java 从InputStream或字节数组构造数据源
我正在写一个小文件上传工具的事情作为一个更大的项目的一部分。最初,我使用ApacheCommons文件实用程序类从servlet处理这个问题。下面是我为该服务编写的快速测试客户端的一个片段:Java 从InputStream或字节数组构造数据源,java,servlets,apache-commons,Java,Servlets,Apache Commons,我正在写一个小文件上传工具的事情作为一个更大的项目的一部分。最初,我使用ApacheCommons文件实用程序类从servlet处理这个问题。下面是我为该服务编写的快速测试客户端的一个片段: public static void main(String[] args) { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.getInInterceptors().add(new LoggingInIn
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();
}
@SuppressWarnings(“未选中”)
受保护的void doPost(最终HttpServletRequest请求,最终HttpServletResponse响应)
抛出ServletException、IOException{
//表单应具有enctype=“多部分/表单数据”作为属性
如果(!ServletFileUpload.isMultipartContent(请求)){
LOG.info(“无效的表单属性”);
返回;
}
//DataInputStream in=新的DataInputStream(request.getInputStream());
最终的DiskFileItemFactory工厂=新的DiskFileItemFactory();
setSizeThreshold(文件大小);
最终ServletFileUpload sfu=新ServletFileUpload(工厂);
sfu.setSizeMax(最大文件大小);
最终HttpSession会话=request.getSession();
最终列表文件=新的ArrayList();
最终列表filesToProcess=newarraylist();
试一试{
最终列表项=sfu.parseRequest(请求);
用于(最终文件项目f:项目){
如果(!f.isFormField())
添加(f);
}
/*用于(最终文件项f:文件){
最终字符串absoluteFileName=UPLOAD_DESTINATION+FilenameUtils.getName(f.getName());
//f、 写入(新文件(绝对文件名));
filesToProcess.add(绝对文件名);
}*/
FileItem f=files.get(0);
LOG.info(“文件:”+FilenameUtils.getName(f.getName()));
LOG.info(“FileBaseName:+FilenameUtils.getBaseName(f.getName()));
LOG.info(“FileExtension:+FilenameUtils.getExtension(f.getName()));
FileUploadServiceClient=新FileUploadServiceClient();
DataSource source=新文件DataSource(新文件(f.getName());
FileType file=新文件类型();
setHandler(新的DataHandler(源));
setName(FilenameUtils.getBaseName(f.getName());
setType(FilenameUtils.getExtension(f.getName());
布尔ret=client.uploadFile(文件);
LOG.info(“上传文件-”+ret);
filesToProcess.add(UPLOAD_DESTINATION+FilenameUtils.getName(f.getName());
setAttribute(“filesToProcess”,filesToProcess);
final RequestDispatcher=request.getRequestDispatcher(“验证”);
if(null!=调度程序){
转发(请求、响应);
}
}捕获(文件上载异常){
LOG.info(“异常”+e.getMessage());
e、 printStackTrace();
}捕获(例外e){
LOG.info(“异常”+e.getMessage());
e、 printStackTrace();
}
}
今天早上我一直在做这件事,但没有取得任何进展。即使我完全摆脱了apachecommons文件的东西,自己处理请求的解析,我仍然无法正确地构造数据源
谢谢 - 是公用代码电子邮件
ByteArrayDataSource
- 试图取代ApacheCommons听起来很奇怪——不要这样做,除非你有很好的理由
- 您可以在servlet中获得绝对路径。您可以调用
,它将返回应用程序的绝对路径,然后您可以获取与其相关的文件getServletContext().getRealPath(“/”)
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);
在我们的应用程序中,有些对象具有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");
}
}
是的,我不想取代apache commons。我甚至没有想过从上下文中获取路径并以这种方式获取文件。不过,这个项目的另一部分会使这一点变得困难。明天我将看一看ByteArraydata源代码,并可能在我的解决方案中使用它。谢谢确切地您需要发送文件内容,而不仅仅是文件句柄;)我认为这仍然会将整个流加载到内存中,还是我错了?(其他答案也是如此,或者它们加载一个文件,而我只有一个InputStream)。