文件上传和下载(一)--【jsp+servlet】

一、文件上传

在TCP/IP中,最早出现的文件上传机制是FTP。它是将文件由客户端发送到服务器的标准机制。

但是在jsp编程中不能使用FTP方法来上传文件,这是由jsp运行机制所决定的。

通过为表单元素设置method="post" enctype="multipart/form-data"属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而是实现文件的上传。


enctype属性有三种类型



实例【jsp+servlet】

1、上传实现思路

(一)、环境搭建【配置web.xml创建UploadServlet】

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>UploadServlet</servlet-name>
    <servlet-class>com.wuhn.scxz.servlet.UploadServlet</servlet-class>
  </servlet>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>DownloadServlet</servlet-name>
    <servlet-class>com.wuhn.scxz.servlet.DownloadServlet</servlet-class>
  </servlet>
  
  <!-- 上传servlet -->	
  <servlet-mapping>
    <servlet-name>UploadServlet</servlet-name>
    <url-pattern>/UploadServlet.do</url-pattern>
  </servlet-mapping>
  <!-- 下载servlet -->
  <servlet-mapping>
    <servlet-name>DownloadServlet</servlet-name>
    <url-pattern>/DownloadServlet.do</url-pattern>

  </servlet-mapping>	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

(二)、前台页面配置【Form的method设置为post,enctype配置为multipart/form-data


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML>
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>上传</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link rel="stylesheet" type="text/css" href="<%=path%>/css/common.css">
	<script type="text/javascript" src="<%=path%>/js/jquery-1.11.1.js"></script>
	<script type="text/javascript">
		
		
		/*//js 预览功能因为回去不到本地实际的路径,所以无法实现。因为浏览器考虑到安全性的问题,限制了获取真实的本机路径,只能这样C:\fakepath\img1-lg.jpg
		function showPreview(obj){
			var imgPath = obj.value;
			console.log(imgPath);
			document.getElementById("previewImg").innerHTML="<img src='"+imgPath+"'/>";
		}
		*/
		
	</script>

  </head>
  
  <body>
  	<form action="<%=path%>/UploadServlet.do" method="post" enctype="multipart/form-data">
  		请选择图片:<input id="myfile" name="myfile" type="file"/>
  		<input type="submit" value="提交"  />${result}
  	</form>
  	
  	
  </body>
</html>



(三)、后台Servlet实现【保存上传文件】

实现的步骤:

1、获取request当中的流信息,保存到临时文件。

2、从临时文件中得到上传的文件名及文件内容起止位置。

3、根据文件起止位置,读取上传文件内容,保存到本地。

package com.wuhn.scxz.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author wuhn
 * @创建时间 2015-12-07
 * @功能 上传文件
 * **/
public class UploadServlet extends HttpServlet {

	/**
	 * get方法
	 * **/
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request,response);//默认为post提交
		
	}

	/**
	 * post方法
	 * **/
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("测试:已接收到请求");
		//从request当中获取流信息
		InputStream inputStream = request.getInputStream();
		
		//tempFile指向临时文件
		String tempFileName= "D:\\tempFile";
		File tempFile = new File(tempFileName);
		
		//fileOutputStream文件输出流指向这个临时文件
		FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
		byte b[] = new byte[1024];
		int n;
		while ((n = inputStream.read(b)) != -1) {
			fileOutputStream.write(b, 0, n);
		}
		//关闭输出流、输入流
		fileOutputStream.close();
		inputStream.close();
		
		
		//关闭上传文件的名称
		RandomAccessFile randomFile = new RandomAccessFile(tempFile,"r");
		randomFile.readLine();
		String str = randomFile.readLine();
		String strSplit = str.split(";")[str.split(";").length-1]; 
		int beginIndex = strSplit.indexOf("\"")+1;
		int endIndex = strSplit.lastIndexOf("\"");
		System.out.println(strSplit+" beginIndex:"+beginIndex+" endIndex:"+endIndex);
		String filename = strSplit.substring(beginIndex, endIndex);
		System.out.println("filename:"+filename);
		
		//重新定位文件指针到文件头
		randomFile.seek(0);
		long startPosition = 0;
		int i =1;
		//获取文件内容的开始位置
		while ((n = randomFile.readByte())!=-1 && i<4) {
			if(n == '\n'){
				startPosition = randomFile.getFilePointer();
				i++;
			}			
		}
		startPosition = startPosition-1;
		//获取文件内容的结束位置
		randomFile.seek(randomFile.length());
		long endPosition = randomFile.getFilePointer();
		int j = 1;
		while (endPosition >=0 && j<2) {
			endPosition--;
			randomFile.seek(endPosition);
			if(randomFile.readByte()=='\n'){
				j++;
			}
		}
		endPosition = endPosition - 1;
		
		
		//设置保存上传文件的路径
		String realPath = getServletContext().getRealPath("/")+"images/upload";//这是服务器上的地址
		//System.out.println("保存上传文件的路径:"+realPath);
		File fileUploadFile = new File(realPath);
		if (!fileUploadFile.exists()) {
			fileUploadFile.mkdir();
		}
		File saveFile = new File(realPath, filename);
		RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile, "rw");
		//从临时文件当中读取文件内容(根据起止位置获取)
		randomFile.seek(startPosition);
		while (startPosition<endPosition) {
			randomAccessFile.write(randomFile.readByte());
			startPosition = randomFile.getFilePointer();
		}
		//关闭输入输出流、删除临时文件
		randomAccessFile.close();
		randomFile.close();
		
		//返回
		request.setAttribute("result", "上传成功!");
		RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/01.jsp");
		dispatcher.forward(request, response);
		
	}

}




二、文件下载

1、需要通过HttpServletResponse.setContentType方法设置Content-Type头字段的值,为浏览器无法使用某种方式或激活某哥程序来处理的MIME类型,例如,“application/octet-stream”或“application/x-msdownload”等。


2、需要通过HttpServletResponse.setHeader方法设置Content-Disposition头的值为“attachment;filename=文件名”。


3、读取下载文件,调用HttpServletResponse.getOutputStream方法返回的ServletOutputStream对象来向客户端写入附件文件内容。


实现【jsp+servlet】

(一)、配置web.xml【配置wen.xml,创建DownloadServlet】


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>UploadServlet</servlet-name>
    <servlet-class>com.wuhn.scxz.servlet.UploadServlet</servlet-class>
  </servlet>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>DownloadServlet</servlet-name>
    <servlet-class>com.wuhn.scxz.servlet.DownloadServlet</servlet-class>
  </servlet>
  
  <!-- 上传servlet -->	
  <servlet-mapping>
    <servlet-name>UploadServlet</servlet-name>
    <url-pattern>/UploadServlet.do</url-pattern>
  </servlet-mapping>
  <!-- 下载servlet -->
  <servlet-mapping>
    <servlet-name>DownloadServlet</servlet-name>
    <url-pattern>/DownloadServlet.do</url-pattern>

  </servlet-mapping>	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>



(二)、前台页面开发【通过超链接的方式发起文件下载请求】


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML>
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>下载</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link rel="stylesheet" type="text/css" href="<%=path%>/css/common.css">
	<script type="text/javascript" src="<%=path%>/js/jquery-1.11.1.js"></script>

  </head>
  
  <body>
    下载:<a href="<%=path%>/DownloadServlet.do?filename=test.txt">test.txt</a>    ${errorResult}
  </body>
</html>



(三)、后台Servlet【设置响应类型及响应头输出流写入文件内容】

package com.wuhn.scxz.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author wuhn
 * @创建时间 2015-12-07
 * @功能 下载文件
 * **/
public class DownloadServlet extends HttpServlet {
	/**
	 *get方法 
	 * **/
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获取文件下载路径
		String path = getServletContext().getRealPath("/")+"images/upload";
		String filename = request.getParameter("filename");
		File file = new File(path + filename); 
		if(file.exists()){
			//设置相应类型 
			response.setContentType("application/x-msdownload");//或者application/octet-stream
			//设置头信息
			response.setHeader("Content-Disposition", "attachment;filename=\""+filename+"\"");
			InputStream inputStream = new FileInputStream(file);
			ServletOutputStream outputStream = response.getOutputStream();
			byte b[] = new byte[1024];
			int n;
			while ((n=inputStream.read(b)) != -1) {
				outputStream.write(b, 0, n);
			}
			//关闭流、释放资源
			outputStream.close();
			inputStream.close();
			
		}else{
			request.setAttribute("errorResult", "文件不存在,下载失败!");
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/01.jsp");
			dispatcher.forward(request, response);
		}
	}

	/**
	 * post方法
	 * **/
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request,response);//默认为get
	}
}


三、项目代码【点击这里下载】












你可能感兴趣的:(文件上传和下载(一)--【jsp+servlet】)