测试两种下载:浏览器通过服务器下载其他网站文件(http协议);浏览器下载服务器本地硬盘里的文件(file协议)
1.工具类downloadUtils.java的核心部分
//服务器使客户端可以从远程url下载文件
public void download(String fileUrl, HttpServletResponse response) throws ServletException, IOException {
String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") +1, fileUrl.length());// 文件名称
URL url = new URL(fileUrl);
URLConnection conn = url.openConnection();
int filesize = conn.getContentLength(); // 取数据长度
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
// 清空response
response.reset();
// 文件名称转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名
response.addHeader("Content-Disposition",
"attachment;filename=" + new String(fileName.getBytes("utf-8"), "iso8859-1"));
response.addHeader("Content-Length", "" + filesize);
BufferedOutputStream os = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
// 从输入流中读入字节流,然后写到文件中
byte[] buffer = new byte[1024];
int nRead;
while ((nRead = bis.read(buffer, 0, 1024)) > 0) { // bis为网络输入流
os.write(buffer, 0, nRead);
}
bis.close();
os.flush();
os.close();
}
2.Servlet核心部分webxmlServlet.java(只需看doGet方法即可,其他的可不看):
package test;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class webxmlServlet
*/
public class webxmlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public webxmlServlet() {
super();
// TODO Auto-generated constructor stub
}
public void init()
{
String userName;
String userName1;
String path;
try {
ServletConfig config = getServletConfig();
userName = config.getInitParameter("username");
userName1 = this.getInitParameter("username");
path = config.getInitParameter("path");
System.out.println("初始化获得的userName:"+userName);//初始化获得的userName:admin
System.out.println("初始化获得的userName1:"+userName1);//初始化获得的userName1:admin
System.out.println("初始化获得的path:"+path);//初始化获得的path:null
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
System.out.println("webxmlServlet的doGet开始。。。");
//1.服务器使客户端从网络上下载文件
String url = "http://apps.bdimg.com/libs/accounting.js/0.3.2/accounting.min.js";
fileDownload fd = new fileDownload();
// fd.download(url, response);
//2.服务器从本地拿文件给和客户端
String localUrl = "file:///D:/test/test1.txt";
fd.download(localUrl, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
注意:doGet方法中写了两种测试方法:
1.一种是浏览器从其他网站下资源,本地的服务器只是提供这种链接下载的服务,使客户端可以不需要能访问这个url即可下载此资源,服务器代为传输下载,即服务器提供链接和传输中介服务。使用http协议。
2.另一种是浏览器从服务器的本地设备中获取,即服务器从自己硬盘中拿出文件给客户端。使用本地文本传输协议file协议。这种更常见。
3.这两种服务都需要使用协议不管是http协议还是本地文本传输协议file协议。
4.doGet中这个两种方法必须有分开测试,即测试一个注释一个,不然一个测试I/O流关闭后会导致另一个报错,你也可以new两次fileDownload。我是为了测试效果,才测一个注掉一个。
3.web.xml(需要手动在WEB-INF目录下手动新建目录classes/log4j.properties)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>path</param-name>
<param-value>/WEB-INF/config.properties</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<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>CheckAccount</servlet-name>
<servlet-class>com.ht.servlet.CheckAccount</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>admin</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>CheckAccount</servlet-name>
<url-pattern>/CheckAccount</url-pattern>
</servlet-mapping>
<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>webxmlServlet</servlet-name>
<servlet-class>test.webxmlServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>admin</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>webxmlServlet</servlet-name>
<url-pattern>/webxmlServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>40</session-timeout>
</session-config>
<error-page>
<error-code>404</error-code>
<location>/login.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/login.jsp</location>
</error-page>
<!-- <filter>
<filter-name>Encoding</filter-name>
<filter-class>ghjf.test.filter.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> -->
</web-app>
在启动servlet后,需要测试。
4.用浏览器打开点击链接测试的HTML页面testServletDownload.html:
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>测试客户端下载文件页面</title>
</head>
<body>
<a href="http://localhost:8080/demoProj/webxmlServlet">点我下载文件</a>
</body>
</html>