文件上传:

1、commons-fileupload-1.2.1.jar与commons-io-1.4.jar文件是apache开源小组的结晶,通过他们可以在支持Servlet的容器中完成基于HTTP协议流的文件上传


2、这两个组件是基于在Servlet下完成文件上传的,当过度到Struts2时代之后,框架对这两个组件做了一次封装,从操作上表现的更为人性化


3、如果不使用第三方组件来完成文件上传,则必须自己解析HTTP协议流提取上传文件数据

第一步

1、在MyEclipse中新建一个web工程





2、在工程目录下新建一个lib文件夹,将下载的commons-

 fileupload-1.2.1.jar与commons-io-1.4.jar文件拷贝到lib文

      件夹下,右键点击此两个文件选择add build path将其添加到 

      构建路径中


第二步

1、新建Servlet类FileUploadTest,并重写doGet与doPost方法;在doGet方法中调用doPost方法



2、在web.xml文件中配置Servlet

<servlet>
	<servlet-name>fileUploadTest</servlet-name>
	<servlet-class>com.scxh.upload.FileUploadTest</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>fileUploadTest</servlet-name>
	<url-pattern>/fileUploadTest</url-pattern>
</servlet-mapping>


第三步

创建JSP页面file.jsp,表单html片段如下:

<form action="fileUploadTest" method="post" enctype="multipart/form-data">
用户名:<input name="username" value="张孝祥"/><br><br>
密    码:<input type="password" name="password" value="123456"/>
<br><br>
爱    好:
<input type=“checkbox” name=“loves” value=“basketball”/>篮球
<input type=“checkbox” name=“loves” value=“football”/>足球<br><br>
上    传:<input type="file" name="fileAttach"><br><br>
<input type="submit" value="提  交"/>
<input type="reset" value="重  置"/>
</form>


第四步

在Post方法体中编写Servlet代码如下:

DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);//参数是HttpServletRequest对象
for (FileItem item : items){遍历所有客户端提交的参数(包括文件域)
    if (item.isFormField()) {//键为普通表单域
        String key = item.getFieldName();//取出普通表单域的键
        String value = item.getString();//取出普通表单域的值
    }else{//键为文件域
        String key = item.getFieldName();//取出文件域的键
        String value = item.getName();//取出文件域的值
        long fileLen = item.getSize();//取出上传文件的尺寸
        String mimeType = item.getContentType();//取出上传文件的类型
        item.write(new File(“D:/xxx.xxx”));//保存上传的文件到服务器本地
    }
}



文件下载:

1、默认情况下,客户端只要直接请求一个文件则服务端将推送这个文件到客户端,如果客户端不识别该文件则默认情况下将会弹出一个另存为的下载提示,但是对于浏览器能够识别的文件则可能会被浏览器直接打开
2、如果要使浏览器能够正确的弹出下载文件的另存为提示则必须在推送头中加上一个称之为Content-Disposition的头,加上该推送头之后,浏览器能够将其当成附件并给出下载文件的提示



第一步

1、新建Servlet类FileDownloadTest,并重写doGet与doPost方法;在doGet方法中调用doPost方法

2、在web.xml文件中配置Servlet

<servlet>
	<servlet-name>fileDownloadTest</servlet-name>
	<servlet-class>com.scxh.download.FileDownloadTest</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>fileDownloadTest</servlet-name>
	<url-pattern>/fileDownloadTest</url-pattern>
</servlet-mapping>


第二步

创建JSP页面file.jsp,表单html片段如下:

<body>
    <span style="color:red;font-size:22px;font-weight:bolder;">文件下载</span>
    <hr color="green" width="100%" size="2"/>

    <!– 直接请求浏览器认识的文件可能被浏览器直接打开 -->
    <a href="download/test.doc">下载阶段实训表</a>

    <!– 直接请求浏览器不认识的文件可能被浏览器当成附件而弹出下载提示,但是下
     载的具体文件名被get的提交方式暴露出来-->
    <a href="download/jprofiler_windows_5_1_4.zip">下载JProfiler请点击这里</a>
    
     <!– 使用Servlet方式完成get/post下载可以不用暴露文件名(下载的文件通过提	交的参数进行映射),且能保证浏览器将所有文件当成附件下载 -->
    <a href=“fileDownloadTest?fileName=中央一号文件.doc”>
    </a>

  </body>



第三步

在Post方法体中编写Servlet代码如下:

//利用前面的Accp组件提供的编码功能完成请求处理以防产生乱码
HttpServletRequest request=new FileUpload(req).getRequest();
String fileName=request.getParameter("fileName");
//此步设置浏览器弹出的提示内容,这些内容必须经过URL编码,否则将出现下载问题
String showFileName = URLEncoder.encode(fileName, "UTF-8");
//获取将要下载文件的输入流,参数以右斜杆开始表示工程根路径
InputStream is=getServletContext().getResourceAsStream("/download/"+fileName);
//必须增加此header头以保证浏览器将其当成附件下载
response.addHeader("Content-Disposition", "attachment;filename="+showFileName);
OutputStream os=response.getOutputStream();
byte[] b=new byte[1024];
try{//推送文件流
    for(int k=is.read(b);k!=-1;os.write(b),k=is.read(b));
    os.flush();//刷出缓冲中可能存在的数据
}finally{//关闭输出输入流
    os.close();
    is.close();
}



ACCP组件介绍:

1、这个组件实际上是对apache组件的一种包装,该组件对Accp组件包装之后更加人性化的支持上传了,使用该组件只需要将accp2.013.11.08.jar包添加到当前工程的classpath路径中,而不再需要导入commons-fileupload-1.2.1.jar和commons-io-1.4.jar文件
2、使用该组件只需要修改Servlet代码即可,其它的配置不发生任何变动
   该组件的原理是使用FileUpload包装请求对象request和要保存的上传文件路径,然后使用FileUpload调用upload(不解码)或uploadAndDecoding(解码)解析上传HTTP流并返回UploadRequest,一旦得到UploadRequest对象之后剩下的操作就和普通的HttpServletRequest对象操作相同了
  

//第一个参数表示HttpServletRequest对象,第二个参数表示要保存的文件路径
FileUpload fileUpload=new FileUpload(request,“/upload”);
UploadRequest upload=fileUpload.uploadAndDecoding();
//获取普通参数
String username=(String)upload.getParameter("username");
String password=(String)upload.getParameter("password");
//如果一个键对应两个值则返回List列表
List<String> loves=(List<String>)upload.getParameter("loves");
//获取文件域
UploadFile uploadFile=(UploadFile)upload.getParameter("fileAttach");

System.out.println(username+":"+password);
System.out.println("loves:"+loves);
System.out.println("fileName:"+uploadFile.getFileName());
System.out.println("FileSize:"+uploadFile.getFileSize());
System.out.println("MimeType:"+uploadFile.getMimeType());