Request

Request
1、HttpServletRequest
一、HttpServletRequest概述
        咱們在建立Servlet時會覆蓋service()方法,或doGet()/doPost(),這些方法都有兩個參數,一個爲表明請求的request和表明響應response。
        service方法中的request的類型是ServletRequest,而doGet/doPost方法的request的類型是HttpServletRequest,HttpServletRequest是ServletRequest的子接口,功能和方法更增強大。
        request對象是JSP中重要的對象,每一個request對象封裝着一次用戶請求,而且全部的請求參數都被封裝在request對象中,所以request對象是獲取請求參數的重要途徑。
二、Request的運行流程
同Response。
 
三、request得到請求內容
請求行
得到客戶端的請求方式: String  getMethod();
得到請求的資源: String  getContextPath();---web應用的名稱
String getRequestURI()
StringBuffer getRequestURL()
String getContextPath() ---web應用的名稱
String getQueryString() ---- get提交url地址後的參數字符串
            //一、得到請求方式
             String method = request.getMethod();
             System.out.println("method:"+method);
             //二、得到請求的資源相關的內容
             String requestURI = request.getRequestURI();
             StringBuffer requestURL = request.getRequestURL();
             System.out.println("uri:"+requestURI);
             System.out.println("url:"+requestURL);
             //得到web應用的名稱
             String contextPath = request.getContextPath();
             System.out.println("web應用:"+contextPath);
             //地址後的參數的字符串
             String queryString = request.getQueryString();
             System.out.println(queryString);
             //三、得到客戶機的信息---得到訪問者IP地址
             String remoteAddr = request.getRemoteAddr();
             System.out.println("IP:"+remoteAddr);
注意:request得到客戶機(客戶端)的一些信息
request.getRemoteAddr() --- 得到訪問的客戶端IP地址
 
請求頭
得到指定請求頭: String  getHeader(String  name);
獲取全部請求頭的名稱:java.util.Enumeration<String> getHeaderNames();
long getDateHeader(String name)
String getHeader(String name)
Enumeration getHeaderNames()
Enumeration getHeaders(String name)
int getIntHeader(String name)
            //一、得到指定的頭
             String header = request.getHeader("User-Agent");
             System.out.println(header);
             //二、得到全部的頭的名稱
             Enumeration<String> headerNames = request.getHeaderNames();
             while(headerNames.hasMoreElements()){
                    String headerName = headerNames.nextElement();
                    String headerValue = request.getHeader(headerName);
                    System.out.println(headerName+":"+headerValue);
             }
 
referer 頭的做用:執行該此訪問的來源作防盜鏈
 
請求體
請求體中的內容是經過post提交的請求參數,格式是:
username=zhangsan&password=123&hobby=football&hobby=basketball
key ---------------------- value
username                [zhangsan]
password                [123]
hobby                    [football,basketball]
 
獲取paramName請求參數的值:
String getParameter(String paramName);
paramName請求參數的值,當該請求參數有多個值時,該方法將返回多個值所組成的數組:
String[] getParameterValues(String name);
獲取全部請求參數名和參數值所組成的Map對象
Map<String,String[]> getParameterMap();
獲取全部請求參數名所組成的Enumeration對象
Enumeration getParameterNames();
            //一、得到單個表單值
             String username = request.getParameter("username");
             System.out.println(username);
             String password = request.getParameter("password");
             System.out.println(password);
             //二、得到多個表單的值
             String[] hobbys = request.getParameterValues("hobby");
             for(String hobby:hobbys){
                    System.out.println(hobby);
             }
             //三、得到全部的請求參數的名稱
             Enumeration<String> parameterNames = request.getParameterNames();
             while(parameterNames.hasMoreElements()){
                    System.out.println(parameterNames.nextElement());
             }
             System.out.println("------------------");
             //四、得到全部的參數 參數封裝到一個Map<String,String[]>
             Map<String, String[]> parameterMap = request.getParameterMap();
             for(Map.Entry<String, String[]> entry:parameterMap.entrySet()){
                    System.out.println(entry.getKey());
                    for(String str:entry.getValue()){
                           System.out.println(str);
                    }
                    System.out.println("---------------------------");
             }
   注:Map複雜了一點,可是比較有用。          
 
注意:不管是get請求方式仍是post請求方式,上述的方法同樣能夠得到。
 
四、Request的其餘功能
a、request是一個域對象
request對象也是一個存儲數據的區域對象,因此也具備以下方法:
setAttribute(String name, Object o)
getAttribute(String name)
removeAttribute(String name)
 
注意:request域的做用範圍:一次請求中
在request中存儲數據,而後經過請求轉發可以獲取到(重定向沒有數據)。(a與b結合來看)
 
b、request完成請求轉發
得到請求轉發器----path是轉發的地址
RequestDispatcher getRequestDispatcher(String path)
經過轉發器對象轉發
requestDispathcer.forward(ServletRequest request, ServletResponse response)
//servlet1將請求轉發給servlet2
             RequestDispatcher dispatcher = request.getRequestDispatcher("/servlet2");
             dispatcher.forward(request, response);
注意:轉發與重定向的區別?
        1)重定向兩次請求,轉發一次請求
        2)重定向地址欄的地址變化,轉發地址不變
        3)從新定向能夠訪問外部網站 轉發只能訪問內部資源
        4)轉發的性能要優於重定向
重定向是服務器外部行爲,請求轉發是服務器內部行爲。
 
注意:ServletContext域與Request域的生命週期比較?
        ServletContext:
            建立:服務器啓動
            銷燬:服務器關閉
            域的做用範圍:整個web應用
        request:
            建立:訪問時建立request
            銷燬:響應結束request銷燬
            域的做用範圍:一次請求中
 
注意:客戶端地址與服務器端地址的寫法?
    客戶端地址:是客戶端去訪問服務器的地址,服務器外部的地址。其特色:寫上Web應用的名稱。
    客戶端地址有:直接輸入地址;重定向;
 
    服務器端地址:服務器內部資源跳轉的地址。其特色:不須要寫Web應用的名稱。
 
2、完成用戶註冊
一、獲取表單的數據
二、將數據存儲到數據庫中
 
注意:中文亂碼問題;BeanUtils:將Map中的數據映射到實體中(JavaBean),根據map的key與實體的屬性進行對比。
 
註冊的基本實現:
一、完成登陸頁面(html or jsp)
二、JDBC工具類實現
jar包:c3po.....dbutils.......mysql-connector....
c3p0-config.xml
DataSourceUtils.java
三、JavaBean實現User(實體數據封裝到JavaBean中,數據工整,面向對象思想)
四、註冊servlet實現
       //1.獲取數據
             //String username = request.getParameter("username");
             //String password = request.getParameter("password");
             
             //2.將散裝的數據封裝到JavaBean中
             //User user = new User();
             //user.setName(username);
             //user.setPassword(password);             
               //1.2使用BeanUtils進行自動映射封裝
             //BeanUtils工做原理:將map中的數據,根據key與實體的屬性的對象關係封裝
             //只要key的名字與實體的屬性的名字同樣,就自動封裝到實體中
             Map<String, String[]> properties = request.getParameterMap();
             User user = new User();
             try {
                    BeanUtils.populate(user, properties);
             } catch (IllegalAccessException | InvocationTargetException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
             }
             
             //如今這個位置user對象已經封裝好了
             //手動封裝uid----uuid----隨機的不重複的字符串32位
             //java代碼生成後是36位
             user.setUid(UUID.randomUUID().toString());           
             response.getWriter().write(user.toString());         
             //3.將參賽傳遞給一個業務操做方法
             try {
                    regist(user);
                    response.getWriter().write("regist success");               
             } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
             }
注:紅色部分須要添加jar包:beanutils   及  loggingjar包
 
解決獲取數據的中文亂碼問題?
//設置request的編碼-----只適合post方式
             request.setCharacterEncoding("UTF-8");
 
亂碼過程:王五----使用UTF-8編碼------使用iso8859-1解碼------亂碼xxx,
實現亂碼的解決:xxx------使用iso8859-1編碼------使用utf-8解碼----王五
編碼:str.getByte("iso8859-1");
new String(string,"utf-8");
       //get方式亂碼解決
             String username = request.getParameter("username");//亂碼
             //先用iso8859-1編碼,再使用utf-8解碼
             username = new String(username.getBytes("iso8859-1"),"UTF-8");
適用於get  post
get不適用於表單提交。
 
用戶登陸失敗的信息回顯
 
//4.認爲註冊成功跳轉到登陸頁面
             //使用重定向,而非轉發(地址變化)
             response.sendRedirect(request.getContextPath()+"/login.jsp");
爲何使用request.getContextPath();
 
3、用戶登陸失敗的信息回顯
步驟:
一、用戶登陸
二、輸入用戶名密碼
三、用戶名及密碼正確,跳轉到首頁(重定向)
四、用戶名或密碼不正確
五、轉向登陸頁面,提示用戶名或者密碼錯誤
 
技術點:
一、登陸頁面設計(html  or  jsp)
表單form的action跳轉到對應的servelt進行處理。
<form class="form-horizontal" action="/WEB15_Request/login" method="post">
二、LoginServlet.java  (登陸處理頁面)
//0、設置Request編碼
             request.setCharacterEncoding("UTF-8");
             //1.獲取用戶名和密碼
             String username = request.getParameter("username");
             String password = request.getParameter("password");
             //2.調用一個業務方法進行該用戶查詢
             User login = null;
             try {
                     login = login(username, password);
             } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
             }
             //3.經過user是否爲null判斷用戶名和密碼是否正確
             if(login!=null) {
                    //用戶名和密碼正確
                    //登陸成功跳轉到網站的首頁(重定義)
                    response.sendRedirect(request.getContextPath());                  
             }else {
                    //用戶名或密碼錯誤
                    //跳回當前頁面login.jsp
                    //使用轉發到login.jsp向           
                    request.setAttribute("loginInfo","用戶名或密碼錯誤");
                    request.getRequestDispatcher("/login.jsp").forward(request, response);
             }
       }
       
       public User login(String username, String password) throws SQLException {
             QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
             String sql = "select * from user where username = ? and password = ?";
             User user = runner.query(sql, new BeanHandler<User>(User.class),username,password );
             return user;
       }
三、登陸頁面錯誤回顯代碼 jsp
<div>&nbsp;<%=request.getAttribute("loginInfo")==null?"":request.getAttribute("loginInfo")%></div>
使用三目運算符,若是直接request話,會顯示null在登陸頁面上面。
四、其餘,暫無。
 
4、總結
一、request得到行的內容(請求參數)
request.getMethod();
request.getRequestURI();
request.getRequestURL();
request.getContextPath();
request.getRemoteAddr();
 
二、request得到頭的內容
request.getHeader(name);
 
三、request得到體(請求參數)
String  request.getParameter(name);
Map<String, String[]> request.getParameterMap();
String[] request.getParametherValues(name);
注意:客戶端發送的參數到服務器端得到的值都是字符串。
 
中文亂碼問題:
post:
request.setCharacterEncoding("UTF-8");
get(原始方法):
 username = new String(username.getBytes("iso8859-1"),"UTF-8");
 
四、request其餘內容 (轉發和域)
在域存儲數據:
request.setAttribute(name,value);
request.getAtteribute(name);
轉發:
request.getRequestDispatcher(轉發的地址(服務器內部地址)).forward(request,response);
相關文章
相關標籤/搜索