表单提交文件上传

前言

表单上传文件是最基本的上传文件方式,虽然现在有很多优秀的上传插件,如:webuploader、uploadify等,但我们还是说一下表单上传。

具体内容

1.jsp页面form表单

<form name="myform" action="<%=path%>/upload" method="post" enctype="multipart/form-data">
    <input type="text" name="userName" value="" />
    <input type="text" name="age" value="" />
    <input type="file" name="userFile" />
    <input type="submit" value="提交" />
</form>
  • action便是要提交到java的路径,利用submit提交即可,当然也可以这么写,首先给form起名name="myform",然后利用button按钮点击事件onClick="doSearch()"方法提交,js代码如下
function doSearch(){
    document.myform.action=path + "/upload";
    document.myform.target="_self";
    document.myform.submit();
}
  • enctype属性
    1、application/x-www-form-urlencoded:这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成url编码方式。
    2、multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定的文件内容也封装到请求参数里。
    3、text/plain:这种方式主要适用于直接通过表单发送邮件的方式。

2.后端java处理上传文件的架包有3种:

  • commons-fileupload上传组件
  • COS上传组件
  • SmartUpload组件

我们只将讲commons-fileupload上传组件,这个组件需要架包commons-fileupload-1.3.3.jar和commons-io-2.5.jar,java代码如下

 // 判断enctype属性是否为multipart/form-data
boolean isMultipart = ServletFileUpload.isMultipartContent(request);

DiskFileItemFactory factory = new DiskFileItemFactory();

// 当上传文件太大时,因为虚拟机能使用的内存是有限的,所以此时要通过临时文件来实现上传文件的保存
// 此方法是设置是否使用临时文件的临界值(单位:字节)
factory.setSizeThreshold(1024*1024);//1M

// 与上一个结合使用,设置临时文件的路径(绝对路径)
factory.setRepository(new File(request.getSession().getServletContext().getRealPath("")));

Map<String,Object> map =new HashMap<String,Object>();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(1024*1024);// 设置上传内容的大小限制(单位:字节)
List<?> items = upload.parseRequest(request);
Iterator<?> iter = items.iterator();
while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();
    if (item.isFormField()) {//如果是普通表单字段
        String name = item.getFieldName();
        String value = item.getString();
        map.put(name, value);
    } else { //如果是文件字段
        String fieldName = item.getFieldName();
        String fileName = item.getName();
        String contentType = item.getContentType();
        boolean isInMemory = item.isInMemory();
        long sizeInBytes = item.getSize();//可以用来判断文件大小

        if (fileName!=null) {
            File fullFile=new File(item.getName());
            File savedFile=new File(request.getSession().getServletContext().getRealPath(""),fullFile.getName());
            item.write(savedFile);
        } else {
            InputStream uploadedStream = item.getInputStream();
            uploadedStream.close();
        }
    }
}

从代码中可以看出代码循环了表单元素,利用item.isFormField()判断是否是普通字段,普通字段放到了Map里,文件利用架包上传,上传地址为
request.getSession().getServletContext().getRealPath("")
这个是获取项目绝对路径,这个路径不是新建项目时workspace里项目路径,而是项目编译后的路径,可以打印看一下。

结语

如果只是上传文件而没有其它元素也可以通过字节流实现文件上传,如下:

 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
      java.io.InputStream in= request.getInputStream();  
      java.io.FileOutputStream out= new java.io.FileOutputStream("d:\\out.txt");  

      byte[] buffer = new byte[8192];  
      int count = 0;  
      while((count = in.read(buffer)) >0){  
           out.write(buffer, 0, count);  
      }          
      out.close();  
 }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章