day47_HTTP請求消息丶Request對象

HTTP:

概念:Hyper Text Transfer Protocol 超文本傳輸協議。傳輸協議:定義了,客戶端和服務器端通信時,發送數據的格式
特點:

  • 基於TCP/IP的高級協議
  • 默認端口號:80
  • 基於請求/響應模型的:一次請求對應一次響應
  • 無狀態的:每次請求之間相互獨立,不能交互數據

歷史版本:

  • 1.0:每一次請求響應都會建立新的連接
  • 1.1:複用連接

HTTP協議:請求消息數據格式

請求消息數據格式分別下面幾個部分組成

1:請求行

  • 請求方式 請求url 請求協議/版本

請求方式:HTTP協議有7中請求方式,常用的有2種

GET:

  • 請求參數在請求行中,在url後。沒有請求體。
  • 請求的url長度有限制的
  • 不太安全

POST:

  • 請求參數在請求體中
  • 請求的url長度沒有限制的
  • 相對安全

2. 請求頭:客戶端瀏覽器告訴服務器一些信息

  • 請求頭名稱: 請求頭值

常見的請求頭:

  • User-Agent:瀏覽器告訴服務器,我訪問你使用的瀏覽器版本信息。可以在服務器端獲取該頭的信息,解決瀏覽器的兼容性問題
  • Referer:告訴服務器,我(當前請求)從哪裏來?作用:防盜鏈丶統計工作

3. 請求空行

  • 空行,就是用於分割POST請求的請求頭,和請求體的。

4:請求體(正文):

  • :封裝POST請求消息的請求參數的

Request

request對象和response對象的原理

  • request和response對象是由服務器創建的。我們來使用它們
  • request對象是來獲取請求消息,response對象是來設置響應消息

     

request對象繼承體系結構:    

  • ServletRequest接口處於最頂層的接口
  • 其下面有一個子接口HttpServletRequest去繼承ServletRequest接口
  • 而HttpServletRequest接口是由org.apache.catalina.connector.RequestFacade 類實現

                              

request功能:

獲取請求行數據

1. 獲取請求方式 :

  • String getMethod()  

2. 獲取虛擬目錄:

  • String getContextPath()

3. 獲取Servlet路徑:

  • String getServletPath()

4. 獲取get方式請求參數:

  • String getQueryString()

5. 獲取請求URI/URL:

  • String getRequestURI():   URI:統一資源標識符
  • StringBuffer getRequestURL()  :URL:統一資源定位符

 6. 獲取協議及版本

  • String getProtocol()

7. 獲取客戶機的IP地址:

  • String getRemoteAddr()
 protected void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {

        //客戶端的獲取請求方式
        System.out.println("訪問的方式是:" + request.getMethod());

        //獲取項目的虛擬目錄
        System.out.println("項目的虛擬目錄是:" + request.getContextPath());

        //獲取要訪問的Servlet的路徑
        System.out.println("Servlet的路徑:" + request.getServletPath());

        //獲取get方式請求的參數
        System.out.println("get方式請求的參數:" + request.getQueryString());

        //獲取請求URI或者是URL
        System.out.println("獲取URI:" + request.getRequestURI());
        System.out.println("獲取URL:" + request.getRequestURL());

        //獲取使用的協議及版本:
        System.out.println("獲取協議和版本號:" + request.getProtocol());

        //獲取客戶家IP地址
        System.out.println("獲取客戶機IP:" + request.getRemoteAddr());
        
    }

獲取請求頭數據

  • String getHeader(String name):通過請求頭的名稱獲取請求頭的值
  protected void doGet(HttpServletRequest request, HttpServletResponse response) 
  throws ServletException, IOException {
        //演示獲取請求頭數據:referer
        String referer = request.getHeader("referer");
   
        //防盜鏈
        if(referer != null ){
            if(referer.contains("/day14")){
                //正常訪問
               // System.out.println("播放電影....");
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("播放電影....");
            }else{
                //盜鏈
                //System.out.println("想看電影嗎?...");
              
      
            }
        }

    }
  • Enumeration<String> getHeaderNames():獲取所有的請求頭名稱
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
        //演示獲取請求頭數據
        
        //1.獲取所有請求頭名稱
        Enumeration<String> headerNames = request.getHeaderNames();
        //2.遍歷
        while(headerNames.hasMoreElements()){
            String name = headerNames.nextElement();
            //根據名稱獲取請求頭的值
            String value = request.getHeader(name);
            System.out.println(name+"---"+value);
        }

獲取請求體數據:

  • 請求體:只有POST請求方式,纔有請求體,在請求體中封裝了POST請求的請求參數

步驟:

1. 獲取流對象

  • BufferedReader getReader():獲取字符輸入流,只能操作字符數據
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        //獲取請求消息體--請求參數

        //1.獲取字符流
        BufferedReader br = request.getReader();
        //2.讀取數據
        String line = null;
        while((line = br.readLine()) != null){
            System.out.println(line);
        }

    }
  • ServletInputStream getInputStream():獲取字節輸入流,可以操作所有類型數據

2. 再從流對象中拿數據

其他常用方法

獲取請求參數通用(post丶get)方式都可以使用的方法

  • String getParameter(String name):根據參數名稱獲取參數值   
  • String[] getParameterValues(String name):根據參數名稱獲取參數值的數組  hobby=xx&hobby=game
  • Enumeration<String> getParameterNames():獲取所有請求的參數名稱
  • Map<String,String[]> getParameterMap():獲取所有參數的map集合
       //根據參數名稱獲取參數值
        String username = request.getParameter("username");
        System.out.println(username);

       //根據參數名稱獲取參數值的數組
        String[] hobbies = request.getParameterValues("hobby");
        //遍歷數組
         for (String hobby : hobbies) {
            System.out.println(hobby);
  

        //獲取所有請求的參數名稱
       Enumeration<String> parameterNames = request.getParameterNames();
   
        // 獲取所有參數的map集合
        Map<String, String[]> parameterMap = request.getParameterMap();
        //遍歷
        Set<String> keyset = parameterMap.keySet();
        for (String name : keyset) {    
            //獲取鍵獲取值
            String[] values = parameterMap.get(name);
            System.out.println(name);
            for (String value : values) {
                System.out.println(value);
            }

            System.out.println("-----------------");
        }

獲取請求參數中文亂碼問題

  • get方式:tomcat 8 已經將get方式亂碼問題解決了
  • post方式:會亂碼。 解決方式:在獲取參數前,設置request的編碼request.setCharacterEncoding("utf-8");

請求轉發

請求轉發:一種在服務器內部的資源跳轉方式

步驟:

  1. 通過request對象獲取請求轉發器對象:RequestDispatcher getRequestDispatcher(String path) 參數是要轉發的目的地
  2. 使用RequestDispatcher對象來進行轉發:forward(ServletRequest request, ServletResponse response)  

 特點:

  • 瀏覽器地址欄路徑不發生變化
  • 只能轉發到當前服務器內部資源中。
  • 請求轉發是一次請求

共享數據:

域對象:一個有作用範圍的對象,可以在範圍內共享數據

  • request域:代表一次請求的範圍,一般用於請求轉發的多個資源中共享數據

方法:

  • void setAttribute(String name,Object obj):存儲數據
  • Object getAttitude(String name):通過鍵獲取值
  • void removeAttribute(String name):通過鍵移除鍵值對

獲取ServletContext對象:

  • 使用方法ServletContext getServletContext()

登錄案例

用戶登錄案例需求:

  1. 編寫login.html登錄頁面username & password 兩個輸入框
  2. 使用Druid數據庫連接池技術,操作mysql,day14數據庫中user表
  3. 使用JdbcTemplate技術封裝JDBC
  4. 登錄成功跳轉到SuccessServlet展示:登錄成功!用戶名,歡迎您
  5. 登錄失敗跳轉到FailServlet展示:登錄失敗,用戶名或密碼錯誤

開發步驟

1. 創建Web項目,導入html頁面,配置文件,jar包

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--虛擬目錄+Servlet的資源路徑-->
    <form action="/login/LoginServlet"  method="post">
        用戶名:<input type="text" name="username"> <br>
        密碼:<input type="password" name="password"><br>

        <input type="submit" value="登錄">

    </form>
</body>
</html>

2. 創建數據庫環境(創建庫丶表丶添加數據)

3. 創建包,裏面存放着與數據庫中標對應的User類

package com.wrg.domain;

public class User {
    // 成員變量對應着數據庫中的字段名稱
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

    4. 創建包util,編寫工具類JDBCUtils

package com.wrg.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具類 使用Durid連接池
 */
public class JDBCUtils {

    private static DataSource ds ;

    static {

        try {
            //1.加載配置文件
            Properties pro = new Properties();
            //使用ClassLoader加載配置文件,獲取字節輸入流
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);

            //2.初始化連接池對象
            ds = DruidDataSourceFactory.createDataSource(pro);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 獲取連接池對象
     */
    public static DataSource getDataSource(){
        return ds;
    }


    /**
     * 獲取連接Connection對象
     */
    public static Connection getConnection() throws SQLException {
        return  ds.getConnection();
    }
}

    5. 創建包創建類UserDao,提供login方法

package com.wrg.dao;

import com.wrg.domain.User;
import com.wrg.util.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

public class UserDao {

    //聲明JDBCTemplate對象共用
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    /**
     * 登錄方法
     * @param loginUser 只有用戶名和密碼
     * @return user包含用戶全部數據,沒有查詢到,返回null
     */
    public User login(User loginUser){
       try {
           //1.編寫sql
           String sql = "select * from user where username = ? and password = ?";
           //2.調用query方法
           User user = template.queryForObject(sql,
                   new BeanPropertyRowMapper<User>(User.class),
                   loginUser.getUsername(), loginUser.getPassword());
           return user;
       }catch ( DataAccessException a){
           a.printStackTrace();
           return null;
       }

    }
}

   6. 編寫包,實現Servlet類丶FailServlet類丶SuccessServlet類

package com.wrg.web.servlet;

import com.wrg.dao.UserDao;
import com.wrg.domain.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet( "/LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        System.out.println("1");
        //1.設置編碼
        request.setCharacterEncoding("utf-8");
        //2.獲取請求參數
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //3.封裝user對象
        User loginUser = new User();
        loginUser.setUsername(username);
        loginUser.setPassword(password);

        //4.調用UserDao的login方法
        UserDao dao = new UserDao();
        User user = dao.login(loginUser);

        //5.判斷user
        if(user == null){
            //登錄失敗
            request.getRequestDispatcher("/failServlet").forward(request,response);
        }else{
            //登錄成功
            //存儲數據
            request.setAttribute("user",user);
            //轉發
            request.getRequestDispatcher("/successServlet").forward(request,response);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

FailServlet類

package com.wrg.web.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/failServlet")
public class FailServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
        //給頁面寫一句話

        //設置編碼
        response.setContentType("text/html;charset=utf-8");
        //輸出
        response.getWriter().write("登錄失敗,用戶名或密碼錯誤");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

SuccessServlet類

package com.wrg.web.servlet;

import com.wrg.domain.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
        //獲取request域中共享的user對象
        User user = (User) request.getAttribute("user");

        if (user != null) {
            //給頁面寫一句話

            //設置編碼
            response.setContentType("text/html;charset=utf-8");
            //輸出
            response.getWriter().write("登錄成功!" + user.getUsername() + ",歡迎您");
        }


    }
}

 

 

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