本帖最后由 wudeaaa 于 2010-11-11 16:11:51 编辑

解决方案 »

  1.   

    看RFC文档吧:
    http://www.faqs.org/rfcs/rfc1867.html
      

  2.   

    request.getInputStream()获取输入流,然后转成文件输入流,用read方法读取就可以了啊。
      

  3.   

    文档看过来,里面没有说怎么接收(可能是我没看到?),就是根据表rfc1867的规范上传的,服务端接收时,怎么解析得到文件流,我的方法是首先找到分隔符boundary,然后每次读1024个字节,
    byte[] srcb = new byte[1024];
    String content = "";
    while(in.read(srcb) != -1){
     for (int i = 0, j = 0; i < srcb.length - 1 && j <= i; i++) {
    if (srcb[i] == 13 && srcb[i + 1] == 10) {//表示\r\n的ascii码,说明是一行
               byte []sub = subBytes(srcb, j, i);//每一行(从j到i)字节数组
               String line = new String(sub,"UTF-8");
              //分析
               ...
             if(line是正文)
             content += line;() 
    }
             然后把content转为byte[],再写入文件中,但是文件格式错误、
    }
    }
      

  4.   

    这种是标准的上传文件格式啦,用smartupload或者commons-fileupload就可以解释了,根本不需要自己做
      

  5.   

    没必要手工处理,手工处理的话如果你不熟知 RFC 关于 HTTP 协议的规范,是做不出来的。处理文件上传的开源框架有很多,比如:Apache Commons 的 FileUpload、O'Reilly 的 COS 等等。
      

  6.   


    private byte[] parse(HttpServletRequest request) throws IOException { final int NONE = 0;
    final int DATAHEADER = 1;
    final int FILEDATA = 2;
    final int FIELDDATA = 3; final int MXA_SEGSIZE = 1000 * 1024 * 10;//每批最大的数据量 10M String contentType = request.getContentType();// 请求消息类型
    String fieldname = ""; // 表单域的名称
    String fieldvalue = ""; // 表单域的值
    String filename = ""; // 文件名
    String boundary = ""; // 分界符
    String lastboundary = ""; // 结束符
    String filePath = "";
    Hashtable<String, String> formfields = new Hashtable<String, String>();
    int filesize = 0; // 文件长度 int pos = contentType.indexOf("boundary="); if (pos != -1) { // 取得分界符和结束符
    pos += "boundary=".length();
    boundary = "--" + contentType.substring(pos);
    lastboundary = boundary + "--";
    }
    int state = NONE;
    // 得到数据输入流reqbuf
    DataInputStream in = new DataInputStream(request.getInputStream());
    // 将请求消息的实体送到b变量中
    int totalBytes = request.getContentLength();
    String message = "";
    if (totalBytes > MXA_SEGSIZE) {//每批大于10m时
    message = "Each batch of data can not be larger than " + MXA_SEGSIZE / (1000 * 1024)
    + "M";
    return null;
    }
    byte[] b = new byte[totalBytes];
    in.readFully(b);
    in.close();
    String reqContent = new String(b, "UTF-8");//
    BufferedReader reqbuf = new BufferedReader(new StringReader(reqContent)); boolean flag = true;
    int i = 0;
    while (flag == true) {
    String s = reqbuf.readLine();
    if ((s == null) || (s.equals(lastboundary)))
    break; switch (state) {
    case NONE:
    if (s.startsWith(boundary)) {
    state = DATAHEADER;
    i += 1;
    }
    break;
    case DATAHEADER:
    pos = s.indexOf("filename=");
    if (pos == -1) { // 将表单域的名字解析出来
    pos = s.indexOf("name=");
    pos += "name=".length() + 1;
    s = s.substring(pos);
    int l = s.length();
    s = s.substring(0, l - 1);
    fieldname = s;
    state = FIELDDATA;
    } else { // 将文件名解析出来
    String temp = s;
    pos = s.indexOf("filename=");
    pos += "filename=".length() + 1;
    s = s.substring(pos);
    int l = s.length();
    s = s.substring(0, l - 1);// 去掉最后那个引号”
    filePath = s;
    pos = s.lastIndexOf("\\");
    s = s.substring(pos + 1);
    filename = s;
    // 从字节数组中取出文件数组
    pos = byteIndexOf(b, temp, 0);
    b = subBytes(b, pos + temp.getBytes().length + 2, b.length);// 去掉前面的部分
    int n = 0;
    /**
     * 过滤boundary下形如 Content-Disposition: form-data; name="bin";
     * filename="12.pdf" Content-Type: application/octet-stream
     * Content-Transfer-Encoding: binary 的字符串
     */
    while ((s = reqbuf.readLine()) != null) {
    if (n == 1)
    break;
    if (s.equals(""))
    n++; b = subBytes(b, s.getBytes().length + 2, b.length);
    }
    pos = byteIndexOf(b, boundary, 0);
    if (pos != -1)
    b = subBytes(b, 0, pos - 1); filesize = b.length - 1;
    formfields.put("filesize", String.valueOf(filesize));
    state = FILEDATA;
    }
    break;
    case FIELDDATA:
    s = reqbuf.readLine();
    fieldvalue = s;
    formfields.put(fieldname, fieldvalue);
    state = NONE;
    break;
    case FILEDATA:
    while ((!s.startsWith(boundary)) && (!s.startsWith(lastboundary))) {
    s = reqbuf.readLine();
    if (s.startsWith(boundary)) {
    state = DATAHEADER;
    break;
    }
    }
    break;
    }
    }
    return b; } // 字节数组中的INDEXOF函数,与STRING类中的INDEXOF类似
    public static int byteIndexOf(byte[] b, String s, int start) {
    return byteIndexOf(b, s.getBytes(), start);
    } // 字节数组中的INDEXOF函数,与STRING类中的INDEXOF类似
    public static int byteIndexOf(byte[] b, byte[] s, int start) {
    int i;
    if (s.length == 0) {
    return 0;
    }
    int max = b.length - s.length;
    if (max < 0)
    return -1;
    if (start > max)
    return -1;
    if (start < 0)
    start = 0;
    search: for (i = start; i <= max; i++) {
    if (b[i] == s[0]) {
    int k = 1;
    while (k < s.length) {
    if (b[k + i] != s[k]) {
    continue search;
    }
    k++;
    }
    return i;
    }
    }
    return -1;
    } // 用于从一个字节数组中提取一个字节数组
    public static byte[] subBytes(byte[] b, int from, int end) {
    byte[] result = new byte[end - from];
    System.arraycopy(b, from, result, 0, end - from);
    return result;
    } // 用于从一个字节数组中提取一个字符串
    public static String subBytesString(byte[] b, int from, int end) {
    return new String(subBytes(b, from, end));
    }主要实现是parse,返回的是这段的字节数组。比较繁琐
      

  7.   

    public String getResponseXml(String url) {
        String responseXML = null;
        try {
          MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
          HttpClient httpClient = new HttpClient(connectionManager);
          log.debug("请求地址:" + url());
          PostMethod postMethod = new PostMethod(url);
          /** *将内容放入postMethod中** */
          postMethod.setRequestBody("请求内容放入到该位置");      log.debug("开始接收业务处理反馈报文.\n");
          /** *执行postMethod,并获取状态码 */
          int statusCode = httpClient.executeMethod(postMethod);
          log.debug("http返回码: "+statusCode);
          
          if (statusCode != 200) {// 判断是否调用成功
            log.error("调用失败,请确认地址是否正确");
          }
          /** 获取反馈内容 */
          responseXML = postMethod.getResponseBodyAsString();      log.debug("反馈报文为:\n" + responseXML + "\n");
          /** 连接释放 */
          postMethod.releaseConnection();
        } catch (HttpException e) {
          log.error("HttpException异常,正在重试...");
          e.printStackTrace();
        } catch (IOException e) {
          log.error("IOException异常,正在重试...\n");
          e.printStackTrace();
        }
        return responseXML;
      }
      

  8.   

          /** 获取反馈内容 */
          responseXML = postMethod.getResponseBodyAsString();
          InputStream is=postMethod.getResponseBodyAsStream();
          byte[] out=postMethod.getResponseBody();
       
         其中根据自己需要保存反馈内容,哥好多年没来csdn了,今天忽然有兴趣,来逛逛,^_^。