Appearance
Request
Request对象 - 入门
获取请求行信息
tex
GET /http_request/login?username=user&password=pass HTTP/1.1
相关API
String getMethod()
tex得到请求的方式:GET或POST
String getRequestURI()
texUniform Resource Identifier 统一资源标识符,代表一个资源的名字 URI = ContextPath + ServletPath
StringBuffer getRequestURL()
texUniform Resource Locator 统一资源定位符,代表一个可以访问地址
String getProtocol()
tex得到协议和版本
【重点】String getContextPath()
tex得到当前项目的访问地址
【重点】String getServletPath()
tex得到当前Servlet的访问地址
案例
- 获取请求行信息并显示在终端上
实现
RequestLineServlet.java
javaimport 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("/request_line") public class RequestLineServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); System.out.println("Method: " + request.getMethod()); System.out.println("RequestURI: " + request.getRequestURI()); System.out.println("RequestURL: " + request.getRequestURL()); System.out.println("Protocol: " + request.getProtocol()); System.out.println("ContextPath: " + request.getContextPath()); System.out.println("ServletPath: " + request.getServletPath()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
输出
tex
Method: GET
RequestURI: /http_request/request_line
RequestURL: http://localhost:8080/http_request/request_line
Protocol: HTTP/1.1
ContextPath: /http_request
ServletPath: /request_line
小结
- request.getContextPath()
项目路径
- request.getServletPath()
资源路径
获取请求头信息
tex
Host: localhost:8080
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
相关API
【重点】
String getHeader(String headName)
tex指定请求头中键,得到相应的值
Enumeration<String> getHeaderNames()
tex得到请求头中所有的键
Enumeration接口
tex
Enumeration是枚举类型的集合,类似于迭代器
Iterator | Enumeration |
---|---|
hasNext() | hasMoreElements() |
next() | nextElement() |
boolean hasMoreElements()
tex判断是否还有下一个元素,如果有返回true
E nextElement()
tex得到当前元素,并且向下移动一个元素
案例1
需求
- 获取请求头信息并显示在终端上
实现
RequestHeaderServlet.java
javaimport 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.Enumeration; @WebServlet("/request_header") public class RequestHeaderServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); System.out.println(headerName + ": " + request.getHeader(headerName)); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
输出
tex
host: localhost:8080
connection: keep-alive
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
cookie: JSESSIONID=7D790A7277BAFB203442AA8F084217F7
案例2
需求
获取浏览器版本并显示在命令行上
tex判断是Edge、Chrome、Safari、Firefox或IE浏览器
实现
java
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("/request_header")
public class RequestHeaderServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userAgent = request.getHeader("User-Agent");
if (userAgent.contains("Edge")) {
System.out.println("Edge浏览器");
} else if (userAgent.contains("Chrome")) {
System.out.println("Chrome浏览器");
} else if (userAgent.contains("Safari")) {
System.out.println("Safari浏览器");
} else if (userAgent.contains("Firefox")) {
System.out.println("Firefox浏览器");
} else {
System.out.println("IE浏览器");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
输出
tex
Chrome
Firefox
Safari
小结
请求行
- getContextPath
获取项目路径
- getServletPath
获取资源路径
请求头
- getHeader
传入请求头的键,值作为getHeader函数的返回值
获取请求参数[重点]
POST
texusername=user&password=pass
GET
texGET /http_request/login?username=user&password=pass HTTP/1.1
相关API
String getParameter(String name)
通过参数名得到参数的值
String[] getParameterValues(String name)
通过参数名得到一组参数值,返回是字符串的数组
【非重点】
Enumeration<String> getParameterNames()
得到所有参数的名字,返回是枚举的类型
Map<String, String[]> getParameterMap()
得到表单提交的所有参数名和参数值,封装成一个Map集合
Part request.getPart(String name)
Gets the Part with the given name.
Collection<Part> getParts()
Gets all the Part components of this request, provided that it is of type multipart/form-data.
案例
- 获取注册表单提交的数据并输出到页面上
实现
index.html
html<html> <head> <meta charset="utf-8"> <title></title> </head> <body> <form action="request_body" method="get"> <input type="text" name="username" placeholder="用户名"/><br/> <input type="password" name="password" placeholder="密码"/><br/> 爱好: <input type="checkbox" name="hobby" value="eat"/>吃饭 <input type="checkbox" name="hobby" value="sleep"/>睡觉 <input type="checkbox" name="hobby" value="hit dodo"/>打豆豆 <input type="submit" value="登录"/> </form> </body> </html>
RequestBodyServlet.java
javaimport 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; import java.util.Map; import java.util.Set; @WebServlet("/request_body") public class RequestBodyServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); System.out.println("username: " + request.getParameter("username")); System.out.println("password: " + request.getParameter("password")); System.out.println("hobby: " + Arrays.toString(request.getParameterValues("hobby"))); System.out.println("----"); Enumeration<String> names = request.getParameterNames(); while(names.hasMoreElements()) { String pname = names.nextElement(); System.out.println(pname + ": " + request.getParameter(pname)); } System.out.println("----"); Map<String, String[]> map = request.getParameterMap(); Set<Map.Entry<String, String[]>> entries = map.entrySet(); for (Map.Entry<String, String[]> entry : entries) { System.out.println(entry.getKey() + ": " + Arrays.toString(entry.getValue())); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
输出
tex
namename: user
password: pass
hobby: [eat, sleep]
----
namename: user
password: pass
hobby: eat
----
username: [user]
password: [pass]
hobby: [eat, sleep]
小结
String getParameter(String name)
获取参数值(一个名字,对应一个值)
String[] getParameterValues(String name)
获取参数值(一个名字,对应多个值)
Map<String, String[]> getParameterMap()
获取参数值(获取所有的参数名和参数值)
参数乱码问题
GET 方式的乱码解决方案
texTomcat 8.5,GET方式无乱码问题
POST 方式的乱码解决方案
texrequest.setCharacterEncoding("utf-8");
小结
http://localhost:8080/JavaWeb_day02_Request_war_exploded/request_body
获取请求行信息
- getContextPath
获取项目路径
- getServletPath
获取资源路径
获取请求头信息
- String getHeader("name")
获取请求头,参数传入name,value作为返回值
获取请求参数信息
- getParameter
传一个key,返回一个value
- getParameterValues
传一个key,返回所有value
- getParameterMap
不传参数,返回所有的key和value
参数乱码问题
request.setCharacterEncoding("utf-8")
注意
utf-8不是解决乱码问题的万金油
乱码是因为编码和解码不一致造成的
Request - 深入
转发
定义
用于资源跳转,从一个资源跳转到另一个资源
相关API
java
request.getRequestDispatcher("/resourceB").forward(request, response);
方法 | 说明 |
---|---|
RequestDispatcher getRequestDispatcher(String path) | 获取请求转发器(request对象方法) |
void forward(ServletRequest request, ServletResponse response) | 将请求转发到另一个资源(Servlet)上 |
特点【重点】
- 地址不变
- 服务器内部跳转
- 一次请求
案例
- 浏览器请求 AServlet,转发至 BServlet
实现
java
package com.futureweaver.request;
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("/resourceA")
public class AServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("AServlet接收到了用户的请求");
//... 处理自己所负责的业务
// 通过getRequestDispatcher,获得一个请求调度器
// 让调度器,转发到"/resourceB"
// 并且通过forward进行转发
// 转发时,需要两个参数,一个是request,一个是response
request.getRequestDispatcher("/resourceB").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
请求域【重点】
问题
相关API
- Object getAttribute(String key)
tex
从作用域中取出值
- void setAttribute(String key, Object obj)
tex
向作用域中添加键和值,如果之前没有这个键则是添加,如果有就是修改
- void removeAttribute(String key)
tex
删除指定的键和值
作用
服务器内存区域,用于数据存储
一个盒子,在盒子里面可以存储物品(Object)
小结
- request.getRequestDispatcher("/资源路径").forward(request, response)
- void request.setAttribute(String key, Object obj);
- Object request.getAttribute(String key)
- void request.removeAttribute(String key)
Request 对象生命周期【难点】
一个对象从创建到销毁的全过程
什么时候创建
当服务器接收到了浏览器的请求时
什么时候销毁
当响应结束时
由谁创建
Tomcat
由谁销毁
Tomcat
小结
转发的特点
- 一次请求
- 地址不变
- 服务器内部跳转
转发
javarequest.getRequestDispatcher("/资源路径").forward(request, response)
Request 的生命周期
创建
服务器接收到浏览器的请求时,由Tomcat创建
销毁
响应结束时,由Tomcat销毁
案例
需求
静态资源-HTML 登录页面(帐号框、密码框、登录按钮)
登录表单提交至 LoginServlet
利用MyBatis获取真实数据并进行比对
若登录成功,转发至登录成功(LoginSuccessServlet)
若登录失败,转发至登录失败(LoginFailureServlet)
ver 0.1 原生方式
实现
index.html
html<html> <head> <meta charset="utf-8"> <title></title> </head> <body> <form action="login" method="post"> <input type="text" name="username" placeholder="用户名"/><br/> <input type="password" name="password" placeholder="密码"/><br/> 爱好: <input type="checkbox" name="hobby" value="吃饭"/>吃饭 <input type="checkbox" name="hobby" value="睡觉"/>睡觉 <input type="checkbox" name="hobby" value="打豆豆"/>打豆豆 <input type="submit" value="登录"/> </form> </body> </html>
LoginServlet.java
javaimport 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.io.PrintWriter; @WebServlet("/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String username = request.getParameter("username"); String password = request.getParameter("password"); if (username.equals("user") && password.equals("pass")) { request.getRequestDispatcher("/login_success").forward(request, response); } else { request.getRequestDispatcher("/login_failure").forward(request, response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
LoginSuccessServlet.java
javaimport 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("/login_success") public class LoginSuccessServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); System.out.println(request.getParameter("username") + " login success!"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
LoginFailureServlet.java
javaimport 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("/login_failure") public class LoginFailureServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); System.out.println(request.getParameter("username") + " login failure!"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
ver 0.2 JavaBean方式
什么是JavaBean
类必须用 public 修饰
提供 publi 无参数的构造器
提供 getter 和 setter 方法访问属性
JavaBean的两个概念
- 字段
tex
就是成员变量,字段名就是成员变量名
- 属性
- 通过 setter 或 getter 方法获得
- 属性名: setter/getter 方法去掉 set/get 前缀,首字母小写
- 比如: setName() -> Name -> name
- 一般情况下,字段名称和属性名称是一致的
实现
index.html
html<html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="login" method="post"> <input type="text" name="username" placeholder="用户名"/><br/> <input type="password" name="password" placeholder="密码"/><br/> <input type="submit" value="登录"/> </form> </body> </html>
UserInfo.java
javapublic class UserInfo { private String username; private String password; 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; } public UserInfo() { } public UserInfo(String username, String password) { this.username = username; this.password = password; } }
LoginServlet.java
javaimport 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.io.PrintWriter; @WebServlet("/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); UserInfo userInfo = new UserInfo(); userInfo.setUsername(request.getParameter("username")); userInfo.setPassword(request.getParameter("password")); if (userInfo.getUsername().equals("user") && userInfo.getPassword().equals("pass")) { request.getRequestDispatcher("/login_success").forward(request, response); } else { request.getRequestDispatcher("/login_failure").forward(request, response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
ver 1.0 BeanUtil方式
问题
- LoginServlet.java
java
UserInfo userInfo = new UserInfo();
userInfo.setUsername(request.getParameter("username"));
userInfo.setPassword(request.getParameter("password"));
- RegisterServlet.java
java
UserProfile userProfile = new UserProfile();
userProfile.setUsername(request.getParameter("username"));
userProfile.setPassword(request.getParameter("password"));
userProfile.setGender(request.getParameter("gender"));
userProfile.setMobile(request.getParameter("mobile"));
userProfile.setAvatar(request.getParameter("avatar"));
BeanUtils 工具包
commons-beanutils-1.9.3.jar
tex核心工具包
commons-logging-1.2.jar
tex日志记录包
commons-collection-3.2.2.jar
tex增强集合包
BeanUtils常用方法
setProperty(Object obj, String name, Object value)
tex给指定对象obj的指定属性name附值指定的值value 如果属性不存在,则什么也不发生
getProperty(Object obj, String name)
tex获取指定对象obj指定属性name的值 如果属性不存在,则会抛出异常
copyProperties(Object dest, Object orig)
tex将一个对象的值赋值给另一个对象 只有相同属性名才会赋值 简单记忆: "后付钱" -> 即将后一个对象的值赋值给前一个对象
populateObject bean, Map<String, String[]> properties
tex将Map集合中的数据封装到JavaBean对象中
实现
LoginServlet.java
javaimport org.apache.commons.beanutils.BeanUtils; 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.lang.reflect.InvocationTargetException; import java.util.Map; @WebServlet("/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); Map<String, String[]> parameterMap = request.getParameterMap(); UserInfo userInfo = new UserInfo(); try { BeanUtils.populate(userInfo, parameterMap); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } if (userInfo.getUsername().equals("user") && userInfo.getPassword().equals("pass")) { request.getRequestDispatcher("/login_success").forward(request, response); } else { request.getRequestDispatcher("/login_failure").forward(request, response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
ver 2.0 MyBatis方式
项目结构
- resources
- log4j.properties
- mybatis-config.xml
- UserMapper.xml
- src
- com.futureweaver
- domain
- User.java
- mapper
- UserMapper.java
- utils
- SessionFactoryUtil.java
- service
- UserService.java
- web
- LoginServlet.java
- domain
- com.futureweaver
- web
- WEB-INF
- lib
- commons-beanutils-1.9.3.jar
- commons-logging-1.2.jar
- commons-collection-3.2.2.jar
- log4j-1.2.17.jar
- mybatis-3.5.3.jar
- mysql-connector-j-8.2.0.jar
- web.xml
- lib
- index.html
- WEB-INF
学习目标总结
- 能够应用 Request 对象的方法
- 能够了解 Request 请求头信息
- 能够应用 Request 对象解决获取请求参数中文乱码问题
- 能够应用 BeanUtils 工具类对请求参数数据进行封装
- 请求域
- 转发的三个特点
- 能够独立运用 Servlet 技术完成登录功能