Http響應response
response:響應
作用: 往瀏覽器寫東西
組成部分: 響應行 響應頭 響應體
操作響應行 格式: 協議/版本 狀態碼 狀態碼說明
狀態碼: 1xx:已發送請求 2xx:已完成響應 200:正常響應 3xx:還需瀏覽器進一步操作 302:重定向 配合響應頭:location 304:讀緩存 4xx:用戶操作錯誤 404:用戶操作錯誤. 405:訪問的方法不存在 5xx:服務器錯誤 500:內部異常
常用方法: setStatus(int 狀態碼):針對於 1xx 2xx 3xx 了解 :sendError(int 狀態碼):針對於 4xx和5xx
操作響應頭
格式: key:value(value可以是多個值)
常用的方法: setHeader(String key,String value):設置字符串形式的響應頭 了解:setIntHeader(String key,int value):設值整形的響應頭 了解:setDateHeader(String key,long value):設值時間的響應頭 addHeader(String key,String value):添加字符串形式的響應頭 之前設置過則追加,若沒有設置過則設置 了解:addIntHeader(String key,int value):添加整形的響應頭 了解:addDateHeader(String key,long value):添加時間的響應頭
常用的響應頭: location:重定向 refresh:定時刷新 content-type:設置文件的mime類型,設置響應流的編碼及告訴瀏覽器用什么編碼打開 content-disposition:文件下載
重定向: 方式1: ★response.sendRedirect("/day10/loc2"); 方式2: response.setStatus(302); respooen.setHeader("location","/day10/loc2");
案例1:請求重定向
web.xml文件配置
<servlet>
<servlet-name>SHServlet1</servlet-name>
<servlet-class>com.hjh.request_response.SHServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SHServlet1</servlet-name>
<url-pattern>/servlet1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SHServlet2</servlet-name>
<servlet-class>com.hjh.request_response.SHServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SHServlet2</servlet-name>
<url-pattern>/servlet2</url-pattern>
</servlet-mapping>
SHServlet1.java源碼
package com.hjh.request_response; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class SHServlet1 extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //重定向方式一 //1.設置狀態碼
response.setStatus(302); //2.設置響應頭 //response.setHeader("location", "/Servlet/servlet2"); //重定向方式二:設置響應頭
response.sendRedirect("/Servlet/servlet2"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
SHServlet2.java源碼:
package com.hjh.request_response; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class SHServlet2 extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().print("跳轉到這里啦,哈哈哈"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
項目運行,在瀏覽器中輸入“http://localhost:8080/Servlet/servlet1”,回車,url變為“http://localhost:8080/Servlet/servlet2”,瀏覽網頁輸出為:“跳轉到這里啦,哈哈哈”
定時刷新: 方案1:設置頭 refresh respooen.setHeader("refresh","秒數;url=跳轉的路徑"); 方案2:http的meta標簽 <meta http-equiv="refresh" content="3;url=/day10/refresh2.html">
案例參見servlet博文:https://www.cnblogs.com/hejh/p/10942445.html
package com.hjh.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.hjh.domain.User; import com.hjh.service.UserService; public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.設置編碼
response.setContentType("text/html;charset=utf-8"); //2.接收用戶名和密碼
String username = request.getParameter("username"); String password = request.getParameter("password"); //3.調用UserService的login(username,password),返回一個user對象
User user = new UserService().login(username,password); //4.判斷user是否為空
if(user==null) { //user為空
response.getWriter().print("用戶名和密碼不匹配,3秒后跳轉"); //優化,定時跳轉 response.setHeader("refresh","3;url=/Servlet/login.html"); }else { //user為不為空
response.getWriter().print(user.getUsername()+":歡迎回來"); } } }
案例二:
refresh1.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- http-equiv:響應頭 content:響應體 -->
<meta http-equiv="refresh" content="3;url=/Servlet/refresh2.html" >
<title>注冊頁面</title>
</head>
<body> 注冊成功,<span id="sid">5</span>秒之后跳轉到登錄頁面 </body>
<script type="text/javascript"> onload=function(){ //設置定時器
setInterval(changeS,1000); } i=5; function changeS(){ //1.獲取元素
var obj = document.getElementById("sid"); //2.操作元素的標簽體
obj.innerHTML=--i; } </script>
</html>
refresh2.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登錄頁面</title>
</head>
<body> 訪問前,請先進行登錄! </body>
</html>
啟動項目,在瀏覽器中輸入“http://localhost:8080/Servlet/refresh1.html”,回車,頁面顯示顯示:
;
頁面上時間會自減,5秒后頁面跳轉到refresh2.html
操作響應體:頁面上要展示的內容
常用方法: Writer getWriter():字符流 ServletOutputStream getOutputStream() :字節流 自己寫的東西用字符流,其他一概用字節流. 處理響應中文亂碼: 方式1:★ response.setContentType("text/html;charset=utf-8"); 方式2:理解 response.setHeader("content-type", "text/html;charset=utf-8");
注意:
兩個流互斥。當響應完成之后,服務器會判斷一下流是否已經關閉,若沒有關閉,服務器會幫我們關閉.(底層使用的緩沖流)
案例:
web.xml配置信息如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>PrintServlet</servlet-name>
<servlet-class>com.hjh.servlet.PrintServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PrintServlet</servlet-name>
<url-pattern>/print</url-pattern>
</servlet-mapping>
</web-app>
PrintServlet.java源碼如下:
package com.hjh.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PrintServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //處理響應的中文亂碼
response.setContentType("text/html;charset=utf-8"); //打印表格 //獲取字符流
PrintWriter writer = response.getWriter(); writer.print("<table border='1'><tr>"); writer.print("<td>用戶名:</td>"); writer.print("<td>tom</td></tr>"); writer.print("<tr><td>密碼:</td>"); writer.print("<td>123</td>"); writer.print("</tr></table>"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
在沒有紅色標注的這段代碼時,啟動項目訪問,瀏覽器中顯示的是以下數據:
在加上紅色標注的代碼時,啟動項目訪問,瀏覽器中顯示的是以下數據:
文件下載:
下載方式: 1.超鏈接下載 <a href="/day10/download/day10.txt">下載 day10.txt</a> 若瀏覽器能解析該資源的mime類型,則打開;若不能接下則下載;
2.編碼下載 通過servlet完成 <a href="/day10/download?name=day10.txt">下載 day10.txt</a> a.設置文件的mime類型 String mimeType=context.getMimeType(文件名) response.setContentType(mimeType); b.設置下載頭信息 content-disposition response.setHeader("content-disposition", "attachment;filename="+文件名稱); c.提供流 response.getOutputStream();
1.超鏈接下載文件:
download.html內容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>超鏈接文件下載</title>
</head>
<body>
<a href='/Servlet/file/1.html'>1.html</a>
<a href='/Servlet/file/2.txt'>2.txt</a>
<a href='/Servlet/file/3.docx'>3.docx</a>
</body>
</html>
啟動項目,瀏覽器中輸入url回車,頁面顯示如下:
點擊1.html這個超鏈接,瀏覽器能夠識別html的文件類型,所以將1.html文件內容顯示在瀏覽器中,頁面顯示如下:
點擊2.txt這個超鏈接,瀏覽器能夠識別txt的文件類型,所以將2.txt文件內容顯示在瀏覽器中,頁面顯示如下:
點擊3.docx這個超鏈接,瀏覽器無法識別docx的文件類型,瀏覽器中彈出選擇下載保存位置,頁面顯示如下:
案例二:編碼下載,通過servlet實現
download2.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>超鏈接文件下載</title>
</head>
<body>
<a href="/Servlet/download?name=1.html">1.html</a><br/>
<a href="/Servlet/download?name=2.txt">2.txt</a><br/>
<a href="/Servlet/download?name=3.docx">3.docx</a><br/>
</body>
</html>
DownloadServlet.java源碼:
package com.hjh.servlet; import java.io.IOException; import java.io.InputStream; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲取當前下載文件的文件名
String fileName = request.getParameter("name"); System.out.println(fileName); //獲取上下文
ServletContext context = this.getServletContext(); //文件下載 //1.首先獲取文件的mime類型,並設置其類型
String mimeType = context.getMimeType(fileName); response.setContentType(mimeType); //2.設置下載的頭信息
response.setHeader("content-disposition", "attchment;filename="+fileName); //3.對拷流 //3.1獲取輸入流
InputStream is = context.getResourceAsStream("/file/"+fileName); //3.2獲取輸出流
ServletOutputStream os = response.getOutputStream(); int len = -1; byte[] b = new byte[1024]; while((len=is.read(b))!=-1) { os.write(b, 0,len); } //關閉流
os.close(); is.close(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
web.xml配置:
<servlet>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>com.hjh.servlet.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
啟動項目,瀏覽器中輸入url,回車,頁面顯示如下:
點擊1.html、2.txt、3.docx超鏈接,瀏覽器中彈出選擇下載保存位置,頁面顯示如下:
文件下載優化:解決文件名帶中文
download.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>超鏈接文件下載</title>
</head>
<body>
<a href='/Servlet/file/1a.html'>1a.html</a>
<a href='/Servlet/file/2.txt'>2.txt</a>
<a href='/Servlet/file/3答案.docx'>3答案.docx</a>
</body>
</html>
工具類DownLoadUtils.java源碼:
package com.hjh.util; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import sun.misc.BASE64Encoder; public class DownLoadUtils { public static String getName(String agent, String filename) throws UnsupportedEncodingException { 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"); } return filename; } }
DownloadServlet.java源碼:
package com.hjh.servlet; import java.io.IOException; import java.io.InputStream; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import com.hjh.util.DownLoadUtils; public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲取當前下載文件的文件名
String fileName = request.getParameter("name"); //System.out.println(fileName); //解決文件下載文件名帶中文問題,方式1
fileName = new String(fileName.getBytes("iso8859-1"),"utf-8"); //獲取上下文
ServletContext context = this.getServletContext(); //文件下載 //1.首先獲取文件的mime類型,並設置其類型
String mimeType = context.getMimeType(fileName); response.setContentType(mimeType); //2.設置下載的頭信息
response.setHeader("content-disposition", "attachment;filename="+fileName); //通過工具類編碼;解決文件下載文件名帶中文問題,方式2
//String filename = DownLoadUtils.getName(request.getHeader("user-agent"), fileName); //response.setHeader("content-disposition", "attachment;filename="+filename); //3.對拷流 //3.1獲取輸入流
InputStream is = context.getResourceAsStream("/file/"+fileName);//方式2,fileName應改為filename //3.2獲取輸出流
ServletOutputStream os = response.getOutputStream(); // int len = -1; // byte[] b = new byte[1024]; // while((len=is.read(b))!=-1) { // os.write(b, 0,len); // }
IOUtils.copy(is, os); //關閉流
os.close(); is.close(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
代碼優化:引入commons-io-1.4.jar包
在代碼中以下面紅色部分代碼替代黃色部分代碼:
IOUtils.copy(is, os);
代替
int len = -1;
byte[] b = new byte[1024];
while((len=is.read(b))!=-1) {
os.write(b, 0,len);
}
案例:驗證碼
web.xml配置:
<servlet>
<servlet-name>CodeServlet</servlet-name>
<servlet-class>com.hjh.servlet.CodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CodeServlet</servlet-name>
<url-pattern>/code</url-pattern>
</servlet-mapping>
code.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>驗證碼</title>
</head>
<body>
<img alt="驗證碼" src="/Servlet/code" title="看不清,換一張" onclick="changeImg(this)">
</body>
<script type="text/javascript"> function changeImg(obj){ //操作src屬性
obj.src="/Servlet/code?i="+Math.random(); } </script>
</html>
CodeServlet.java源碼:
package com.hjh.servlet; import javax.servlet.http.HttpServlet; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CodeServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { // 使用java圖形界面技術繪制一張圖片
int charNum = 4; int width = 30 * 4; int height = 30; // 1. 創建一張內存圖片
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 2.獲得繪圖對象
Graphics graphics = bufferedImage.getGraphics(); // 3、繪制背景顏色
graphics.setColor(Color.YELLOW); graphics.fillRect(0, 0, width, height); // 4、繪制圖片邊框
graphics.setColor(Color.BLUE); graphics.drawRect(0, 0, width - 1, height - 1); // 5、輸出驗證碼內容
graphics.setColor(Color.RED); graphics.setFont(new Font("宋體", Font.BOLD, 20)); // 隨機輸出4個字符
Graphics2D graphics2d = (Graphics2D) graphics; String s = "ABCDEFGHGKLMNPQRSTUVWXYZ23456789"; Random random = new Random(); //session中要用到
String msg=""; int x = 5; for (int i = 0; i < 4; i++) { int index = random.nextInt(32); String content = String.valueOf(s.charAt(index)); msg+=content; double theta = random.nextInt(45) * Math.PI / 180; //讓字體扭曲
graphics2d.rotate(theta, x, 18); graphics2d.drawString(content, x, 18); graphics2d.rotate(-theta, x, 18); x += 30; } // 6、繪制干擾線
graphics.setColor(Color.GRAY); for (int i = 0; i < 5; i++) { int x1 = random.nextInt(width); int x2 = random.nextInt(width); int y1 = random.nextInt(height); int y2 = random.nextInt(height); graphics.drawLine(x1, y1, x2, y2); } // 釋放資源
graphics.dispose(); // 圖片輸出 ImageIO
ImageIO.write(bufferedImage, "jpg", response.getOutputStream()); } public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { doGet(request, response); } }
啟動項目,輸入url,回車,頁面顯示如下,點擊二維碼區域,二維碼刷新: