一、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);
- 客戶端只發送一次請求。
- 瀏覽器的地址欄地址沒有變化。
- 請求過程中只有一個request和response。
- 幾個servlet共享一個request和response。
- 對客戶端透明,客戶端不需要知道服務端做了哪些操作。
2、重定向
response.sendRedirect("fail");
- 瀏覽器發送兩次請求。
- 瀏覽器的地址發生變化。
- 請求過程產生兩個request對象和兩個response對象。
- 兩個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
- Session表示會話,在一段時間內,用戶與服務器之間的一系列的交互操作。
- 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配置信息。