response和request

response

一.概述

Servlet 最主要的作用就是處理客戶端請求,並向客戶端做出響應。爲此,針對 Servlet 的每 次請求,Web 服務器在調用 service() 之前,都會創建兩個對象,分別是 HttpServletRequest 和 HttpServletResponse,其中,

             HttpServletRequest 用於封裝 HTTP 請求消息,簡稱 request 對象。

             HttpServletResponse 用於封裝 HTTP 響應消息,簡稱 response 對象。


二.HttpServletResponse 對象

在 ServletAPI 中,定義了一個 HttpServletResponse 接口,它繼承自 ServletResponse,專門 用來封裝 HTTP 響應消息。
HTTP 響應消息分爲三部分

         響應狀態行

         響應消息頭

         響應消息體

1.發送響應消息相關方法

  • getOutputStream()方法 該方法所獲取的字節輸出流對象爲 ServletOutputStream 類型。由於 ServletOut putStream 是 OutputStream 的子類,它可以直接輸出字節數組中的二進制數據。因此,要 想輸出二進制格式的響應正文,就需要使用 getOutputStream() 方法
  • getWriter()方法 該方法所獲取的字符輸出流對象爲 PrintWriter 類型。由於 PrintWriter 類型的對象可 以直接輸出字符文本內容,因此,要想輸出內容全爲字符文本的網頁文檔,需要使用 getWriter()方法
//方式1:專門輸出二進制類型數據的
String data="小y"; 
ServletOutputStream out=response.getOutputStream();
out.write(data.getBytes());
//方式2:專門輸出字符文本的類型數據
String data1="小太陽yyy";
PrintWriter writer=response.getWriter();
writer.write(data1);
//兩個方式不可同時使用

三.亂碼問題的解決

由於計算機中的數據都是以二進制形式存儲的,因此,當傳輸文本時,就會發生字符和字節 之間的轉換。 字符與字節之間的轉換是通過查碼錶完成的,將字符轉換成字節的過程稱爲編碼,將字節轉 換成字符的過程稱爲解碼,如果編碼和解碼使用的碼錶不一致就會導致亂碼問題。
      解決方法:

         只需要保證響應數據的編碼和瀏覽器解析的編碼一致即可.

          response 緩衝區的默認編碼是 iso8859-1,此碼錶中沒有中文,可以通過 response 的 setCharacterEncoding(Stringcharset) 設置 response 的編碼
          將 response 緩衝區的編碼設置成 UTF-8,但瀏覽器的默認編碼是本地系統的編碼,中文系統 默認編碼是 GBK,我們可以手動修改瀏覽器的編碼是 UTF-8。
          還可以在代碼中指定瀏覽器解析頁面的編碼方式,通過 response 的 setContentType(String type)方法指定頁面解析時的編碼是 UTF-8 response.setContentType("text/html;charset=UTF-8"); 上面的代碼不僅可以指定瀏覽器解析頁面時的編碼,同時也內含 setCharacterEncoding 的功 能
開發中只要編寫 response.setContentType("text/html;charset=UTF-8");就可以解決頁面輸出中 文亂碼問題。

四.文件下載

          文件下載的實質就是文件拷貝,將文件從服務器端拷貝到瀏覽器端。 所以文件需要使用到 IO 流將服務器端的文件使用 InputStream 讀取到,再使用 ServletOutputStream 寫到 response 緩衝區中

<h1>使用 a 標籤直接指向服務器上的資源</h1> 
<a href="/WEB14/download/a.xlsx">a.xlsx</a><br> 
<a href="/WEB14/download/b.jpg">b.png</a><br> 
<a href="/WEB14/download/c.mp3">c.mp3</a><br> 
<a href="/WEB14/download/d.txt">d.txt</a><br>

存放文件位置:

          訪問 Servlet 直接進行下載:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//獲取輸出流,用於輸出二進制數據的輸出流
		ServletOutputStream out=response.getOutputStream();
		//獲取服務器上文件的地址
		String path=this.getServletContext().getRealPath("download/1.jpeg");
		//設置文件mime的類型.使瀏覽器可以解析的文件也變成下載而不是直接打開
		response.setContentType(this.getServletContext().getMimeType("download/1.jpeg"));
		//返回image/jpeg
		//System.out.print(this.getServletContext().getMimeType("download/1.jpeg"));
		//設置下載的文件的名稱
		response.setHeader("Content-Disposition","attachment;filename=1.jpeg");
		//創建輸入流將文件讀取到流中
		InputStream in=new FileInputStream(path);
		//copy
		int len=0;
		byte[] b=new byte[1024];
		while((len=in.read(b))!=-1){
			out.write(b,0,len);
		}
		in.close();
		out.close();
	}

           下載指定文件:

    <a href="/day34/download2Servlet?filename=1.jpeg">1.jpeg</a><br>
    <a href="/day34/download2Servlet?filename=人員.xlsx">人員.xlsx</a><br>
    <a href="/day34/download2Servlet?filename=3.txt">3.txt</a><br>
    <a href="/day34/download2Servlet?filename=4.zip">4.zip</a><br>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//獲取文件名稱
		String filename=request.getParameter("filename");
		String filePath="download/"+filename;
		//獲取請求頭中的User-Agent
		 //String agent=request.getHeader("User-Agent"); 
		 String filenameEncoder="";
		 //除了IE瀏覽器和火狐瀏覽器,解決文件名是中文的問題
		 filenameEncoder=URLEncoder.encode(filename,"utf-8");
		//設置文件的類型
		response.setContentType(this.getServletContext().getMimeType(filenameEncoder));
		//設置文件下載方式和下載名稱
		response.setHeader("Content-Disposition","attachment;filename="+filenameEncoder);
		//執行IO流下載的過程
		ServletOutputStream out=response.getOutputStream();
		//將文件讀取到輸入流中
		String realPath=this.getServletContext().getRealPath(filePath);
		InputStream in =new FileInputStream(realPath);
		//copy
				int len=0;
				byte[] b=new byte[1024];
				while((len=in.read(b))!=-1){
					out.write(b,0,len);
				}
				in.close();
				out.close();
	}

五.請求重新定向

當客戶端訪問 Servlet1 時,由於在 Servlet 中調用了 sendRedirect() 方法將請求重定向到 Servlet2 中,因此,Web 服務器在收到 Servlet1 的響應消息後,立刻向 Servlet2 發送請求 Servlet2 對請求處理完畢後,再將響應消息回送給客戶端。
代碼示例:

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 Servlet1 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.print("servlet1獲得了請求");
		//重定向
		response.sendRedirect("/day34/servlet2");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(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 Servlet2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().write("servlet2 get request");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

request

1.概述

在 Servlet API 中,定義了一個 HttpServlet Request 接口,它繼承自 ServletRequest 專門用 來封裝 HTTP 請求消息。由於 HTTP 請求消息分爲請求行、請求消息頭和請求消息體三部分, 因此,在 HttpServlet Request 接口中定義了獲取請求行、請求頭和請求消息體的相關方法 .

二.獲取請求信息的方法

方法聲明                                功能描述

String getMethod()                 獲取 http 請求消息中請求方式(GET、POST)

String getRequestURI()         獲取 URL 的主機和端口之後、參數部分之前 的部分 

String getQueryString()         GET 提交 url 地址後的參數字符串

String getServletPath()          獲取 Servlet 的名稱或 Servlet 所映射的路徑

String getRemoteAddr()        獲取訪問者 ip 地址 
 

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 RequestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
 
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String method=request.getMethod();//獲取請求方式
		System.out.println(method);
		//獲取請求資源地址路徑(端口號之後,參數列表之前,包括項目名和請求地址)
		String requestURI=request.getRequestURI();
		System.out.println(requestURI);
		//獲取參數列表之前的部分(包括主機地址,端口號,項目名,請求地址)
		StringBuffer requestURL=request.getRequestURL();
		System.out.println(requestURL);
		//獲取GET方式請求的參數列表
		String queryString=request.getQueryString();
		System.out.println(queryString);
		//獲取servlet的名稱或者映射路徑
		String servletPath=request.getServletPath();//映射地址
		System.out.println(servletPath);
		//獲取請求的端口號
		int serverPort=request.getServerPort();//端口號
		System.out.println(serverPort);
		//獲取請求的IP地址
		String remoteAddr=request.getRemoteAddr();
		response.getWriter().write(remoteAddr);
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

三. 獲取請求消息頭的方法 

代碼示例:

import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 獲取請求的相關信息
 * @author yyy
 *
 */
public class Request2Servlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
   
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//獲取指定名稱的頭信息
		String userAgent=request.getHeader("User-Agent");
		System.out.println(userAgent);
		//獲取所有的頭信息
		Enumeration<String> headerNames=request.getHeaderNames();
		while(headerNames.hasMoreElements()) {
			String headerName=headerNames.nextElement();
			String headerValue=request.getHeader(headerName);
			System.out.println(headerName+"-"+headerValue);
			response.getWriter().write(headerName+"-"+headerValue);
			response.getWriter().write("<br>");
		}
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

四.獲取請求參數

在實際開發中,經常需要獲取用戶提交的表單數據,例如,用戶名、密碼、電子郵件等,爲 了方便獲取表單中的請求參數,在 HttpServlet Request 接口中,定義了一系列獲取請求參數 的方法。 

代碼如下:

import java.io.IOException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RegServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //request解決post方式提交的中文亂碼問題
		 request.setCharacterEncoding("utf-8");
		 //request解決get方式提交的中文亂碼問題
		 //方式1:獲取指定名稱的表單數據
		 String username=request.getParameter("username");
		 System.out.println("用戶名:"+username); String
		 password=request.getParameter("password");
		 System.out.println("密碼:"+password); String[]
		 hobbies=request.getParameterValues("hobby");
		 System.out.println("愛好:"+hobbies);
		 System.out.println(Arrays.toString(hobbies)); 
		 //方式2:獲取所有的表單數據
		 Enumeration<String> parameterNames=request.getParameterNames();
		 while(parameterNames.hasMoreElements()) { String
		 param=parameterNames.nextElement();
		 System.out.println(param+": "+request.getParameter(param)); }
		 
		//方式3:獲取所有的表單數據,返回map集合.
		Map<String,String[]> maps=request.getParameterMap();
		for (Map.Entry<String, String[]> entry : maps.entrySet()) {
			System.out.println(entry.getKey());
			for(String str:entry.getValue()) {
				System.out.println(str);
			}
		}
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

表單數據

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    <form action="/day35_request/regServlet" method="post">
       <label for="username">用戶名:</label>
       <input type="text" name="username" id="username"><br>
       <label for="password">密&emsp;碼:</label>
       <input type="password" name="password" id="password"><br>
       <label for="">愛&emsp;好:</label>
       <input id="hoby" type="checkbox" name="hobby" value="coding">敲代碼
       <input id="hoby" type="checkbox" name="hobby" value="playing">玩遊戲
       <input id="hoby" type="checkbox" name="hobby" value="booking">打吳天賜<br>
       <input type="submit" value="確認">
    </form>
</body>
</html>

五.請求轉發 

工作原理

當客戶端訪問 Servlet1 時,可以通過 forward() 方法將請求轉發給其它 Web 資源,其它 Web 資源處理完請求後,直接將響應結果返回到了客戶端 .

代碼示例:

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 Servlet1 extends HttpServlet {
	private static final long serialVersionUID = 1L;
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//Servlet1獲取到了請求,轉發到Servlet2
		System.out.println("servlet1獲取到了請求,它又丟給了Servlet2");
		request.getRequestDispatcher("/servlet2").forward(request, response);
	
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(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 Servlet2 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().write("Servlet2只能接受這個請求了..");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

執行結果:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章