Java Web:Servlet用法

一、HttpServletRequest、HttpServletResponse

1、HttpServletRequest

HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求中的所有信息都封裝在這個對象中,通過此種方式來獲取請求中的數據。

  • getRequestURL:獲取客戶端的完整URL
  • getRequesURI:獲取請求行中的資源名部分
  • getQueryString:獲取請求行的參數部分
  • getMethod:獲取請求方式
  • getSchema:獲取請求的協議
  • getRemoteAddr:獲取客戶端的ip地址
  • getRemoteHost:獲取客戶端的完整主機名
  • getRemotePort:獲取客戶端的網絡端口號
  • 獲取請求頭信息
    getHeader(String name)
    getHeaders(String name)
  • 獲取客戶端請求參數(用戶提交的數據)
    getParameter(name)
    getParameterValues(String name)
    getParameterNames()
    getParameterMap()

2、HttpServletResponse

HttpServletResponse對象是服務器的響應對象,這個對象中封裝了向客戶端發送數據,發送響應頭,發送響應狀態碼的方法。

  • 設置響應頭
    setHeader(String key,String value) 添加響應信息,key重複會覆蓋
    addHeader(String key,String value) 添加響應信息,key重複不會覆蓋
  • 設置響應狀態
    sendError(int num,String msg ) 添加響應狀態
  • 設置響應實體
    getWriter().write(msg) 響應具體的數據給瀏覽器

3、例子練習

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登錄</title>
</head>
<body>
    <form action="bobo" method="get">
        用戶名:<input type="text" name="username"/><br/>
        密碼:<input type="password" name="pwd"/><br/>
        愛好:<br/>
        <input type="checkbox" name="fav" value="1"/>java
        <input type="checkbox" name="fav" value="1"/>c
        <input type="checkbox" name="fav" value="1"/>c++
<input type="submit" value="登錄"/>
</form>
</body>
</html>
package com.bobo;

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;
import java.util.Arrays;
import java.util.Enumeration;

/**
 * HttpServletRequest:用來存儲客戶端請求的參數
 * 請求頭
 * 請求行
 * 請求體
 *
 * HttpServletResponse:表示服務端返回數據的響應對象
 * 響應頭
 * 響應行
 * 響應體
 */
public class MyServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Post 請求");
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Get 請求");
        /**
         * 獲取請求行信息
         */
        //獲取請求中的請求方式
        System.out.println("請求方式:" + request.getMethod());
        //獲取請求中的完整地址
        System.out.println("請求URL:" + request.getRequestURL());
        //獲取請求中的資源路徑
        System.out.println("請求URI:" + request.getRequestURI());
        //獲取請求中的協議
        System.out.println("請求協議:" + request.getScheme());

        /**
         * 獲取請求頭信息
         */
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            String value = request.getHeader(key);
            System.out.println(key + ":" + value);
        }

        /**
         * 獲取用戶請求參數,注意:無論用戶請求方式是Get還是Post,獲取用戶請求的方式不變
         */
        //注意:這裏的參數要和jsp表單中的name屬性相同
        String username = request.getParameter("username");
        String password = request.getParameter("pwd");
        System.out.println("username:" + username + " password:" + password);
        //第二種方式
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String key = parameterNames.nextElement();
            String value = request.getParameter(key);
            System.out.println("key:" + key + " value:" + value);
        }
        //獲取相同名字的多個值,例如checkbox
        String[] favs = request.getParameterValues("fav");
        System.out.println(Arrays.toString(favs));

        /**
         * 其它常用方法
         */
        //獲取遠程客戶端地址、端口
        System.out.println("RemoteAddr:"+request.getRemoteAddr()+" RemotePort:"+request.getRemotePort());
        //獲取本機地址、本機名
        System.out.println("LocalAddr:"+request.getLocalAddr()+" LocalName:"+request.getLocalName());


        /**
         * ---------響應信息
         */
        //服務端返回數據的格式
        response.setHeader("Context-Type","text/html");
        //response.setContentType("text/html");

        //設置響應頭,兩種方式:1、setHeader 2、addHeader
        //如果存在相同的key會覆蓋上一個值
        response.setHeader("set","bobo1");
        response.setHeader("set","bobo2");
        //如果存在相同的key,不會覆蓋上一個值
        response.addHeader("add","bobo1");
        response.addHeader("add","bobo2");

        response.getWriter().write("<b>this is back data<b>");
    }
}

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

二、Servlet亂碼問題解決

  • 使用String重新進行編碼
    String name = new String(name.getBytes(“ios-8859-1”),”utf-8”)
  • get請求亂碼
    request.setCharacterEncoding(“utf-8”);
    在server.xml中添加屬性useBodyEncodingForURI=true
  • post請求亂碼
    request.setCharacterEncoding(“utf-8”);
  • response亂碼
    response.setCharacterEncoding(“UTF-8”);
    response.setContentType(“text/html;charset=utf-8”)

三、請求轉發和重定向

1、請求轉發

request.getRequestDispatcher("fail").forward(request,response);
  1. 客戶端只發送一次請求。
  2. 瀏覽器的地址欄地址沒有變化。
  3. 請求過程中只有一個request和response。
  4. 幾個servlet共享一個request和response。
  5. 對客戶端透明,客戶端不需要知道服務端做了哪些操作。

在這裏插入圖片描述

2、重定向

response.sendRedirect("fail");
  1. 瀏覽器發送兩次請求。
  2. 瀏覽器的地址發生變化。
  3. 請求過程產生兩個request對象和兩個response對象。
  4. 兩個servlet不能共享同一個request和response對象。

在這裏插入圖片描述

四、Servlet加載MySql數據庫

1、驅動下載地址:

https://dev.mysql.com/downloads/connector/j/

2、把下載下來的驅動jar包放到項目的WEB_INF下面

在這裏插入圖片描述

3、加載MySql數據庫代碼

public class UserDaoImpl implements UserDao {
    @Override
    public User checkUser(User user) {

        //定義鏈接對象
        Connection conn = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        User u = null;
        try {
            //加載驅動
            Class.forName("com.mysql.jdbc.Driver");
            //獲取鏈接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/login", "root", "root");
            //獲取預處理塊
            statement = conn.prepareStatement("select * from user where name = ? and pwd = ?");
            //給?賦值
            statement.setString(1, user.getUserName());
            statement.setString(2, user.getPassword());
            //執行sql語句
            resultSet = statement.executeQuery();
            //從result中獲取結果
            while (resultSet.next()) {
                u = new User(resultSet.getInt("id"), resultSet.getString("name"), resultSet.getString("pwd"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            try {
                resultSet.close();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            try {
                statement.close();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
        return u;
    }
}

五、Servlet之Cookie

HTTP是一個無狀態的協議,當一個客戶端向服務端發送請求,在服務器返回響應後,連接就關閉了,在服務器端不保留連接信息。

思考:當客戶端發送多次請求且需要相同的請求參數的時候,應該如何處理?

1、什麼是Cookie?

  • Cookie是一種在客戶端保持HTTP狀態信息的技術.
  • Cookie是在瀏覽器訪問服務器的某個資源時,由web服務器在響應頭傳送給瀏覽器的數據.
  • 瀏覽器如果保存了某個cookie,那麼以後每次訪問服務器的時候,都會在請求頭傳遞給服務端.
  • 一個cookie只能記錄一種信息,是key-value形式.
  • 一個web站點可以給瀏覽器發送多個cookie,一個瀏覽器也可以存儲多個站點的cookie。

2、cookie的基本原理

在這裏插入圖片描述

3、cookie基本操作

  • 創建cookie對象
    Cookie cookie = new Cookie(String key,String value);
  • 設置cookie參數
    cookie.setMaxAge(int seconds)
    cookie.setPath(String url)
  • 響應Cookie給客戶端
    response.addCookie(Cookie cookie)
  • 獲取cookie屬性
    Cookie[] cookies = request.getCookies()

4、cookie實現免登陸例子

https://github.com/SevenYearZhao/Java-servlet-and-jsp/tree/master/CookieProject

六、servlet之session

1、什麼是session

  1. Session表示會話,在一段時間內,用戶與服務器之間的一系列的交互操作。
  2. session對象:用戶發送不同請求的時候,在服務器端保存不同請求共享數據的存儲對象。

2、特點

  • Session是依賴cookie技術的服務器端的數據存儲技術。
  • 由服務器進行創建。
  • 每個用戶獨立擁有一個session對象。
  • 默認存儲時間是30分鐘。

3、Servlet之Session機制

在這裏插入圖片描述
用戶使用瀏覽器第一次向服務器發送請求, 服務器在接受到請求後, 調用對應的 Servlet 進行處理。 在處理過程中會給用戶創建一個 session 對象, 用來存儲用戶請求處理相關的公共數據, 並將此 session 對象的 JSESSIONID 以 sessoin 的形式存儲在瀏覽器中(臨時存儲, 瀏覽器關閉即失效)。 用戶在發起第二次請求及後續請求時, 請求信息中會附帶 JSESSIONID, 服務器在接收到請求後,調用對應的 Servlet 進行請求處理, 同時根據 JSESSIONID 返回其對應的 session 對象

4、Session基本操作

  • 創建sessoin對象
    HttpSession session = request.getSession()
  • 向Session對象中添加值
    sessoin.setAttribute(String name,Object object)
  • 獲取Session中的值
    session.getAttribute(String name)
  • 設置sessoin屬性
    session.setMaxInactiveInterval(5)//設置存活時間
    session.invalidate(); //session強制失效

5、Session實現數據用戶登錄例子

解決了使用request.sendDirectly()重定向servlet丟失用戶名的情況。
https://github.com/SevenYearZhao/Java-servlet-and-jsp/tree/master/SessionProject

七、Servlet之ServletContext和ServletConfig

1、ServletContext

思考:不同用戶的數據共享怎麼辦?

使用ServletContext來處理。

什麼是ServletContext?

  • 運行在JVM上的每一個web應用程序都有一個與之對應的Servlet上下文(Servlet運行環境)
  • Servlet API提供ServletContext接口用來表示Servlet上下文,ServletContext對象可以被web應用程序中的所有servlet訪問
  • ServletContext對象是web服務器中的一個已知路徑的根

ServletContext原理

ServletContext 對象由服務器進行創建, 一個項目只有一個對象。 不管在項目的任意位置進行獲取得到的都是同一個對象, 那麼不同用戶發起的請求獲取到的也就是同一個對象了, 該對象由用戶共同擁有。

Servletcontext API
在這裏插入圖片描述

2、ServletConfig

思考:使用ServletContext對象可以獲取web.xml中的全局配置文件,在web.xml中,每個Servlet也可以進行單獨的配置,那麼該怎麼獲取配置信息呢?使用ServletConfig對象。

作用:
ServletConfig對象是Servlet的專屬配置對象,每個Servlet都單獨擁有一個ServletConfig對象 ,用來獲取web.xml中的配置信息。

使用:
獲取ServletConfig對象。
獲取web.xml中的servlet配置信息。

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