繼續上一篇HttpServletRequest和HttpServletResponse的學習,應用於下載網頁上提供的文件資源.
鏈接在這:HttpServletRequest和HttpServletResponse的初步學習
1.下載資源有三種方式
- 直接以超鏈接的方式下載,讓tomcat的默認Servlet(DefaultServlet)去提供下載,DefaultServlet專門用於處理放在tomcat服務器上的靜態資源。
- 手動編碼提供下載
- 手動編碼提供下載帶有中文名字的資源
樣例代碼給出~
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
HttpServletResponse,下載資源<br>
1.直接以超鏈接的方式下載<br>
<a href="download/a.jpg">a.jpg</a><br>
<a href="download/b.jpg">b.jpg</a><br>
<a href="download/c.jpg">c.jpg</a><br>
2.手動編碼提供下載<br>
<a href="Download?filename=a.jpg">a.jpg</a><br>
<a href="Download?filename=b.jpg">b.jpg</a><br>
<a href="Download?filename=c.jpg">c.jpg</a><br>
3.手動編碼提供下載帶有中文名字的資源<br>
<a href="Download?filename=a.jpg">a.jpg</a><br>
<a href="Download?filename=b.jpg">b.jpg</a><br>
<a href="Download?filename=c.jpg">c.jpg</a><br>
<a href="Download?filename=快樂.jpg">快樂.jpg</a><br>
</body>
</html>
對應的Servlet代碼給出~
Download.java
package cw.Servlet;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sun.misc.BASE64Encoder;
/**
* Servlet implementation class Download
*/
public class Download extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//獲取要下載的文件名字
String filename=request.getParameter("filename");
//來一個get請求,這個filename有中文
filename=new String(filename.getBytes("ISO-8859-1"),"UTF-8");
System.out.println("filename="+filename);
//獲取這個文件在tomcat裏面的絕對路徑地址
String path=getServletContext().getRealPath("Download/"+filename);
/*
* 如果文件的名字帶有中文,需要隊整個文件名進行編碼處理
* 針對瀏覽器類型,對文件名字做編碼處理,如果是IE,或者是chrome,使用URLEncoding編碼
* 如果是Firefox,使用Base64編碼
*/
//對中文的名字進行編碼處理
//獲取來訪的客戶端類型
String client_type=request.getHeader("User-Agent");
if(client_type.contains("Firefox")){
filename=firefox(filename); //調用編碼處理過後filename的firefox函數
}else{
filename=URLEncoder.encode(filename,"UTF-8");
}
//讓瀏覽器收到資源時,以下載的方式提醒用戶,而不是直接展示
response.setHeader("Content-Disposition", "attachment;filename="+filename);
//轉換成輸入流
InputStream is=new FileInputStream(path);
OutputStream os=response.getOutputStream();
int len=0;
byte[] buffer=new byte[1024];
while((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
}
os.close();
is.close();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
public String firefox(String name){
BASE64Encoder base64=new BASE64Encoder();
try{
return "=?UTF-8?B?"+new String(base64.encode(name.getBytes("UTF-8")))+"?=";
}catch(UnsupportedEncodingException e){
e.printStackTrace();
throw new RuntimeException();
}
}
}
2.地址重定向與請求轉發的區別
- 重定向:地址上顯示的是最後的那個資源的路徑地址
localhost:9000/JavaWeb_1/login_success.html
1).請求次數最少有兩次,服務器在第一次請求後,會返回302以及一個地址,瀏覽器再根據這個地址執行第二次訪問
2).可以跳轉到任意路徑,不是自己的工程也可以跳
3).執行兩次請求,效率較低
4).後續的請求,沒法使用上一次的request存儲的數據,或者沒法使用上一次的request對象,因爲是兩次不同的請求
- 請求轉發:地址上顯示的請求servlet的地址
localhost:9000/JavaWeb_1/loginS?username=admin&password=123&登陸=提交
1).請求次數只有一次,因爲是服務器內部幫客戶端執行了後續的工作
2).只能跳轉到自己項目的資源路徑
3).因爲只執行一次請求,所以效率較高
4).可以使用上一次的request對象
樣例代碼給出~
login.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>請輸入登陸信息</h2>
<!-- <form action="LoginServlet" method="get"> -->
<!-- <form action="HServlet" method="get"> -->
<form action="loginS" method="get">
賬號:<input type="text" name="username" />
密碼:<input type="text" name="password" />
<input type="submit" name="登陸" />
</form>
</body>
</html>
login_success.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>登陸成功!</h2>
</body>
</html>
loginS.java
package cw.Servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class loginS
*/
public class loginS extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=UTF-8");
String username=request.getParameter("username");
String password=request.getParameter("password");
if("admin".equals(username)&&"123".equals(password)){
response.getWriter().write("登陸成功!");
//1.重定向
/* 早期的寫法
response.setStatus(302);
response.setHeader("location", "login_success.html");
*/
//重定向的寫法:重新定位方向
//response.sendRedirect("login_success.html");
//2.請求轉發的寫法
request.getRequestDispatcher("login_success.html").forward(request, response);
}else{
response.getWriter().write("登陸失敗!");
}
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}