二、Web服务器——ServletHTTPRequest笔记
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                二、Web服务器——ServletHTTPRequest笔记
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                今日內容:
1. Servlet 2. HTTP協議 3. RequestServlet:
1. 概念 2. 步驟 3. 執行原理 4. 生命周期 5. Servlet3.0 注解配置 6. Servlet的體系結構 Servlet -- 接口|GenericServlet -- 抽象類|HttpServlet -- 抽象類* GenericServlet:將Servlet接口中其他的方法做了默認空實現,只將service()方法作為抽象* 將來定義Servlet類時,可以繼承GenericServlet,實現service()方法即可* HttpServlet:對http協議的一種封裝,簡化操作1. 定義類繼承HttpServlet2. 復寫doGet/doPost方法7. Servlet相關配置1. urlpartten:Servlet訪問路徑1. 一個Servlet可以定義多個訪問路徑 : @WebServlet({"/d4","/dd4","/ddd4"})2. 路徑定義規則:1. /xxx:路徑匹配2. /xxx/xxx:多層路徑,目錄結構3. *.do:擴展名匹配HTTP:
* 概念:Hyper Text Transfer Protocol 超文本傳輸協議* 傳輸協議:定義了,客戶端和服務器端通信時,發送數據的格式* 特點:1. 基于TCP/IP的高級協議2. 默認端口號:803. 基于請求/響應模型的:一次請求對應一次響應4. 無狀態的:每次請求之間相互獨立,不能交互數據* 歷史版本:* 1.0:每一次請求響應都會建立新的連接* 1.1:復用連接* 請求消息數據格式1. 請求行請求方式 請求url 請求協議/版本GET /login.html HTTP/1.1* 請求方式:* HTTP協議有7中請求方式,常用的有2種* GET:1. 請求參數在請求行中,在url后。2. 請求的url長度有限制的3. 不太安全* POST:1. 請求參數在請求體中2. 請求的url長度沒有限制的3. 相對安全2. 請求頭:客戶端瀏覽器告訴服務器一些信息請求頭名稱: 請求頭值* 常見的請求頭:1. User-Agent:瀏覽器告訴服務器,我訪問你使用的瀏覽器版本信息* 可以在服務器端獲取該頭的信息,解決瀏覽器的兼容性問題2. Referer:http://localhost/login.html* 告訴服務器,我(當前請求)從哪里來?* 作用:1. 防盜鏈:2. 統計工作:3. 請求空行空行,就是用于分割POST請求的請求頭,和請求體的。4. 請求體(正文):* 封裝POST請求消息的請求參數的* 字符串格式:POST /login.html HTTP/1.1Host: localhostUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateReferer: http://localhost/login.htmlConnection: keep-aliveUpgrade-Insecure-Requests: 1username=zhangsan * 響應消息數據格式Request:
1. request對象和response對象的原理1. request和response對象是由服務器創建的。我們來使用它們2. request對象是來獲取請求消息,response對象是來設置響應消息2. request對象繼承體系結構: ServletRequest -- 接口| 繼承HttpServletRequest -- 接口| 實現org.apache.catalina.connector.RequestFacade 類(tomcat)3. request功能:1. 獲取請求消息數據1. 獲取請求行數據* GET /day14/demo1?name=zhangsan HTTP/1.1* 方法:1. 獲取請求方式 :GET* String getMethod() 2. (*)獲取虛擬目錄:/day14* String getContextPath()3. 獲取Servlet路徑: /demo1* String getServletPath()4. 獲取get方式請求參數:name=zhangsan* String getQueryString()5. (*)獲取請求URI:/day14/demo1* String getRequestURI(): /day14/demo1* StringBuffer getRequestURL() :http://localhost/day14/demo1* URL:統一資源定位符 : http://localhost/day14/demo1 中華人民共和國* URI:統一資源標識符 : /day14/demo1 共和國6. 獲取協議及版本:HTTP/1.1* String getProtocol()7. 獲取客戶機的IP地址:* String getRemoteAddr()2. 獲取請求頭數據* 方法:* (*)String getHeader(String name):通過請求頭的名稱獲取請求頭的值* Enumeration<String> getHeaderNames():獲取所有的請求頭名稱3. 獲取請求體數據:* 請求體:只有POST請求方式,才有請求體,在請求體中封裝了POST請求的請求參數* 步驟:1. 獲取流對象* BufferedReader getReader():獲取字符輸入流,只能操作字符數據* ServletInputStream getInputStream():獲取字節輸入流,可以操作所有類型數據* 在文件上傳知識點后講解2. 再從流對象中拿數據2. 其他功能:1. 獲取請求參數通用方式:不論get還是post請求方式都可以使用下列方法來獲取請求參數1. String getParameter(String name):根據參數名稱獲取參數值 username=zs&password=1232. String[] getParameterValues(String name):根據參數名稱獲取參數值的數組 hobby=xx&hobby=game3. Enumeration<String> getParameterNames():獲取所有請求的參數名稱4. Map<String,String[]> getParameterMap():獲取所有參數的map集合* 中文亂碼問題:* get方式:tomcat 8 已經將get方式亂碼問題解決了* post方式:會亂碼* 解決:在獲取參數前,設置request的編碼request.setCharacterEncoding("utf-8");2. 請求轉發:一種在服務器內部的資源跳轉方式1. 步驟:1. 通過request對象獲取請求轉發器對象:RequestDispatcher getRequestDispatcher(String path)2. 使用RequestDispatcher對象來進行轉發:forward(ServletRequest request, ServletResponse response) 2. 特點:1. 瀏覽器地址欄路徑不發生變化2. 只能轉發到當前服務器內部資源中。3. 轉發是一次請求3. 共享數據:* 域對象:一個有作用范圍的對象,可以在范圍內共享數據* request域:代表一次請求的范圍,一般用于請求轉發的多個資源中共享數據* 方法:1. void setAttribute(String name,Object obj):存儲數據2. Object getAttitude(String name):通過鍵獲取值3. void removeAttribute(String name):通過鍵移除鍵值對4. 獲取ServletContext:* ServletContext getServletContext()案例:用戶登錄
* 用戶登錄案例需求:1.編寫login.html登錄頁面username & password 兩個輸入框2.使用Druid數據庫連接池技術,操作mysql,day14數據庫中user表3.使用JdbcTemplate技術封裝JDBC4.登錄成功跳轉到SuccessServlet展示:登錄成功!用戶名,歡迎您5.登錄失敗跳轉到FailServlet展示:登錄失敗,用戶名或密碼錯誤* 分析* 開發步驟1. 創建項目,導入html頁面,配置文件,jar包2. 創建數據庫環境CREATE DATABASE day14;USE day14;CREATE TABLE USER(id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(32) UNIQUE NOT NULL,PASSWORD VARCHAR(32) NOT NULL);3. 創建包cn.itcast.domain,創建類Userpackage cn.itcast.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;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}}4. 創建包cn.itcast.util,編寫工具類JDBCUtilspackage cn.itcast.util;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import javax.xml.crypto.Data;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. 創建包cn.itcast.dao,創建類UserDao,提供login方法package cn.itcast.dao;import cn.itcast.domain.User;import cn.itcast.util.JDBCUtils;import org.springframework.dao.DataAccessException;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;/*** 操作數據庫中User表的類*/public class UserDao {//聲明JDBCTemplate對象共用private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());/*** 登錄方法* @param loginUser 只有用戶名和密碼* @return user包含用戶全部數據,沒有查詢到,返回null*/public User login(User loginUser){try {//1.編寫sqlString 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 e) {e.printStackTrace();//記錄日志return null;}}}6. 編寫cn.itcast.web.servlet.LoginServlet類package cn.itcast.web.servlet;import cn.itcast.dao.UserDao;import cn.itcast.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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.設置編碼req.setCharacterEncoding("utf-8");//2.獲取請求參數String username = req.getParameter("username");String password = req.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.判斷userif(user == null){//登錄失敗req.getRequestDispatcher("/failServlet").forward(req,resp);}else{//登錄成功//存儲數據req.setAttribute("user",user);//轉發req.getRequestDispatcher("/successServlet").forward(req,resp);}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req,resp);}}7. 編寫FailServlet和SuccessServlet類@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()+",歡迎您");}} @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);}}8. login.html中form表單的action路徑的寫法* 虛擬目錄+Servlet的資源路徑9. BeanUtils工具類,簡化數據封裝* 用于封裝JavaBean的1. JavaBean:標準的Java類1. 要求:1. 類必須被public修飾2. 必須提供空參的構造器3. 成員變量必須使用private修飾4. 提供公共setter和getter方法2. 功能:封裝數據2. 概念:成員變量:屬性:setter和getter方法截取后的產物例如:getUsername() --> Username--> username3. 方法:1. setProperty()2. getProperty()3. populate(Object obj , Map map):將map集合的鍵值對信息,封裝到對應的JavaBean對象中總結
以上是生活随笔為你收集整理的二、Web服务器——ServletHTTPRequest笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: Python pandas库159个常用
 - 下一篇: Nodejs 中的包、npm 、第三方模