07_Request:获取请求行信息
HttpServletRequest
HttpServletRequest接口的对象代表客户端的请求,当客户端通过HTTP协议访问Tomcat服务器时,HTTP请求中的所有信息都封装在HttpServletRequest接口的对象中,web开发人员通过这个对象的方法,可以获得客户端信息。
通过HttpServletRequest接口的对象进行的常用操作:
-
获取请求行信息:请求方式,url,ip地址和HTTP版本。
-
获取请求头信息:浏览器类型,ip地址等。
-
获取请求参数或者请求体中的数据:url后面拼接的参数或者请求体中提交的参数;
获取http请求行信息的API方法
请求行主要包括:请求方式、url、 协议/版本
HttpServletRequest接口的对象提供了以下方法来获取这些信息:
方法 | 说明 |
---|---|
String getMethod() | 获取请求方式的类型 字母是大写的 |
StringBuffer getRequestURL() | 获取客户端发出请求完整URL |
String getRemoteAddr() | 获取IP地址 |
String getProtocol() | 获取当前协议的名称和版本 |
说明:对于上述方法StringBuffer getRequestURL() 的返回值是StringBuffer ,它也表示字符串缓冲区,用法和StringBuilder一样,只是StringBuffer 是多线程安全的,效率低。StringBuilder是多线程不安全的,效率高
08_Request:获取请求头信息
获取http请求头信息的API方法
浏览器的请求头信息是由很多key:value
形式的数据组成的
HttpServletRequest对象给我们提供了两个方法用来获取请求的头信息
方法 | 作用 |
---|---|
String getHeader(String name) | 根据请求头的key关键字获取请求头信息 |
Enumeration getHeaderNames() | 返回此请求包含的所有头信息的key,属于对枚举类型进行遍历 |
说明: 枚举属于一种特殊的数据类型,类似于集合,对他遍历也是类似于集合遍历方式。Enumeration类似于Iterator的迭代器。只是Iterator来迭代1.2之后的集合。而Enumeration用来迭代1.2之前集合和枚举类型的。
【说明】请求头的key关键字如下表所示:
请求头key | 请求头value |
---|---|
referer | 浏览器通知服务器,当前请求来自何处,如果是直接访问,则不会有这个头。 |
If-modified-Since | 浏览器通知服务器,本地缓存的最后变更时间。与另一个响应头组合控制浏览器页面的缓存。 |
cookie | 与会话有关技术,用于存放浏览器缓存的cookie信息。 |
user‐agent | 浏览器通知服务器,客户端浏览器与操作系统相关信息 |
connection | 保持连接状态。Keep-Alive 连接中,close 已关闭 |
host | 请求的服务器主机名 |
content-length | 请求体的长度 |
content-type | 如果是POST请求,会有这个头,默认值为application/x-www-form-urlencoded,表示请求体内容使用url编码 |
accept | 浏览器可支持的MIME类型。文件类型的一种描述方式。 |
mime格式 | 浏览器请求数据的类型,例如: text/html ,html文件 text/css,css文件 text/javascript,js文件 image/*,所有图片文件 |
accept-encoding | 浏览器通知服务器,浏览器支持的数据压缩格式。如:GZIP压缩 |
accept-language | 浏览器通知服务器,浏览器支持的语言。各国语言(国际化i18n) |
… | … |
09_Request:获取请求体信息
获取http请求体信息的API方法
学习完了对请求行和请求头的内容,最后一部分就是请求体了,在请求体中,包含的是用户通过浏览器发送的请求参数,因此,我们主要学习的就是获取请求参数的方法
首先,观察一下浏览器中的请求数据是怎么提交的:
get请求:get请求提交的数据是拼接在url后面的,如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qUbgbvqL-1650854650098)(D:/BaiduNetdiskDownload/Java/08-JavaWeb/Day29_JavaWeb/01_讲义/imgs/1529912593623.png)]
post请求:post请求的数据是在请求体中发送到后台的
【请求体】
username: lisi
password: 1234
通过对比,发现数据传递的格式都是:name=value
获取请求参数的方法:
方法名 | 描述 |
---|---|
String getParameter(String name) | getParameter获得指定参数名对应的值。如果没有返回null,如果值有多个获得第一个。 例如:username=jack。注意:参数name是form表单中的name属性值。 |
String[] getParameterValues(name) | getParameterValues[] 获取请求数据key相同的多个数据.一般获取的是复选框。例如: 爱好(复选框选项)。 |
Map<String,String[]> request.getParameterMap(); | 获得表单中所有的数据,key表示input标签name的属性值:,value是一个数组,表示input输入框的值 |
说明:
Map<String, String[]> parameterMap = request.getParameterMap()的返回值是一个Map集合,用来获取用户输入的所有值。
Map集合的key:表单的name属性值
Map集合的value:以String类型的数组形式存储表单提交的每一项的值
小结
- 当根据参数的name获取的value值是一个时,使用:String getParameter(String name)
- 当根据参数的name获取的value值是多个时,使用:String[] getParameterValues(String name)
- 把所有的请求数据封装到Map集合,使用:Map getParameterMap()
10_Request:使用工具类封装请求体数据
BeanUtils工具类介绍
BeanUtils 是 Apache commons组件的成员之一,主要用于简化JavaBean封装数据的操作。它可以给JavaBean封装一个字符串数据,也可以将一个表单提交的所有数据封装到JavaBean中
注意:form表单中的name属性名 和 javaBean的属性名要保持一致
小结
- 在开发中,通常使用HttpServletRequest对象获取到请求数据后,会把请求数据封装到JavaBea对象中
- 为了方便开发,借用第三方工具类:BeanUtils实现 请求数据封装到Bean
- 步骤:
- 1、把BeanUtils需要jar文件,导入到WEB-INF目录下的lib文件夹
- 把jar文件添加到classpath
- 2、获取浏览器所有的请求数据
- Map getParameterMap()
- 3、使用BeanUtils工具类中的API方法
- BeanUtils.populate( javabean对象, map对象 )
- map对象: 存放所有的请求数据
- BeanUtils.populate( javabean对象, map对象 )
- 1、把BeanUtils需要jar文件,导入到WEB-INF目录下的lib文件夹
- 细节:form表单控件的name属性的值和JavaBean类中的属性名保持致
- 步骤:
11_Request:request的生命周期
Request对象的生命周期
request对象生命周期如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yc3hwPlO-1650854650099)(D:/BaiduNetdiskDownload/Java/08-JavaWeb/Day29_JavaWeb/01_讲义/imgs/request生命周期.bmp)]
【一次请求和响应的完整流程】
1、浏览器向servlet发送请求
2、tomcat收到请求后,创建Request和Response两个对象,并将请求数据封装到request对象中,然后传递给Servlet
3、Servlet接收到请求后,调用doget或者dopost方法。处理浏览器的请求信息,然后通过Response返回tomcat服务器信息
4、tomcat接收到返回的信息,返回给浏览器。
5、浏览器接收到返回消息后,tomcat销毁Request和Response两个对象,同时销毁这两个对象所获得的信息。
- 创建:浏览器给tomcat服务器发送请求后,tomcat创建request对象封装请求数据
- 销毁:tomcat服务器给浏览器响应信息结束后销毁request对象
特点:浏览器每次给服务器发送请求,服务器都会为这次请求创建一个新的request对象
小结
- request对象的生命周期范围: 一次请求和一次响应之间
- 请求时,创建request对象
- 响应结束,销毁request对象
12_Request:request域对象
Request域对象介绍
问:什么是域对象?
在web中需要用对象来存储数据、获取数据和移除数据,就使用域对象来实现。域对象是一个容器,这种容器主要用于servlet与servlet之间的数据传输使用的 .
今天讲解的request域对象,就可以在一次请求中的多个servlet之间进行数据共享.
request域对象,一个存储数据的区域对象。是把request当成一个容器来存储数据,request域存储数据主要是用于在两个servlet之间传递数据。
request作为域对象,常用的方法如下:
方法 | 说明 |
---|---|
void setAttribute(String name, Object o) | 往request域中设置值 |
Object getAttribute(String name) | 从request域中根据name取值,这里的name和setAttribute()方法中的第一个参数name一致 |
void removeAttribute(String name) | 从request域中移除值,这里的name和setAttribute()方法中的第一个参数name一致 |
以上三个方法都是操作request中域对象中的数据,与请求参数无关。
getParameter()方法和getAttribute()方法的区别:
-
getParameter()方法获取的是浏览器提交的数据(是表单提交的数据);
-
getAttribute()方法获取的是request域中的数据(即获取的都是通过request.setAttribute()设置的值);
13_Request:请求转发
请求转发介绍
我们上面学习了域对象的一种request,主要是负责向request域对象中存储数据,然后以key作为键将数据取出。这种使用存储和获取数据的方式在开发中最为常见的就是请求转发。
请求转发:可以从某个servlet到某个html等静态资源,还可以去其他的servlet中。我们之前使用到的请求都是从页面发出,然后请求到Servlet。其实,在Servlet中。请求也可以从一个Servlet发起,然后请求到另一个Servlet或静态页面。这项技术叫做请求转发。
请求转发的描述可以参考如下图:
请求转发API
请求转发需要借助以下两个方法实现:
方法 | 说明 |
---|---|
RequestDispatcher getRequestDispatcher(String path) | 获取请求转发器(该方法需要使用request对象调用)。参数:path指定指向资源的路径名的 String 。如果该路径名是相对的,那么它必须是相对于当前 servlet 的。 |
void forward(ServletRequest request, ServletResponse response) | 将请求转发到另一个资源(Servlet)上。参数:request表示客户端对 servlet 发出的请求的 ServletRequest 对象 response 表示 servlet 向客户端返回的响应的 ServletResponse 对象。 |
当要实现Servlet1转发Servlet2时:
第1步:获取请求转发器对象 RequestDispatcher
- 知道转发的路径
第2步:使用请求转发器对象,调用方法进行请求转发 forward()
- 需要把request对象,response对象一起交给Servlet2
- ServletRequest
- 子接口:HttpServletRequest
- ServletResponse
- 子接口:HttpServletResponse
- ServletRequest
小结
- 转发是Tomcat服务器内部的跳转行为(和浏览器没有关系)
- 从一个Servlet转发到另一个资源(静态或动态),**能够实现跳转,但是浏览器地址栏地址没有发生改变。**因为对浏览器来说本质上就只有一次请求;
- 请求转发的时候,共享request域中的数据;
- 无论转发多少次,都是只有一次请求,同时会有一次响应;
- 三层体系
- web
- 技术:Servlet
- 功能:
- 接收浏览器发送的数据
- 把接收的数据封装到JavaBean对象中
- 实例化service层的对象,并调用业务层对象的方法
- 把JavaBean作为参数传递给业务层
- 基于业务层方法的执行结果,判断:
- 成功:进入到success.html页面
- 失败:进入到error.html页面
- service
- 定义用户登录功能
- 接收web层传递的JavaBean对象
- 实例化dao层对象,并把JavaBean对象传递给dao层
- 基于dao层中的功能返回值进行业务逻辑处理
- 定义用户登录功能
- dao
- 技术:mybatis
- 功能:
- 连接数据库
- sql语句
- 发送sql,接收结果
- 返回结果给service层
- web
17_解决中文乱码
post请求中文乱码问题
注意:如果将login.html页面中的form表单改为post提交,此时在登录页面提交汉字的时候,使用request接收数据的时候会出现中文乱码问题。form表单代码:
<form class="form-signin" action="/loginServlet" method="post">
在开发中,存在多种不同的编码表:
- ASCII码表:美国信息标准交换码
- ISO-8859-1 :拉丁码表(欧洲)
- 包含了ASCII码表
- big5 //繁体中文
- GB2312 //简体中文
- GBK //简体中文
- 国际计算机协议,提出统一的编码表:UTF-8
乱码产生原因
原因:Tomcat8只对于get请求处理了乱码问题。post请求并没有处理乱码。所以我们要手动进行处理。在进行手动处理乱码之前,我们要知道乱码是如何产生的。
乱码发生过程总结如下:
解决post请求乱码
默认情况下,tomcat服务器使用的的编码方式:iso-8859-1,而html页面是utf-8,我们可以采用先编码在解码的方式来处理。先将从页面获取的数据编码为iso-8859-1,然后在使用UTF-8进行解码。
代码如下:
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取用户名和密码
String username = request.getParameter("username");
//方式一:
//编码
// String encodeUsername = URLEncoder.encode(username, "iso-8859-1");
//解码
// username = URLDecoder.decode(encodeUsername, "utf-8");
//方式二:
//编码
// byte[] bytes = username.getBytes("iso-8859-1");
//解码
// username = new String(bytes, "utf-8");
//方式二变为一行代码
username = new String(username.getBytes("iso-8859-1"), "utf-8");
String password = request.getParameter("password");
System.out.println("username = " + username);
System.out.println("password = " + password);
//封装数据 javabean
User2 user = new User2();
user.setUsername(username);
user.setPassword(password);
//进行登陆业务操作
UserService service = new UserService();
boolean result = service.login(user);
if (result){
//登陆成功
//转发跳转success.html
request.getRequestDispatcher("/success.html").forward(request,response);
}else {
//登陆失败
request.getRequestDispatcher("/error.html").forward(request,response);
}
}
}
说明:
1、URLEncoder属于java.net包下的类,专门用来对HTML表单进行编码的。该类中的静态方法:
static String encode(String s, String enc) 使用特定的编码方案将字符串转换为指定的编码格式。
参数:
s 要编码的字符串
enc 使用的编码表
2、URLDecoder属于java.net包下的类,专门用来对HTML表单进行解码的。该类中的静态方法:
static String decode(String s, String enc) 使用特定的编码方案解码指定字符串。
参数:
s 要解码的字符串
enc 使用的编码表
控制台输出结果:username = 柳岩
注意:上述代码是可以解决post请求,可是如果换成get请求又会出现乱码。因为Tomcat8已经对于get请求处理了乱码问题。换句话说get请求方式我们拿到的已经是正确的数据了,如果在使用iso-8859-1编码,然后使用utf-8解码,又会导致乱码。所以我们可以使用另一种方式来解决post乱码。即使用request对象中的方法:setCharacterEncoding(String chasetName)
代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决post中文乱码问题
request.setCharacterEncoding("utf-8");
//获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username = " + username);
System.out.println("password = " + password);
//封装数据 javabean
User2 user = new User2();
user.setUsername(username);
user.setPassword(password);
//进行登陆业务操作
UserService service = new UserService();
boolean result = service.login(user);
if (result){
//登陆成功
//转发跳转success.html
request.getRequestDispatcher("/success.html").forward(request,response);
}else {
//登陆失败
request.getRequestDispatcher("/error.html").forward(request,response);
}
控制台输出结果:username = 柳岩.
注意:
- request.setCharacterEncoding(“utf-8”); 处理乱码一定放在获取数据的代码之前,一般我们都放在方法第一句话。先设置编码,在获取数据。
- request.setCharacterEncoding(“utf-8”); 表示设置请求编码集,只对请求体中的数据有效。而post具有请求体,get有请求体,请求体没有数据,所以只对post有效,get无效。
小结
-
当浏览器是GET请求时,在Tomcat中已解决了中文乱码问题
-
当浏览器是POST请求时,Tomcat没有解决中文乱码问题
-
使用request对象中的方法,来解决中文乱码
-
request.setCharacterEncoding("utf-8"); //仅对POST请求有效
-
必须保证设置字符集的代码放在doGet()或doPost()方法中的第一行位置
-
d(password);
//进行登陆业务操作
UserService service = new UserService();
boolean result = service.login(user);
if (result){
//登陆成功
//转发跳转success.html
request.getRequestDispatcher(“/success.html”).forward(request,response);
}else {
//登陆失败
request.getRequestDispatcher(“/error.html”).forward(request,response);
}
控制台输出结果:username = 柳岩.
**注意:**
- request.setCharacterEncoding("utf-8"); 处理乱码一定放在获取数据的代码之前,一般我们都放在方法第一句话。先设置编码,在获取数据。
- request.setCharacterEncoding("utf-8"); 表示设置请求编码集,==只对请求体中的数据有效==。而post具有请求体,get有请求体,请求体没有数据,所以只对post有效,get无效。
**小结**
- 当浏览器是GET请求时,在Tomcat中已解决了中文乱码问题
- 当浏览器是POST请求时,Tomcat没有解决中文乱码问题
- 使用request对象中的方法,来解决中文乱码
- ~~~java
request.setCharacterEncoding("utf-8"); //仅对POST请求有效
~~~
- ==必须保证设置字符集的代码放在doGet()或doPost()方法中的第一行位置==