WEB開發2--request&response
Web伺服器收到客戶端的http請求,會針對每一次請求,分別建立一個用於代表請求的request物件、和代表響應的response物件。request和response物件即然代表請求和響應,那我們要獲取客戶機提交過來的資料,只需要找request物件就行了。要向容器輸出資料,只需要找response物件就行了。
一 Response
1 常見方法
Response分為響應訊息行,響應訊息頭和響應正文。對應Request分為請求訊息行,請求訊息頭和請求正文。主要呼叫ServletResponse和HttpServletResponse類(介面)裡的方法
2 常見作用
2.1 向客戶端傳送中文資料(解決亂碼問題)
- 以字元流的形式響應(字串文字資料)
response.getWriter().write(“中國”);//getWriter()返回Printwriter物件
接連出現??和涓浗的問題,原因如下:
由於Tomcat伺服器中預設編碼方式為ISO-8859-1,不支援中文。本身解析不了“中國“,所以在向瀏覽器響應結果時,出現??無法識別的情況(不是亂碼),方法:setCharacterEncoding(“UTF-8”),告知伺服器用UTF-8的方式解析文字。
然後,重新部署後,再次向瀏覽器響應結果時是“涓浗”(亂碼),原因是沒有告知瀏覽器應該用UTF-8的方式編碼,方法:response.setHeader(“content-type”, “text/html;charset=UTF-8”)。
其實有個更簡單的方法,直接告知伺服器和瀏覽器均用UTF-8的方式編碼,當然也可以用別的編碼方式,格式:response. setContentType(“text/html;charset=UTF-8”);
- 以位元組流的形式響應(二進位制)
response.getOutputStream().write(“中國”.getByte());//以預設編碼傳送資料;getOutputStream()返回ServletOuputStream物件。
getByte(): String類中的方法,返回byte[];使用平臺的預設字符集將此 String 編碼為 byte 序列,並將結果儲存到一個新的 byte 陣列中。(預設字符集就是你在安裝作業系統時選擇的安裝語言,簡體中文的編碼方式是GBK)。
response.getOutputStream().write(“中國”.getByte(“UTF-8”));//以UTF-8編碼向客戶端傳送資料,若瀏覽器預設GBK,會出現亂碼(不一致而導致的亂碼)。所以這時需要response.setContentType(“text/html;charset=UTF-8”);告知瀏覽器一聲用UTF-8編碼。
例項:
當response.setContentType(“text/html;charset=UTF-8”);
response.getOutputStream().write(“中國”.getByte());共同使用時,由於位元組輸出流使用預設編碼(中文–GBK),不一致就會出現亂碼。
注意:getOutputStream和getWriter這兩個方法互相排斥,呼叫了其中的任何一個方法後,就不能再呼叫另一方法,否則會拋異常。
2.2 實現請求重定向
定義:一個web資源收到客戶端請求後,(可能由於自身無法處理等問題)通知客戶端去訪問另外一個web資源,這稱之為請求重定向。
特點:位址列會變,併傳送2次請求。
實現方式:
response.sendRedirect()
實現原理:
302/307狀態碼和location頭即可實現重定
注意:sendRedirect的路徑引數寫法,是絕對路徑還是相對路徑(帶不帶”/”)?要不要寫上應用名(專案名)?如果引數為”www.baidu.com“,允許這樣寫嗎?會發生什麼?要與後面的Request的請求轉發方法RequestDispatcher()引數區分開。
response.sendRedirect("/day01/ResponseDemo4");//注意重定向時,不一定定向到哪個專案裡去了,故需要在引號裡寫上/+專案名(應用名)。表示http//localhost:8080/後面的東西。當然也可以直接寫"www.baidu.com",會跳轉到百度介面
//sendRedirect本質上是下面方式的合併:
response.setStatus(302);//307也可以,都是告訴客戶端要重新定向新的資源
response.setHeader("location", "/day01/ResponseDemo4");//傳送響應訊息頭,告訴瀏覽器要去訪問哪個URL。
3 Response重定向執行過程細節
- 客戶端傳送http請求給web伺服器
- 若是首次訪問,web伺服器建立servlet(例項化,初始化);若不是,往下走(客戶端訪問同一個servlet,只初始化,例項化一次)。
- web伺服器建立request和response物件。(初始時請求資訊是有客戶端傳來的資料的,響應資訊是空的)
- web伺服器呼叫servlet的service(req,rep)方法。
- web把執行權交給servlet,先通過request獲取請求資訊(頭,行,正文)。
- 然後執行程式,用sendRedirect方法,寫特殊響應頭,將結果儲存到response物件中()
- servlet的service方法執行完畢,將執行權返回給web伺服器。
- web伺服器解析response物件返回值,發出包含重定向的http響應,返回給客戶端。(web伺服器=tomcat=servlet引擎)
- 客戶端傳送包含重定向的請求資訊
- 然後又是一個輪迴,只不過不用再建立servlet,而且執行權在servlet時,不用寫特殊響應頭,而是寫真正的返回結果;另外web伺服器返回不返回包含重定向的http響應,而是返回真正的結果。
二 Request
1 常用方法及含義
2 獲取表單資料(Form)中文亂碼問題
方法一:request.getParameter(name);
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String[] hobbys = request.getParameterValues("hobby");
System.out.println(username);
for(int i=0;i<hobbys.length;i++){
System.out.println(hobbys[i]);
}
}
方法二:request.getParameterNames()
private void doGet(HttpServletRequest request)
throws UnsupportedEncodingException {
request.setCharacterEncoding("UTF-8");
Enumeration names = request.getParameterNames();
while(names.hasMoreElements()){
String name = (String)names.nextElement();
String values[]=request.getParameterValues(name);
for(int i=0;values!=null&&i<values.length;i++){
System.out.println(values[i]);
}
}
}
方法三:getParameterMap()
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
User u=new User();
Map <String,String[]> map=request.getParameterMap();
for(Map.Entry<String,String[]> m: map.entrySet()){
String key=m.getKey();
String value[]=m.getValue();
PropertyDescriptor pd=new PropertyDescriptor(key,User.class);//
Method setter=pd.getWriteMethod();
if(value.length==1){
setter.invoke(key, value[0]);
}
else{
setter.invoke(key, (Object)value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
3 請求轉發
客戶端傳送請求後,伺服器一個servlet無法完全處理,需要和另一個servlet協作,兩者返回的結果共同響應給客戶端。使用request.RequestDispatcher()方法,設定路徑引數時要注意必須是絕對路徑,而且只能是當前應用的servlet(類)。
- 客戶端傳送http請求
- 若是首次訪問,servlet引擎例項化並初始化servlet,若不是直接到3
- servlet引擎建立請求request和響應response物件。
- servlet引擎呼叫service(req,rep)方法,傳入剛建立的兩個物件作為引數
- servlet引擎將執行權交給servlet,呼叫service裡的doGet方法,獲取請求資訊
- servlet呼叫service方法中的doPost方法,寫入響應資訊
- servlet向servlet引擎返回請求轉發forward命令(只能轉發當前應用下的其他servlet、jsp等)
- servlet引擎收到forward命令後,找到請求轉發地址(URI/Mapping),若是第一次訪問,建立servlet2,並呼叫servlet2的service方法。
- servlet2讀取請求資訊
- 在原來響應資訊基礎上,追加資訊的響應資訊
- serlet2的service方法返回
- servlet的service方法返回
- servlet引擎解析響應資訊
- servlet引擎返回響應結果給客戶端
3.1 請求轉發與重定向的區別
轉發:位址列不變;客戶端只請求一次;servlet間可以傳遞資料;不可以跳轉到其他應用。
重定向:位址列變;客戶端請求兩次;不可以傳遞資料;可以跳轉到其他應用。
4 請求包含
包含:Servelt(源元件)把其他web元件(目標元件)生成的響應結果包含到自身的響應結果中。
轉發和請求包含的共同點
源元件和目標元件處理的都是同一個客戶請求,源元件和目標元件共享同一個ServeltRequest和ServletResponse物件。
目標元件都可以為Servlet、JSP或HTML文件
都依賴 javax.servlet.RequestDispatcher介面
相關文章
- Web開發Web
- Solon Web 開發Web
- web前端開發Web前端
- web開發workflowWeb
- 微信開發 webWeb
- WEB開發經典文章-開發秘方Web
- Dart web開發(1)DartWeb
- Flutter Web 開發部署FlutterWeb
- 《大話WEB開發》Web
- Python Web開發PythonWeb
- 開發Web應用Web
- Web開發學習Web
- Web前端開發概述Web前端
- web開發1——servletWebServlet
- web 開發(6)- VueWebVue
- Web開發的發展史Web
- .Net Web 開發研習(1) —— Web開發的“十事要說”Web
- Web開發輔助工具Web
- web前端開發規範Web前端
- Python的web開發PythonWeb
- Web開發框架推導Web框架
- Web 開發進階指南Web
- Web前端開發(五)-- jQueryWeb前端jQuery
- Java Web開發技術JavaWeb
- web開發學習之旅Web
- Web 開發規範 — WSGIWeb
- Flask web開發(3):模板FlaskWeb
- node express web開發框架ExpressWeb框架
- 現代Web開發方法Web
- Web前端開發之EasyUIWeb前端UI
- Web開發初學指南Web
- 高階Web開發教程Web
- Web開發框架趨勢Web框架
- Chrome Web App開發感受ChromeWebAPP
- web專案開發流程Web
- web開發中圖形Web
- PHP開發Web服務PHPWeb
- PHP和MySQL Web開發PHPMySqlWeb