上传时浏览器会自动产生类似URLEncode.encode()的编码,也许把你的分隔符编码了。

解决方案 »

  1.   

    浏览器编码在向服务器端提交请求时,浏览器需要将大量的数据一同提交给 Server 端, 而提交前,浏览器需要按照 Server 端可以识别的方式进行编码,对于普通的表单数据,这种编码方式很简单,编码后的结果通常是 field1=value2&field2=value2&… 的形式,如 name=aaaa&Submit=Submit。这种编码的具体规则可以在 rfc2231 里查到, 通常使用的表单也是采用这种方式编码的,Servlet 的 API 提供了对这种 编码方式解码的支持,只需要调用 ServletRequest 类中的方法就可以得到 用户表单中的字段和数据。这种编码方式( application/x-www-form-urlencoded )虽然简单,但对于传输大块的二进制数据显得力不从心,对于传输这类数据,浏览器采用了另一种编码方式,即 "multipart/form-data" 的编码方式,采用这种方式,浏览器可以很容易的表单内的数据和文件一起。这种编码方式先定义好一个不可能在数据中出现的字符串作为分界符,然后用它将各个数据段分开,而对于每个数据段都对应着 HTML 页面表单中的一个 Input 区,包括一个 content-disposition 属性,说明了这个数据段的一些信息,如果这个数据段的内容是一个文件,还会有 Content-Type 属性,然后就是数据本身。提交请求提交请求的过程由浏览器完成的,并且遵循 HTTP 协议,每一个从浏览器端到服务器端的一个请求,都包含了大量与该请求有关的信息, 在 Servlet 中,HttpServletRequest 类将这些信息封装起来,便于我们提取使用。在文件上载和表单提交的过程中,有两个指的关心的问题,一是上载的数据是是采用的那种方式的编码,这个问题的可以从 Content-Type 中得到答案,另一个是问题是上载的数据量有多少即 Content-Length ,知道了它,就知道了 HttpServletRequest 的实例中有多少数据可以读取出来。这两个属性,我们都可以直接从 HttpServletRequest 的一个实例中获得,具体调用的方法是 getContentType() 和 getContentLength() 。Content-Type 是一个字符串, 
    System.out.println(request.getContentType());可以得到这样的一个输出字符串: 
    multipart/form-data; boundary=---------------------------7d137a26e18
    前半段正是编码方式,而后半段正是分界符,通过 String 类中的方法,我们可以把这个字符串分解,提取出分界符。String contentType=request.getContentType();
    int start=contentType.indexOf("boundary=");
    int boundaryLen=new String("boundary=").length();
    String boundary=contentType.substring(start+boundaryLen);
    boundary="--"+boundary;
    判断编码方式可以直接用 String 类中的 startsWith 方法判断。 
    if(contentType==null || !contentType.startsWith("multipart/form-data"))
    这样,我们在解码前可以知道:
    编码的方式是否是multipart/form-data
    数据内容的分界符
    数据的长度 
    具体信息请参见(用 Servlet 进行上载的原理和实现):
    http://www-900.ibm.com/developerWorks/cn/java/fileup/index.shtml