JavaWeb学习(19): 文件的上传和下载

饭前点心:

众所周知,在网页上进行上传和下载东西是我们最常见的操作。

上传文件步骤:

1、引入2个jar
   apache: commons-fileupload.jar组件
       commons-fileupload.jar依赖 commons-io.jar
2、前台jsp:
    <input type="file"  name="spicture"/>
表单提交方式必须为post
在表单中必须增加一个属性 entype="multipart/form-data"
3、后台Servlet
    在代码中有详细的注释。

上传时应注意的问题:

上传的目录  upload :
1.如果修改代码,则在tomcat重新启动时 会被删除
	原因:当修改代码的时候,tomcat会重新编译一份class 并且重新部署(重新创建各种目录)

2.如果不修改代码,则不会删除
	原因: 没有修改代码,class仍然是之前的class

    因此,为了防止 上传目录丢失: a.虚拟路径	b.直接更换上传目录 到非tomcat目录

下载文件步骤:

1、不需要依赖任何jar
2、步骤:
    a.请求(地址a  form),请求Servlet	
b.Servlet通过文件的地址  将文件转为输入流 读到Servlet中
c.通过输出流 将 刚才已经转为输入流的文件  输出给用户

下载时应注意的问题:

下载文件 需要设置2个 响应头:
response.addHeader("content-Type","application/octet-stream" );//MIME类型:二进制文件(任意文件)
response.addHeader("content-Disposition","attachement;filename="+fileName );//fileName包含了文件后缀:abc.txt

下载时统一不同浏览器的编码:

未统一时:

统一后:

不同浏览器设置统一编码的方式有所不同,在代码中会有详细的解释。

Code:

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
		<!-- 上传文件  -->
		<form action="UpAndDownServlet" method = "post" enctype="multipart/form-data">
		
			学号: <input type = "text" name = "sno">   <br>
			姓名: <input type = "text" name = "sname"> <br>
			上传文件: <input type = "file" name = "spicture"> <br>
			<input type = "submit" value = "上传"> <br>
		
		</form>	
		<!-- 下载文件 -->
		<a href="DownloadServlet?filename=MIME.png">MIME</a>

	
</body>
</html>

UpAndDownServlet.java(上传文件的 Servlet)

package org.rj.servlet;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet("/UpAndDownServlet")
public class UpAndDownServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
  
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 统一请求时编码
		request.setCharacterEncoding("utf-8");
		// 统一响应时编码
		response.setCharacterEncoding("utf-8");
		// 统一前台显示代码
		response.setContentType("text/html; charset=UTF-8");
		// 判断前台是否有 multipart/form-data 属性
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		
		if(isMultipart) {
			// FileItemFactory 是一个接口,需要通过实现类进行实现
			FileItemFactory factory = new DiskFileItemFactory();
			// 需要有参数,参数是一个 FileItemFactory 对象(这是个接口)
			ServletFileUpload upload = new ServletFileUpload(factory);
			try {
				// 通过parseRequest解析form中的所有请求字段,并保存到 items集合中(即前台传递的sno sname
				// spicture此时就保存在了items中)
				List<FileItem> items = upload.parseRequest(request);
				Iterator<FileItem> iter = items.iterator();
				// 迭代器进行遍历
				while(iter.hasNext()) {
					// 获取当前信息(返回值是 FileItem)
					FileItem item = iter.next();
					String itemName = item.getFieldName();
					if(item.isFormField()) {
						if(itemName.equals("sno")) {
//							int sno = Integer.parseInt(item.getString("utf-8"));
						}else if(itemName.equals("sname")) {
//							String name = item.getString("utf-8");
						}else {
							System.out.println("其他字段。。。");
						}
					} else {
						// 获取文件名
						String fileName = item.getName();
						// 上传路径(一般是服务器路径,但是有缺点)
						String path = request.getSession().getServletContext().getRealPath("upload");
						File file = new File(path,fileName);
						// 上传文件	
						item.write(file);
						System.out.println("上传成功!");
						return ;
					}	
				}
				
			} catch (FileUploadException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

DownloadServlet.java(下载文件的Servlet):

package org.rj.servlet;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.tomcat.util.codec.binary.Base64;

/**
 * Servlet implementation class DownloadServlet
 */
@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		//获取需要下载的文件名
		String fileName = request.getParameter("filename") ;//form  、a  href、 ...Server?a=b
		
		//下载文件:需要设置 消息头
		response.addHeader("content-Type","application/octet-stream" );//MIME类型:二进制文件(任意文件)
//		response.addHeader("content-Disposition","attachment;filename="+fileName );//fileName包含了文件后缀:abc.txt
		
		// edge浏览器  防止出现中文乱码
//		response.addHeader("content-Disposition","attachment;filename="+URLEncoder.encode(fileName, "utf-8") );
		// 火狐浏览器  防止出现中文乱码
		response.addHeader("content-Disposition","attachment;filename==?UTF-8?B?"+   new String(  Base64.encodeBase64(fileName.getBytes("UTF-8"))  ) +"?=" );//fileName包含了文件后缀:abc.txt
		
		
		//Servlet通过文件的地址  将文件转为输入流 读到Servlet中
		InputStream in = getServletContext().getResourceAsStream("/res/图片.png") ;
		
		//通过输出流 将 刚才已经转为输入流的文件  输出给用户
		ServletOutputStream out = response.getOutputStream() ;
		byte[] bs = new byte[10];
		int len=-1 ;
		while(  (len=in.read(bs)) != -1) {
			out.write(bs,0,len);
		}
		out.close();
		in.close();
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
}

图片资源:

后记:

关于文件传输所用到的 IO 流还不是太掌握,基础不是太扎实,看来还是要重新过一下基础部分。
这些代码要是自己在重新敲一遍的话可能有的地方会出错,重要的是先掌握方法。
原文地址:https://www.cnblogs.com/prjruckyone/p/12684087.html