1. 程式人生 > >Request和Response,轉發和重定向

Request和Response,轉發和重定向

主要內容:

HttpServletRequest

請求轉發

HttpServletResponse

請求重定向

具體內容:

每次請求service()方法,都會由容器建立一個新的物件

Servlet物件的比較

Request和response在每一次訪問時都被建立。由容器建立的

Serlvet只會被建立一次,由使用者來開發,由容器來建立,單一的例項。

ServletConfig會為每一個Servlet建立一個Config物件,且由Servlet維護。就是宣告成了成員變數。

ServletContext物件,是這一個專案就只有一個此物件。

HttpServletRequest

簡介

Servlet API 中定義的 ServletRequest 介面類用於封裝請求訊息。

HttpServletRequest 是專用於HTTP協議的ServletRequest 子介面,它用於封裝 HTTP 請求訊息。

service() 方法內部呼叫 HttpServletRequest 物件的各種方法來獲取請求訊息。

Request功能

接收使用者的引數

接收使用者的所有請求頭資訊

轉發、包含

做為域物件也可以存放資料

接收使用者的引數

getParameter(String)方法

  根據名字獲取一個引數,返回型別為String

getParameterValues

(String)方法

  根據名字獲取一組相關的資料,返回型別為String[]

getParameterNames ()方法

  獲取所有引數的名字,返回型別為Enumeration

getParameterMap ()方法

  獲取所有資料,,返回型別為Map

例子:

<form action="one" method="post">
  姓名:<input type="text" name="name"><br>
  愛好:<input type="checkbox" name="hobby" value="read">讀書
       <input type="checkbox" name="hobby" value="football">足球
       <input type="checkbox" name="hobby" value="run">跑步 <br>
  性別:<input type="radio" name="sex" value="male">男
       <input type="radio" name="sex" value="female">女<br>
  <input type="submit" value="提交">
</form>
// 獲取名字<input type="text" name="name">的值
String name = req.getParameter("name");
// 愛好<input type="checkbox" name="hobby" value="read">
String[] hobbys = req.getParameterValues("hobby");
// 性別<input type="radio" name="sex" value="male">
String sex = req.getParameter("sex");
// 顯示到頁面上
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.print("你叫:" + name + "<br/>");
out.print("你的愛好是:<br/>");
for (String h : hobbys) {
  out.print(h + "<br/>");
}
out.print("你的性別是:" + sex + "<hr/>");
// 使用getParameterNames()獲取所有引數名字
Enumeration<String> names = req.getParameterNames();
while (names.hasMoreElements()) {
String nm = (String) names.nextElement();
  out.print("獲取到的名字:" + nm + "<br/>");
}
out.print("<hr/>");

// 使用getParameterMap()獲取所有資料
Map<String, String[]> map = req.getParameterMap();
for (Entry<String, String[]> en : map.entrySet()) {
  out.print(en.getKey() + "<br>");
  String[] vs = en.getValue();
  for (String str : vs) {
    out.print(str + "<br>");
  }
  out.print("<hr/>");
}

獲取引數時的亂碼問題

解決方法一

String name = req.getParameter("name");//目前獲取到的是iso-8859-1的編碼
byte[] bs = name.getBytes("iso-8859-1");//根據iso-8859-1獲取位元組碼
String name1 = new String(bs,"utf-8");//根據utf-8編碼,重新組成新字串
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.print("姓名是:" + name1 + ",原來的是"+name);

解決方法二

req.setCharacterEncoding("utf-8");// 只能post型別有效
String name = req.getParameter("name");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.print("姓名是:" +name);

獲取請求行的相關資訊

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  resp.setContentType("text/html;charset=uTF-8");
  PrintWriter out = resp.getWriter();
  out.print("請求型別:"+req.getMethod()+"<br/>");
  out.print("請求協議:"+req.getProtocol()+"<br/>");
  out.print("請求地址:"+req.getRequestURI()+"<br/>");
  out.print("你的ip:"+req.getRemoteAddr()+"<br/>");
  out.print("請求:"+req.getQueryString()+"<br/>");
  out.print("請求主機:"+req.getHeader("Host")+"<br/>");
  out.print("請求來自哪裡:"+req.getHeader("Referer")+"<hr/>");
  //以下獲取所有頭資訊
  Enumeration<String> en = req.getHeaderNames();
  while(en.hasMoreElements()){
    String key = en.nextElement();
    out.print(key+"=="+req.getHeader(key)+"<br/>");
  }
}

轉發:

轉發:是將請求在伺服器內部交給另一個元件再去執行,同時共享request中的資料

例子:

req.setAttribute("name", "Jack"+new Random().nextInt(100));
// 通過request獲取RequestDispatcher
// 以 "/" 開始是指 專案的上下文根, http://127.0.0.1:8081/Servlet03 裡面的 '/Servlet03’  
RequestDispatcher rd = req.getRequestDispatcher("/sb");
// 執行轉發
rd.forward(req, resp);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().print("這是servletB....."+req.getAttribute("name"));

轉發過程圖解:

n包含:是將另一個元件的執行結果包含到自己的響應結果中 

req.setAttribute("name", "山東濟寧");
out.print("這是第一個ServletA<br/>");
req.getRequestDispatcher("/sd").include(req, resp);
out.print("這是第一個ServletA執行完成了<br/>");
out.print("這是第二個ServletB,"+req.getAttribute("name")+"<br/>");

HttpServletResponse簡介

Servlet API中定義的ServletResponse介面類用於建立響應訊息。

HttpServletResponse是專用於HTTP協議的ServletResponse子介面,它用於封裝HTTP響應訊息。

重定向

請求重定向:指的是一個web資源受到客戶端請求後,通知客戶端去訪問另外一個web資源

sendRedirect

使用方法:response.sendRedirect(路徑)

重點:

請求轉發和重定向:
本質區別:請求轉發只發送了一次請求,重定向發了兩次請求
1)請求轉發:位址列還是初次請求的位址列
       重定向:位址列不再是第一次請求的地址,位址列為最後一次請求的地址
2)請求轉發:在最終的servlet中,request物件和中轉的request物件是同一個物件
     重定向:在最終的servlet中,request物件和中轉的request物件是不是同一個物件
3).請求轉發:/代表的是當前web應用的根目錄   http://localhost:8080/Servlet02--》這是web應用根目錄
   重定向:/代表的是當前web站點的根目錄  http://localhost:8080---》這是web站點
4)請求轉發:只能轉發到當前web應用
   重定向:可以重定向到外部資源

5)轉發時請求的型別不變

重定向時 的被呼叫者的請求型別只能是get