日期:2014-05-20  浏览次数:20710 次

如何用同一个表单上传文件和提交非文件性的数据?
我想在表单中收集待上传文件的元数据,然后输入数据库;同时,文件也要上传到服务器。  
  但是,上传文件时,form的enctype属性要设成"multipart/form-data";而一旦如此设定,服务器如何收集元数据?  
   
  示例代码如下:  
  <form action = "servlet/XXX" enctype = "multipart/form-data" method="post">  
  <table width="90%" border="0" cellspacing="0" cellpadding="0">  
  <tr>  
  <td> 作者:  
  <input type="text" name="textfield">  
  <input type="file" name="file">  
  <input type="submit" name="Submit" value="提交"> </td>  
  </tr>  
  </table>  
  </form>  
   
  请高人指教!

------解决方案--------------------
form设置了enctype="multipart/form-data" 属性后,就是2进制传输数据了 
form里面的input的值传过去的不过是以2进制的方式,所以request就得不到值了。
这是一个java的BUG.不管用什么语言处理文件表单,form的POST方法提交的数据都是在标准输入中,C/c++,perl这些语言都是要求程序员自己从标准输入中读取数据再处理的,象php,asp,c#这些语言就提供了写好的组件,他们把文件放处理好放在一个内存区,把字段也处理好放在一个内存区,这样你用不同的方法就可以从相应的地方取到了你要的内容。

JSP是怎么处理的呢?它在用request.getParameter("xxxx");把标准输入中的内容全部读出来,只取那些字段内容.关于文件内容的那些数据就不要了.大家知道标准输入是一个buffer,一旦读过一次,下面再读就没有了,所以当你request.getParameter ("xxx");再读文件就取不到了.而目前市场上提供jsp文件上传组件的程序中,获得文件内容也是犯了同样的错误.他们只把文件
那一段的数据读出来,字段那一段数据就不要了,所以读取文件后request对象中的内容也空了。

知道了这个原因,就好解决了.我们可以作自己来写,用两个地方同时把request.getInputStream()的所有数据都放在它相应的地方,先用一个Hashtable把所有字段的name和value压进去,同时把文件源数据放在DataInputStream中,同时提交多少文件(在读数据源时每读到一行Content-Type就说明有一个文件)就保存几个DataInputStream,这样再用一个 request.getFile()从内存中的DataInputStream中取得文件内容返回给调用者.