通过WebService上传文件的原理

我们都知道如何通过WebService把一个字符串形式的参数传递到服务器端的一个函数并取得返回的结果,而通过WebService上传文件的原理和上传一个字符串在根本上是一样的。
唯一不同的是,我们需要多做一点额外的工作,即先读取文件到一个字节数组中,再通过Base64将其转化为字符串。详情请看下面的代码:
// 客户端读取文件然后用Base64将其转化为字符串的函数
private static String getFileByteString(File file) throws Exception{
    InputStream in = new FileInputStream(file);
 
    // 取得文件大小
    long length = file.length();
 
    // 根据大小创建字节数组
    byte[] bytes = new byte[(int) length];
 
    // 读取文件内容到字节数组
    int offset = 0;
    int numRead = 0;
    while (offset < bytes.length
        && (numRead = in.read(bytes, offset, bytes.length - offset)) >= 0) {
      offset += numRead;
    }
 
    // 读取完毕的校验  
    if (offset < bytes.length) {
      throw new IOException("不能完全讀取文件:"+ file.getName());
    }
 
    in.close();
 
    String encodedFileString = Base64.encode(bytes);
 
    return encodedFileString;
}


服务器端如何将接收到的字符串还原成文件
有了上页函数的帮助,我相信你将它传递到WebSercvice端某函数是必能做到的事,剩下的问题是,如何将接收到的字符串还原成文件呢?
答案是再用Base64将字符串还原成字节数组再将它写入一个文件即可,这样写出来的文件能保证内容和你上传的原文件一致,下面是示例程序:

WebService服务器端将接收来的字符串还原的文件的过程

// uploadedFileString是传过来的包含你上传的文件内容的字符串
byte[] bytes = Base64.decode(uploadedFileString);
            
// 存储路径
String path=CommonUtil.getUploadPath();

// 存储的文件名
String localFileName=getLocalFileName(parser.getUserid(),parser.getFileName());

// 写入新文件
FileOutputStream out = new FileOutputStream(path+localFileName);
out.write(bytes);
out.flush();
out.close();


客户端如何访问已上传的文件

上传只是手段,我们上传的真正目的其实是下载,就我们刚才上传的文件而言,如何能让人访问到它呢?我们可以如下办理:
1.将上传文件书写在WebService所在Web应用下的某目录中,如upload"1.jpg,这样客户就可以通过这样的URL访问到这个文件http://209.205.177.42:8080/webApp/upload/1.jpg. 上面IP地址是WebSercice应用所在机器的公网地址,webApp是该应用名。
2.在客户端上传文件完毕后,将上述地址以函数返回值的形式告知客户,客户就可以通过网络来访问它了。

如何得到WebApp下的upload目录
书写一个在WebApp启动时就启动的Servlet,在其init函数就能得知Webapp所在目录,得到upload目录再往下走一层就行了。下面的InitServlet的示例代码:

public class InitialSystemServlet extends HttpServlet {

    private static final long serialVersionUID = -7444606086930580188L;

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, java.io.IOException {
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, java.io.IOException {
        doPost(request, response);
    }

    public void init(ServletConfig config) throws ServletException {
       
        // 设置上传路径
        CommonUtil.setUploadPath(config.getServletContext().getRealPath("/"));
    }
}


其它问题1.如何防止文件被覆盖:在生成文件时采用时间+用户ID+随机数的文件名,这样重名几率就大大降低,还不放心可以在写文件之间检验文件是否已存在了。2.如何要把文件不放在服务器而是放到数据库怎么办:你可以把文件内容甚至字符串直接存储到数据库,需要下载时再取出来。

相关文章
相关标签/搜索