JavaEE學習日誌持續更新----> 必看!JavaEE學習路線(文章總彙)
JavaEE學習日誌(五十二)
Response對象
負責對瀏覽器進行響應
HttpServletResponse接口繼承自ServletResponse接口
使用子接口HttpServletResponse接口,此接口對象由tomcat引擎提供。
Response設置響應行
設置狀態碼:setStatus(int 狀態碼)
response.setStatus(500);
Response設置響應頭
HTTP協議的響應頭,數據格式爲鍵值對k:v
包含指導性信息,指導客戶端
方法
addHeader(String add,String value)
添加,實現一個鍵對應多個值addIntHeader(String add,int value)
addDataHeader(String key,long l)
response.addHeader("heima","java");
response.addIntHeader("heima2",2);
response.addDateHeader("heima3",System.currentTimeMillis());
setHeader(String add,String value)
設置,覆蓋原來的鍵(用這個)setIntHeader(String add,int value)
setDataHeader(String key,long l)
response.setHeader("heima","javaee");
Response設置響應體
HTTP的響應體,就是頁面的正文部分
方法
getWriter()
返回值是打印流PrintWriter
PrintWriter pw = response.getWriter();
pw.write("hehe");
pw.print("xixi");
write()
和print()
的區別
write()
:使用字符串數據,沒有差別;輸出的是整數,查詢編碼表
print()
:無論是什麼,原樣打印
響應中的中文亂碼問題
產生亂碼的原因:編碼和解碼不一致。響應數據時,沒有直接寫在客戶端,而是寫在response對象緩衝區,而緩衝區使用的編碼表是ios8859-1拉丁文編碼。
解決方法一:
設置response對象緩衝區的編碼表,並通知瀏覽器,使用utf-8解碼
方法:setCharacterEncoding("編碼表")
這種方法谷歌瀏覽器好像不行,其他瀏覽器可以。
response.setCharacterEncoding("utf-8");
PrintWriter pw = response.getWriter();
pw.write("<meta charset='utf-8'>");
pw.write("你好");
解決方法二(就用它):
方法:setContentType("text/html;charset=UTF-8")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.write("你好");
}
getOutputStream()
返回字節輸出流OutputStream
返回字節流,響應非文本類型的數據
在Web目錄下添加a.jgp文件,輸出a.jpg
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
響應非文本類型數據
*/
//獲取圖片的絕對路徑
String aFile = getServletContext().getRealPath("a.jpg");
FileInputStream fis = new FileInputStream(aFile);
OutputStream out = response.getOutputStream();
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes))!=-1){
out.write(bytes,0,len);
}
fis.close();
}
重定向(重點)
概念
接收瀏覽器的請求,對瀏覽器進行響應,瀏覽器進行重新的定向:
- 302狀態碼
- 重定向資源的地址:響應頭
代碼示例:servlet1重定向到servlet2
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
接收瀏覽器的請求,對瀏覽器進行響應
瀏覽器進行重新的定向:
302狀態碼
重定向資源的地址:響應頭
*/
response.setStatus(302);
response.setHeader("location","/Web03/servlet2");
}
簡便寫法:response.sendRedirect("/Web03/servlet2");
重定向到百度
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
接收瀏覽器的請求,對瀏覽器進行響應
瀏覽器進行重新的定向:
302狀態碼
重定向資源的地址:響應頭
*/
/*response.setStatus(302);
response.setHeader("location","/Web03/servlet2");*/
response.sendRedirect("http://www.baidu.com");
}
Response注意事項
- 重定向後,不要再寫代碼,沒有意義
- 不能多次重定向
getWriter()
字符流和getOutputStream()
字節流互斥,只能選擇一個使用。(因爲當servlet執行完成之後,緩衝區纔會發送數據,那麼緩衝區到底是字符的,還是字節的)
文件下載
客戶端瀏覽器從服務器下載文件
實現:超鏈接,連接的地址是服務器端文件的路徑
會出現一個問題:當瀏覽器識別文件,不是下載,直接打開運行
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
a:link{color: black}
a:visited{color: black}
</style>
</head>
<body>
<!--超鏈接,實現文件下載
連接的地址,服務器端需要下載的文件的路徑
-->
<a href="/Web03/download/a.flv">a.flv</a>
<a href="/Web03/download/a.jpg">a.jpg</a>
<a href="/Web03/download/a.mp3">a.mp3</a>
<a href="/Web03/download/a.mp4">a.mp4</a>
<a href="/Web03/download/a.txt">a.txt</a>
<a href="/Web03/download/a.zip">a.zip</a>
</body>
</html>
所以需要編寫服務器端代碼,告訴瀏覽器下載,不要打開
關鍵代碼:告訴瀏覽器,此文件下載
response.setHeader("Content-Disposition","attachment;filename=a.jpg");
具體程序
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
通過服務器端下載,不要打開
指導瀏覽器幹什麼:響應頭
瀏覽器下載是HTTP協議規定
*/
response.setHeader("Content-Disposition","attachment;filename=a.jpg");
String aFile = getServletContext().getRealPath("download/a.jpg");
FileInputStream fis = new FileInputStream(aFile);
OutputStream out = response.getOutputStream();
int len = 0;
byte[] bytes = new byte[1024];
while((len = fis.read(bytes))!=-1){
out.write(bytes,0,len);
}
fis.close();
}
前端
<!--超鏈接,連接地址不是文件,而是Servlet-->
<a href="/Web03/downLoad">a.jpg</a>
文件下載(中文文件名)
jdk8之前:直接導包使用
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 編寫程序,通知瀏覽器請你下載,不要打開
* 指導瀏覽器幹什麼,響應頭
* 瀏覽器下載是HTTP協議規定
*/
String agent = request.getHeader("User-Agent");
String filename="美女.jpg";
if (agent.contains("MSIE")) {
// IE瀏覽器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐瀏覽器
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它瀏覽器
filename = URLEncoder.encode(filename, "utf-8");
}
response.setHeader("Content-Disposition","attachment;filename="+filename);
String aFile = getServletContext().getRealPath("download/a.jpg");
FileInputStream fis = new FileInputStream(aFile);
OutputStream out = response.getOutputStream();
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes))!=-1){
out.write(bytes,0,len);
}
fis.close();
}
jdk8之後:需要下載Apache的commons-codec才能使用。
import org.apache.commons.codec.binary.Base64;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
通過服務器端下載,不要打開
指導瀏覽器幹什麼:響應頭
瀏覽器下載是HTTP協議規定
*/
String agent = request.getHeader("User-Agent");
String filename="美女.jpg";
if (agent.contains("MSIE")) {
// IE瀏覽器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐瀏覽器
Base64 base64 = new Base64();
filename = "=?utf-8?B?" + base64.encodeBase64String(filename.getBytes("utf-8")) + "?=";
} else {
// 其它瀏覽器
filename = URLEncoder.encode(filename, "utf-8");
}
response.setHeader("Content-Disposition","attachment;filename="+filename);
String aFile = getServletContext().getRealPath("download/a.jpg");
FileInputStream fis = new FileInputStream(aFile);
OutputStream out = response.getOutputStream();
int len = 0;
byte[] bytes = new byte[1024];
while((len = fis.read(bytes))!=-1){
out.write(bytes,0,len);
}
fis.close();
}
驗證碼
驗證碼的本質就是一個圖片,圖片裏面是一個隨機生產的字符串
生成驗證碼
public class CodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 創建畫布
int width = 120;
int height = 40;
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 獲得畫筆
Graphics g = bufferedImage.getGraphics();
// 填充背景顏色
g.setColor(Color.white);
g.fillRect(0, 0, width, height);
// 繪製邊框
g.setColor(Color.red);
g.drawRect(0, 0, width - 1, height - 1);
// 生成隨機字符
// 準備數據
String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
// 準備隨機對象
Random r = new Random();
// 聲明一個變量 保存驗證碼
String code = "";
// 書寫4個隨機字符
for (int i = 0; i < 4; i++) {
// 設置字體
g.setFont(new Font("宋體", Font.BOLD, 28));
// 設置隨機顏色
g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
String str = data.charAt(r.nextInt(data.length())) + "";
g.drawString(str, 10 + i * 28, 30);
// 將新的字符 保存到驗證碼中
code = code + str;
}
// 繪製干擾線
for (int i = 0; i < 6; i++) {
// 設置隨機顏色
g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
}
// 將驗證碼 打印到控制檯
System.out.println(code);
// 將驗證碼放到session中
request.getSession().setAttribute("code_session", code);
// 將畫布顯示在瀏覽器中
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
前端
注意:頁面打開的時候,請求了服務器資源/Web03/code;點擊圖片的時候js函數中,發了請求/Web03/code。請求的資源沒有變化,服務器端程序也沒有變化,所以瀏覽器就會拿緩存。
所以有要求:每次請求不一樣,添加參數
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--
實現驗證碼效果
本質圖片:img src=屬性值是服務器資源CodeServlet
-->
<img src="/Web03/code" onclick="fnchange()" id="code">
<script type="text/javascript">
function fnchange() {
/*
頁面打開的時候,請求了服務器資源/Web03/code
點擊圖片的時候js函數中,發了請求/Web03/code
請求的資源沒有變化,服務器端程序也沒有變化
所以瀏覽器就拿了緩存
所以有要求:每次請求不一樣,添加參數
*/
//點擊圖片,修改src的屬性值
var code = document.getElementById("code");
var date = new Date().getTime();
code.src="/Web03/code?a="+date;
}
</script>
</body>
</html>