一】原理
1)web容器(tomcat等)會傳入與web容器相關的HttpServletRequest和HttpServletResponse的實現。
2)每一次瀏覽器的請求web服務器都會創建一個新的HttpServletReques和ServletResponse對象,並且
這兩個對象的聲明周期僅限於web容器內。
二】response對象常用方法
1》setStatues
2》setHeader
3》getWriter
4》getOutputStream
三】response常見應用
1)向瀏覽器輸出數字
原理:
無論是ServletOutputStream對象還是ServletWrite對象的write(int c);方法
都會自動將c去查詢iso8859-1編碼表,並取出相應的字符傳送到客戶端,
所以輸入的是數字,客戶端得到的卻是對應的字符。
解決辦法:
將數字轉換成字符串,再通過字符串的形式進行輸出。
又因為OutputStream對象write()方法參數中不支持對字符串的輸出,所以需要通過getBytes方法進行轉換
而ServletWriter的write()方法參數支持字符串的輸出,所以可以直接輸出,不必轉換
code:
response.getOutputStream().write(97);//a response.getWriter().write(65);//A response.getOutputStream().write((97+"").getBytes());//97 response.getWriter().write(65+"");//65
2)向瀏覽器輸出中文字符【重點】
原因:
1》byte[] getBytes();方法在進行編碼的時候會按照當前的編碼方式進行編碼
2》byte[] getBytes(String charset);方法在進行編碼的時候會按照指定的編碼方式進行編碼
3》而iso8859-1不支持中文字符的編碼,所以,在進行編碼的時候需要指定能夠編碼中文字符的編碼方式。
注意:在以字符流方式輸出中文到客戶端,需要提前告訴客戶端用utf-8去接受。
code:
//1,輸出數字 字節流方式 response.getOutputStream().write(97);//a response.getWriter().write(65);//A response.getOutputStream().write((97+"").getBytes());//97 response.getWriter().write(97+""); //2,輸出中文字符 【兩種方式:重點】 response.getOutputStream().write("中國".getBytes("utf-8")); or response.setContentType("text/html;charset=utf-8"); response.getWriter().write("美國");
3)設置響應頭發送給客戶端【重點】
當遇到中文字符的時候,需要使用URLEncoder類的靜態方法使用指定的編碼機制將字符串轉換為客戶端瀏覽器能正確解析的編碼方式。
方法原型:
String encode(String s, String enc);
code:
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(file.getName(), "utf-8"));
補充:
HTML中的所有<meta>標簽,類似於response.setHeader(),目的是通知瀏覽器以特定的頁面方式顯示頁面信息
四】response案例----制作驗證碼
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 設置客戶端禁止緩存 response.setHeader("expires", "-1"); response.setHeader("cache-control", "no-cache"); response.setHeader("pragma", "no-chche"); // 在內存中構造一幅圖片 BufferedImage image = new BufferedImage(600, 50, BufferedImage.TYPE_INT_RGB); // 得到一個畫筆 Graphics graph = image.getGraphics(); // 指定畫筆的參數 graph.setColor(Color.red); graph.setFont(new Font("黑體", Font.BOLD, 16)); // 將指定的字符串繪在圖上 graph.drawString(getString(), 20, 20);// 坐標 //將內存中的圖片輸出到指定的流中 ImageIO.write(image, "JPG", response.getOutputStream()); } // 產生一個隨機字符串 private String getString() { String str = ""; String numberAndLetter = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; int length = numberAndLetter.length(); for (int i = 1; i <= 4; i++) { if (i == 1 || i == 3) {// 數字 while (true) { Random random = new Random(); int index = random.nextInt(length); String value = numberAndLetter.substring(index, index + 1); if (value.matches("[0-9]")) { str += value; break; } } } else if (i == 2 || i == 4) {// 大小字母 while (true) { Random random = new Random(); int index = random.nextInt(length); String value = numberAndLetter.substring(index, index + 1); if (value.matches("[A-Za-z]")) { str += value; break; } } } } return str; } 或者 public class Demo3 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //設置客戶端禁止緩存 response.setHeader("expires", "-1"); response.setHeader("cache-control", "no-cache"); response.setHeader("pragma", "no-chche"); //在內存中構造一幅圖片 BufferedImage img = new BufferedImage(200,300,BufferedImage.TYPE_INT_RGB); //獲得在圖中的畫筆 Graphics graph = img.getGraphics(); //在圖片中畫上驗證碼 graph.drawString(getString(), 20, 20); ImageIO.write(img, "JPG", response.getOutputStream()); } private String getString() { Random random = new Random(System.currentTimeMillis()); String str = null; String str_1 = random.nextInt(10)+""; String str_2 = (char)(random.nextInt(26)+random.nextInt(2)*('a'-'A')+'A')+""; String str_3 = random.nextInt(10)+""; String str_4 = (char)(random.nextInt(26)+random.nextInt(2)*('a'-'A')+'A')+""; System.out.println("str_1 = " + str_1); System.out.println("str_2 = " + str_2); System.out.println("str_3 = " + str_3); System.out.println("str_4 = " + str_4); str = str_1+str_2+str_3+str_4; return str; } }
·知識點補充
1)BufferedImage類 ----在內存中構建一幅圖片
重點方法:
1》構造方法:
BufferedImage(int width, int height, int imageType);
參數:
width :構造的圖片的寬度
height:構造的圖片的寬度
imageType:構造的圖片的類型 --取的只是此類的字段
2》取得一個圖片的畫筆,可以對這個圖片進行繪畫
Graphics getGraphics();
2)Graphics類: --- 畫筆類
重點方法:
void setColor(Color c);//指定顏色
void setFont(Font font);//指定字體
void drawString(String str, int x, int y);
//使用此圖形上下文的當前字體和顏色繪制由指定 string 給定的文本
//X和Y代表的是繪制出的內容的坐標
3)Font類:
重點方法
1》構造函數:
Font(String name, int style, int size);
參數:
name:字體名稱 ”隸書“等
style: Font的樣式常量。
size: 字體的大小
4)ImageIO類
重點方法:
static boolean write(圖片類對象,"將內存中的圖片以什么格式輸出",OuputStream os);
參數:
os:圖片通過哪個流輸出
eg:
//以內存中構造一副圖片
BufferedImage image = new BufferedImage(80,25,BufferedImage.TYPE_INT_RGB);
//取得畫筆
Graphics g = image.getGraphics();
//設置字體大小和顏色
g.setColor(Color.YELLOW);
g.setFont(new Font("黑體",Font.BOLD,22));
//在圖片中,畫一個字符串"1A2B"
g.drawString(getString(),20,20);
//將內存中的圖片以JPG格式輸出到瀏覽器
ImageIO.write(image,"JPG",response.getOutputStream());
5)UUID類:產生隨機的字符串---很隨機!!!
重點方法:
static UUID randomUUID();//獲取類型 4(偽隨機生成的)UUID 的靜態工廠
Sring toString();//返回表示此 UUID 的 String 對象、
應用:
獲取一個隨即字符串的方法:
String random_str = UUID.randomUUID().toString;
五】response案例----轉發
六】response案例----重定向
函數原型:
void sendRedirect(java.lang.String location)
code:
七】關於方法重復使用的細節
1》關於輸出流:使用字節和字符輸出內容到服務器,只能使用其中一種。否則拋出IllegalStateException
原因:
當使用其中一種方式輸出完畢並不再用這種方式輸出之后,response對象馬上被銷毀了,這時候便不能使用它來調用方法了。
2》當定義了相同的消息頭的時候,后者定義的消息頭會覆蓋掉前面的消息頭,即后則起決定作用。
code:
response.setContextType("text/html;charset=iso8859-1");
response.setContextType("text/html;charset=gbk");
response.getWriter().write("中國");
3》在沒有關閉流的情況下,web容器的引擎會自動關閉由response對象取得的不再使用的流。
但是其他的普通流並不會自動關閉。
補充:要明白轉發和重定向的區別,詳見圖。