1.設置響應行
格式:HTTP/1.1 200 ok
設置狀態碼:setStatus(int sc):傳入一個int型的狀態碼就把狀態碼設置了
2.設置響應頭:setHeader(String name,String value)
響應行+響應頭實現重定向
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 旗木五五開 * @create 2020-03-06 9:59 * 重定向 */ @WebServlet("/responseDemo1") public class ResponseDemo1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("1被訪問"); // 訪問responseDemo1會自動跳轉到responseDemo2 // 1.設置狀態碼為302 response.setStatus(302); // 2.設置響應頭:頭名稱:location,值:資源路徑 response.setHeader("location","/day15/responseDemo2"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 旗木五五開 * @create 2020-03-06 10:01 */ @WebServlet("/responseDemo2") public class ResponseDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("2被訪問"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
回車確定后1變2
控制台輸出
簡單的重定向response.sendRedirect
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 旗木五五開 * @create 2020-03-06 9:59 * 重定向 */ @WebServlet("/responseDemo1") public class ResponseDemo1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("1被訪問"); response.sendRedirect("/day15/responseDemo2"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
重定向的特點:redirect
①地址欄發生變化
②重定向可以訪問其他 站點(服務器)的資源
③重定向是兩次請求:不能使用request域來共享數據
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 旗木五五開 * @create 2020-03-06 9:59 * 重定向 */ @WebServlet("/responseDemo1") public class ResponseDemo1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("1被訪問"); request.setAttribute("sm","request"); response.sendRedirect("/day15/responseDemo2"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 旗木五五開 * @create 2020-03-06 10:01 */ @WebServlet("/responseDemo2") public class ResponseDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("2被訪問"); Object sm = request.getAttribute("sm"); System.out.println(sm); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
轉發的特點:forward
①轉發地址欄路徑不變
②轉發只能訪問當前服務器下的資源
③轉發是一次請求:可以使用request域來共享數據
路徑寫法
相對路徑:通過路徑不可以確定唯一資源。
規則:不以/開頭的,以 . 開頭路徑。不寫默認./當前路徑 ../后退一級的目錄。jsp頁面不推薦使用相對路徑
如:./index.html index.html
規則:找到當前資源 和目標資源的 相對位置關系
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>找到當前資源 和目標資源的 相對位置關系</h1> <p> 當前資源:localtion http://localhost/day15/localtion.html </p> <p> 目標資源:requestDemo2 http://localhost/day15/responseDemo2 </p> <a href="./responseDemo2"> responseDemo2 </a> <a href="responseDemo2"> responseDemo </a> </body> </html>
絕對路徑:通過路徑可以確定唯一資源。以/開頭的
如:http://localhost/day15/responseDemo2或者 /day15/responseDemo2
規則:判斷定義的路徑是給誰用的。判斷請求從哪發出。使用動態虛擬目錄
給客戶端瀏覽器使用:需要加虛擬目錄(項目的訪問路徑)。重定向、<A>、<form>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>絕對路徑</h1> <a href="/day15/responseDemo2"> responseDemo2 </a> </body> </html>
給服務器使用:不需要加虛擬目錄。轉發
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 旗木五五開 * @create 2020-03-07 17:32 */ @WebServlet("/responseDemo3") public class ResponseDemo3 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/responseDemo2").forward(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
動態的獲取虛擬目錄request.getContextPath()
html不行,jsp可以
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 旗木五五開 * @create 2020-03-06 9:59 * 重定向 */ @WebServlet("/responseDemo1") public class ResponseDemo1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 調用request請求頭方法 String contextPath = request.getContextPath(); // 拼接 虛擬目錄 資源路徑 response.sendRedirect(contextPath+"/responseDemo2"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
3.設置響應體:通過流的方式
使用步驟:
1.獲取輸出流
字符輸出流:只能輸出字符
PrintWiter getWiter():打印流
有兩種輸出數據的方式
write方法,
print方法:自動刷新(不刷新把數據寫出緩沖區的效果)
但是這個方法是response獲取的,上面兩個方法都可以自動刷新。response在一次響應完成之后會自動銷毀,獲取的流也會被自動關閉。
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @author 旗木五五開 * @create 2020-03-07 19:03 */ @WebServlet("/responseDemo4") public class ResponseDemo4 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.獲取字符輸出流 PrintWriter pw = response.getWriter(); // 2.輸出數據 pw.write("<h1>hello response</h1>"); /* 數據會被瀏覽器解析展示到頁面上 */ } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
解決中文亂碼:亂碼的原因:編碼解碼用的字符集不一致
瀏覽器打開默認的字符集和當前操作系統的語言環境有關系,現在用的是中文的Windows操作系統。打開瀏覽器默認的字符集(編碼表)就是GBK(國標擴展碼)或GB2312(國標碼)都是中文的碼表。
由此可知服務器用的不是GB2312
服務器用的是啥呢
解決方法:獲取去流對象之前,設置默認編碼
text/html;charset=utf-8 文本數據/值類型HTML;字符設置=utf-8
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @author 旗木五五開 * @create 2020-03-07 19:03 */ @WebServlet("/responseDemo4") public class ResponseDemo4 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.獲取流對象之前,設置默認編碼 /*光寫這行代碼不夠,如果瀏覽器用的不是GBK還是會亂碼。需要2*/ response.setCharacterEncoding("GBK"); // 2.設置響應體,告訴瀏覽器,服務器發送的消息體數據的編碼。建議瀏覽器使用該編碼解碼 /*這一行代碼可以代替1,一行代碼干兩件事*/ response.setHeader("content-type","text/html;charset=utf-8");
// 2的簡單的形式,設置編碼-----------------用這個 response.setContentType("text/html;charset=utf-8"); // 獲取字符輸出流 PrintWriter pw = response.getWriter(); // 輸出數據 pw.write("<h1>hello response</h1>"); /* 數據會被瀏覽器解析展示到頁面上 */ pw.write("你好 response"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
字節輸出流:能輸出任何數據
ServletOutputStream getOutputStream():當做OutputStream來使用
package cn.itcast.web.servlet; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 旗木五五開 * @create 2020-03-07 21:14 */ @WebServlet("/responseDemo5") public class ResponseDemo5 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 解決亂碼同上 response.setContentType("text/html;charset=utf-8"); // 1.獲取直接輸出流 ServletOutputStream sos = response.getOutputStream(); // 2.輸出數據 /*字節流輸出字符數據 getBytes()獲取字節數組 括號內可以設置編碼*/ sos.write("hello 你好".getBytes("utf-8")); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
2.使用輸出流,將數據輸出到客戶端瀏覽器
驗證碼
本質:圖片
目的:防止惡意表單注冊
圖片是怎么來的?
第一種:在文件夾中放很多圖片隨機顯示(第一種,一萬張圖片,通過窮舉的方式能把一萬張圖片弄完)
第二種:在程序中動態的生成,一張圖片,輸出到頁面上(隨機生成,要列舉出來所有的情況基本不可能)程序都采用的這種方式
package cn.itcast.web.servlet; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; /** * @author 旗木五五開 * @create 2020-03-07 21:37 */ @WebServlet("/checkCodServlet") public class CheckCodServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int width = 100; int height = 50; // 1.創建一個對象,在內存中代表一張圖片。 /*參數寬、高、圖片類型*/ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); // 2.美化圖片 // 2.1填充背景色 Graphics g = image.getGraphics();//畫筆對象 g.setColor(Color.PINK);//設置顏色,大小寫沒有區別 g.fillRect(0, 0, width, height);//填充 /*x和y在圖片中是左上角那個點,從左到右,從上到下*/ // 2.2給圖片畫一個邊框 g.setColor(Color.BLUE);//設置顏色,大小寫沒有區別 /*不減1,右邊和下邊就會畫到外面,無法顯示*/ g.drawRect(0, 0, width - 1, height - 1); // 驗證碼內容 String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; // 隨機角標 Random ran = new Random(); // 2.3寫驗證碼 for (int i = 1; i <= 4; i++) { // 最大值 int index = ran.nextInt(str.length()); // 獲取字符 char ch = str.charAt(index); g.drawString(ch + "", width / 5 * i, height / 2); } // 2.4畫干擾線 g.setColor(Color.GREEN);//顏色 // 畫線 for (int i = 0; i < 10; i++) { // 隨機生成坐標點 int x1 = ran.nextInt(width); int y1 = ran.nextInt(width); int x2 = ran.nextInt(width); int y2 = ran.nextInt(width); // 線段 g.drawLine(x1,y1,x2,y2); } // 3.將圖片輸出到頁面展示。因為現在圖片在內存中要輸出它需要一個對象 /*將內存中的一張圖片寫到頁面,任意的流中。參數圖片對象,圖片后綴名,OutputStream*/ /*后綴名是為了輸出到對應的文件使用的,頁面上無所謂*/ ImageIO.write(image, "jpg", response.getOutputStream()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
開發中使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script> /* * 分析: * 點擊超鏈接或者圖片,切換圖片 * 1.給超鏈接和圖片綁定單機事件 * 2.重新設置圖片的src屬性值 * 頁面加載完后 * */ window.onload = function () { // 1.給圖片綁定單機事件 var img = document.getElementById("checkCode"); // 2.綁定單機事件 img.onclick=function () { /* * 因為兩次請求圖片路徑一樣會被瀏覽器當做緩存 * */ //所以+時間戳 var date=new Date().getTime(); img.src="/day15/checkCodServlet?"+date; } // 給超鏈接綁定單機事件 var t=document.getElementById("change"); t.onclick=function () { /* * 因為兩次請求圖片路徑一樣會被瀏覽器當做緩存 * */ //所以+時間戳 var date=new Date().getTime(); img.src="/day15/checkCodServlet?"+date; } } </script> </head> <body> <img id="checkCode" src="/day15/checkCodServlet" alt=""> <a id="change"href="javascript:void(0)"> 看不清換一張</a> </body> </html>