servlet 下载

下载
1. 下载就是向客户端响应字节数据!
  原来我们响应的都是html的字符数据!
  把一个文件变成字节数组,使用response.getOutputStream()来各应给浏览器!!!

2. 下载的要求
  * 两个头一个流!
    > Content-Type:你传递给客户端的文件是什么MIME类型,例如:image/pjpeg
      * 通过文件名称调用ServletContext的getMimeType()方法,得到MIME类型!
    > Content-Disposition:它的默认值为inline,表示在浏览器窗口中打开,

有的浏览器哦是打开下载框!attachment;filename=xxx 弹出框的文件名称,就是xxx
      * 在filename=后面跟随的是显示在下载框中的文件名称!
    > 流:要下载的文件数据!
      * 自己new一个输入流即可!

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	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_2_5.xsd">
  <display-name></display-name>	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>download1</servlet-name>
  	<servlet-class>cn.itcast.web.servlet.Download1Servlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>download1</servlet-name>
  	<url-pattern>/down1</url-pattern>
  </servlet-mapping>
</web-app>

public class Download1Servlet extends HttpServlet {
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
    	throws ServletException, IOException {
    /*
     * 两个头一个流
     * 1. Content-Type
     * 2. Content-Disposition
     * 3. 流:下载文件的数据
     */
    String filename = "e:/许端阳.mp3";
    String contentType = this.getServletContext().getMimeType(filename);//通过文件名称获取MIME类型
    String contentDisposition = "attachment;filename=许端阳.mp3";
    // 一个流
    FileInputStream input = new FileInputStream(filename);//把文件变成一个流
    //设置头
    resp.setHeader("Content-Type", contentType);
    resp.setHeader("Content-Disposition", contentDisposition);
    // 获取绑定了响应端的流
    ServletOutputStream output = resp.getOutputStream();
    IOUtils.copy(input, output);//把输入流FileInputStream input中的数据写入到输出流ServletOutputStream output中。
    input.close();
	}
	

 String contentDisposition = "attachment;filename=许端阳.mp3"; 如果filename 没有进行编码的话

文件的名称是没有名字是乱码

处理这个问题的方法是

  * FireFox:Base64编码。
  * 其他大部分浏览器:URL编码。

通用方案:filename = new String(filename.getBytes("GBK"), "ISO-8859-1");

修改以后的演示

	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
    	throws ServletException, IOException {
    /*
     * 两个头一个流
     * 1. Content-Type
     * 2. Content-Disposition
     * 3. 流:下载文件的数据
     */
    String filename = "e:/许端阳.mp3";
    String freamname = new String("许端阳.mp3".getBytes("GBK"), "ISO-8859-1");
    String contentType = this.getServletContext().getMimeType(filename);//通过文件名称获取MIME类型
    String contentDisposition = "attachment;filename="+freamname;
    // 一个流
    FileInputStream input = new FileInputStream(filename);//把文件变成一个流
    //设置头
    resp.setHeader("Content-Type", contentType);
    resp.setHeader("Content-Disposition", contentDisposition);
    // 获取绑定了响应端的流
    ServletOutputStream output = resp.getOutputStream();
    IOUtils.copy(input, output);//把输入流FileInputStream input中的数据写入到输出流ServletOutputStream output中。
    input.close();
	}

这种方式也是好用的,但是可能对于一些特殊字符是不管用的,只能是用下面那种方法

// 用来对下载的文件名称进行编码的!
	public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
    String agent = request.getHeader("User-Agent"); //获取浏览器
    if (agent.contains("Firefox")) {//由于base64 只有火狐浏览器是有问题的
    	BASE64Encoder base64Encoder = new BASE64Encoder();
    	filename = "=?utf-8?B?"
        	+ base64Encoder.encode(filename.getBytes("utf-8"))
        	+ "?=";
    } else if(agent.contains("MSIE")) {//微软的其他浏览器就是和采用的都是同样的url 编码
    	filename = URLEncoder.encode(filename, "utf-8");
    } else {
    	filename = URLEncoder.encode(filename, "utf-8");
    }
    return filename;
	}

猜你喜欢

转载自blog.csdn.net/qq_20610631/article/details/81141885