標籤:
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { // 擷取位元組流對象 ServletOutputStream out = response.getOutputStream(); // 擷取字元流對象 PrintWriter writer = response.getWriter(); out.write("image".getBytes()); writer.write("<br/>text"); }
運行結果出現異常,異常資訊如下:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
總結:
由於伺服器的輸出可以使用位元組流或字元流,因此在實際的開發中只需要擷取其中一個流即可。
- 如果在另一個流打擷取之前將第一個流資料直接進行顯示的重新整理,那麼資料被推送給瀏覽器,但是繼續拋出以上的異常。
- 如果在另一個流打擷取之前將第一個流直接關閉,那麼資料被推送給瀏覽器,但是繼續拋出以上的異常。
- 一定要注意在請求轉寄的時候request和response對象是共用的,那麼如果轉寄前已經擷取了response對象上得位元組流,那麼在轉寄後就一定不能再擷取字元流。
- 一定不要在請求轉寄前手工關閉response的任何輸出資料流對象,如果關閉預設響應結束。
HttpServletRequest介面
該介面繼承自ServletRequest介面。該介面的對象主要用於擷取使用者提交請求中的資料。
該介面的對象是由Web容器(Tomcat)建立直接傳遞給service()方法。
ServletRequest介面常用方法
擷取使用者請求參數
String getParameter(String name) ? 擷取單個請求參數String[] getParameterValues(String name) ? 擷取多個請求值Enumeration getParameterNames() ? 擷取所有參數名Map getParameterMap() ? 擷取所有參數的Map集合對象
在對象中儲存和擷取資料
void setAttribute(String name, Object o) ? 設定屬性Object getAttribute(String name) ? 擷取屬性
指定擷取使用者請求參數資料時候的編碼方式
String getCharacterEncoding() ? 設定擷取請求參數值時候編碼方式
HttpServletRequest介面常用方法
Cookie[] getCookies() ? 擷取Cookie數組HttpSession getSession() ? 擷取回話對象String getContextPath() ? 擷取網站的映射路徑
擷取請求參數
在實際的開發中request對象主要的任務是擷取使用者傳遞過來的各種類型的參數。以下我們就以不同的方式擷取各種請求參數。
1 擷取單一的請求參數
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { // 擷取單一的請求參數 String value = request.getParameter("uname"); // 擷取位元組流對象 ServletOutputStream out = response.getOutputStream(); String data = "value="+value; // 輸出 out.write(data.getBytes()); }
2 擷取多個值
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { // 擷取單一的請求參數 String value[] = request.getParameterValues("likes"); // 擷取位元組流對象 ServletOutputStream out = response.getOutputStream(); String data = "value="+Arrays.toString(value).toString(); // 輸出 out.write(data.getBytes()); }
3 擷取所有請求資料
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { // 擷取所有的請求參數名字的迭代器 Enumeration<String> nas = request.getParameterNames(); // 擷取位元組流對象 ServletOutputStream out = response.getOutputStream(); // 迭代 while(nas.hasMoreElements()){ String name = nas.nextElement(); if("uname".equals(name)){ String value = request.getParameter(name); out.write((name+"="+value).getBytes()); } out.write("<br/>".getBytes()); if("likes".equals(name)){ String[] value = request.getParameterValues(name); out.write((name+"="+Arrays.toString(value)).getBytes()); } } }
4 封裝請求參數
一般的註冊頁面中使用者的請求資料比較多,如果servlet直接擷取了這些資料,但是servlet本身不能處理這些資料需要傳遞給底層的業務層代碼進行處理。如果一個一個傳遞那麼太繁瑣。因此擷取到使用者的請求參數後需要適當進行資料的封轉以便傳遞給下一層處理資料。
JavaBeanàBeanUtils
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { // 擷取所有請求的參數的Map對象 Map<String,Object> map = request.getParameterMap(); // 擷取set集合 Set<Map.Entry<String, Object>> set = map.entrySet(); // 擷取迭代器對象 Iterator<Map.Entry<String, Object>> it = set.iterator(); // 建立一個javabean對象 User user = new User(); // 迴圈 while(it.hasNext()){ Map.Entry<String, Object> entry = it.next(); String name = entry.getKey(); Object value = entry.getValue(); try { BeanUtils.setProperty(user, name, value); } catch (Exception e){ System.out.println("封裝失敗!"); e.printStackTrace(); } } // 輸出user對象的資料 System.out.println(user); }
java學習筆記—HttpServletResponse(21)