02.HTTP协议介绍与查看方式【理解】
1.思考
浏览器与服务器传输的数据格式有没有要求?
答:有,使用http协议规范浏览器与服务器的传输数据格式
2.目标
掌握http协议的作用
掌握http协议数据查看方式
3.http协议介绍与作用
介绍
hypertext transaction protocol 超文本传输协议,HTTP是一个简单的请求-响应协议,它通常运行在TCP/IP通信基础之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。
作用
规范浏览器与服务器传输的请求数据与响应数据的格式
4.http协议传输内容的组成
请求数据部分
响应数据部分
5.http协议数据查看方式
- 使用浏览器开发者工具F12查看(常用的,简单,对原生数据进行包装,但是不专业)
- 使用专业抓包工具软件查看(了解,适合学习http协议原生数据格式)
6.查看方式1—使用浏览器查看
-
准备一个请求页面
<!DOCTYPE html> <html lang="zh_CN"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--login 是一个 servlet--> <h2>GET 提交</h2> <form action="login" method="get"> 用户名: <input type="text" name="username"><br/> 密码: <input type="password" name="pwd"><br/> <input type="submit" value="登录"> </form> <hr> <h2>POST 提交</h2> <form action="login?action=addUser&hobby=football" method="post"> 用户名: <input type="text" name="username"><br/> 密码: <input type="password" name="pwd"><br/> <input type="submit" value="登录"> </form> </body> </html>
-
浏览器浏览页面
访问地址
http://localhost:8080/day25_request_war_exploded/01.index.html
浏览器效果
-
浏览器使用F12打开开发者工具,点击“登录”如图查看http协议数据
使用浏览器查看有如下特点
1.查看方便,以后主要使用这种方式 2.所有http协议的被浏览器包装过,不够原生态,不是真正的http协议数据格式
7.查看方式2—使用Fillder专业抓包工具查看数据【了解】
- 软件安装:根据提供的软件"FiddlerSetup-5.0.20173.50948.exe",双击运行根据引导下一步完成引导安装
- Fiddler软件界面查看http协议数据介绍(建议使用IE浏览器,这个软件是微软开发的)
8.http协议特点
http协议是无状态,无状态代表http协议不会存储传输数据,只是规定传输数据的格式。
9.小结
-
http协议的作用?
规范了浏览器与服务器传输的请求与响应数据格式
-
http协议传输数据怎么看?
使用浏览器的开发者工具查看(推荐) 使用抓包工具Fiddler(查看原生http协议数据的工具)
-
http协议特点
无状态
03.请求数据介绍1—数据组成【理解】
目标
掌握http协议请求数据由三部分组成
掌握get与post提交的请求数据区别和传输数据位置
http协议请求数据组成
小结
-
请求数据组成几个部分?
请求行 请求头 请求体
-
get提交请求参数数据位于请求信息哪个部分中?
请求行
-
post提交请求参数数据位于请求信哪个部分中?
请求体
04.请求数据介绍2—request对象介绍与作用【理解】
目标
掌握request对象类体系结构
掌握request的作用
request对象介绍
当浏览器提交请求数据给到服务器,服务器会创建一个对象接收所有请求数据,这个对象就是request
request对象体系结构
idea快捷键查看类关系
使用快捷键Ctrl+N,搜索HttpServletRequest,进入这个类
使用快捷键Ctrl+F12,查看当前类内部所有成员
使用快捷键Ctrl+H, 查看当前类的实现或子类
使用快捷键Ctrl+Alt+U,查看当前类的继承实现接口的结构
request的作用
1. 可以获取所有的请求数据(请求行、请求头、请求体)
2. request可以进行请求转发的页面跳转
3. request是一个作用域对象(请求域)
小结
-
request对象类结构体系?
父接口:ServletRequest 子接口:HttpServletRequest
-
request对象的作用?
获取请求数据 服务器端的页面跳转 操作服务器内存数据
05.request作用1-获取请求数据1-请求行【应用】
思考
请求行数据如何获取?格式如下
GET http://www.itcast.cn/ HTTP/1.1
请求行格式:提交数据请求方法+请求的url+使用的http协议版本
答:使用request对象获取
目标
了解使用request对象获取请求行的数据
掌握request获取提交数据方法类型api方法
掌握request获取部署资源目录名字路径的api方法
常用api方法
代码实现步骤
-
创建一个servlet
-
获取请求行的数据
package com.itheima.request._02row;
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(name = "RowServlet", urlPatterns = "/RowServlet")
public class RowServlet 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 {
//目标:获取请求行数据并打印到控制台输出
//请求行格式:提交数据请求方法+请求的url+使用的http协议版本
//1.获取提交数据的请求方法【重点】
String method = request.getMethod();
//2.获取请求的url
String url = request.getRequestURL().toString();
//3.获取http协议版本
String protocol = request.getProtocol();
//4.扩展其他获取
//4.1 获取当前资源部署目录的名字【重点】
String contextPath = request.getContextPath();
//4.2 获取客户端浏览器的ip地址
String clientIP = request.getRemoteAddr();//客户端浏览器的ip地址:0:0:0:0:0:0:0:1
//当使用localhost本地访问的时候,ip会返回0:0:0:0:0:0:0:1 代表本地ip地址,使用其他就返回真实ip地址
System.out.println("获取提交数据的请求方法:"+method);
System.out.println("获取请求的url:"+url);
System.out.println("获取http协议版本:"+protocol);
System.out.println("资源部署目录的名字:"+contextPath);
System.out.println("客户端浏览器的ip地址:"+clientIP);
}
}
运行效果
访问浏览器地址
http://127.0.0.1:8080/day25_request_war_exploded/RowServlet
访问效果
Http协议版本介绍【了解】
协议版本 | 介绍 |
---|---|
HTTP1.0 | (淘汰) 短连接,在一个TCP连接上只能传输一个HTTP请求和响应 |
HTTP1.1 | (默认,普及应用) 长连接,在一个TCP连接上可以传送多个HTTP请求和响应,也可以并发进行,但是并发的个数有限,2~4个 |
HTTP2 | (实验阶段) 长连接,传输数据完全是二进制格式,多路复用并发处理比HTTP1.1高出好几个等级,非常快. |
HTTPS | 安全,数据加密传输,一般实现有2种: 第一种:对HTTP1.1数据加密传输,应用广泛 第二种:对HTTP2数据加密传输 |
第三方机构测试对比:Http1.1 VS Http2
测试网站:https://http2.akamai.com/demo
以上所有协议由服务器设置支持就可以实现,服务器默认使用HTTP1.1
小结
-
使用request对象可以获取请求方法的类型的api方法?
request.getMethod();
-
使用request对象可以获取当前部署的资源目录名字的api方法?
request.getContextPath();
06.request作用1-获取请求数据2-请求头【应用】
目标
使用request对象获取请求头数据
常用api方法
代码实现
package com.itheima.request._03head;
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.Enumeration;
@WebServlet(name = "_01HeadServlet", urlPatterns = "/_01HeadServlet")
public class _01HeadServlet 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 {
//目标:获取请求头的数据并打印到控制台
/*
* request获取请求头api方法
* 1. request.getHeader(String name) 根据请求头的名字获取对应的值
* 2. request.getHeaderNames() 根据请求头的名字列表集合
* */
//1.获取所有请求头的名字列表
Enumeration<String> enumeration = request.getHeaderNames();
//2.循环遍历打印每一对请求头的键与值
while (enumeration.hasMoreElements()){
//获取每一个元素(请求头的名字)
String key = enumeration.nextElement();
//根据key获取value
String value = request.getHeader(key);
System.out.println(key+":"+value);
}
}
}
效果
访问地址:
http://127.0.0.1:8080/day25_request_war_exploded/_01HeadServlet
请求头相关信息简单介绍【了解】
请求头1—referer功能演示
访问第一个资源地址
http://localhost:8080/day25_request_war_exploded/01.index.html
点击“登录”访问第二个资源地址,请求头信息referer显示第一个资源的地址
请求头2—if-Modified-Since功能演示
if-modified-since请求头的功能,浏览器用于判断访问的资源是否使用缓存
下面演示:浏览器请求服务端静态资源第一次是从服务获取,浏览器如果启用了缓存,就会将静态资源缓存到本地,那么第二次再次访问就会从本地获取获取。如果服务器更新了静态资源,浏览第三次获取静态资源就会重新从服务器获取缓存到本地
疑问:浏览器访问服务器获取资源,如何知道服务器是否更新了静态资源?
答:浏览器第一次请求静态资源,服务器会响应一个资源的最后修改时间给浏览器,浏览器缓存资源的同时也保存了时间,浏览器第二次请求静态资源同时携带缓存时间给到服务器,服务器对比浏览器传过来的时间与资源文件的修改时间,如果一样服务器让浏览器回去取自己的本地缓存,否则服务器会响应这个最新的静态资源给到浏览器显示。
总结
浏览器只能对静态资源进行缓存,默认没有对动态资源缓存。而且静态资源的缓存不用开发人员管理,服务器域浏览器自动管理。
小结
-
根据请求头的key获取value
request.getHeader(key);
07.request作用1-获取请求数据3-请求体【应用】
目标
掌握使用request获取请求方法get或post提交的参数数据方法api
常用api方法
案例需求
准备一个用户注册表单页面,输入数据提交给服务器,服务器使用request相关api方法获取提交的表单数据。
代码实现
-
代码结构
-
准备一个页面data.html提交请求get/post请求参数数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>用户注册</h2> <!--action设置服务器资源的地址,就是访问的servlet地址--> <form action="GetRequestDataServlet" method="post"> 用户名: <input type="text" name="name"><br/> 性别: <input type="radio" name="gender" value="male" checked="checked"/>男 <input type="radio" name="gender" value="female"/>女 <br/> 城市: <select name="city"> <option value="guangzhou">广州</option> <option value="shenzhen">深圳</option> <option value="zhuhai">珠海</option> </select> <br/> 爱好: <input type="checkbox" name="hobby" value="上网"/>上网 <input type="checkbox" name="hobby" value="上学"/>上学 <input type="checkbox" name="hobby" value="上车"/>上车 <input type="checkbox" name="hobby" value="上吊"/>上吊 <br/> <input type="submit" value="注册"/> </form> </body> </html>
-
创建一个servlet用于获取请求参数数据
package com.itheima.request._04body; 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; @WebServlet(name = "_01BodyServlet", urlPatterns = "/GetRequestDataServlet") public class _01BodyServlet 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 { //目标:使用request获取客户端提交请求参数数据 /* * request获取get或post提交请求数据的api方法 * 1. request.getParameter(String name) 根据请求参数数据的name获取对应的一个Sting类型的value * 2. request.getParameterValues(String name) 根据请求参数数据的name获取一组String[]的数据 * 3. request.getParameterMap() 获取所有请求参数数据的键值对返回一个Map<String,String[]> * */ //用户名 String name = request.getParameter("name"); //性别 String gender = request.getParameter("gender"); //城市 String city = request.getParameter("city"); //爱好 String[] hobbies = request.getParameterValues("hobby"); //打印到控制台 System.out.println("用户名:"+name); System.out.println("性别:"+gender); System.out.println("城市:"+city); System.out.println("爱好:"+ Arrays.toString(hobbies)); } }
运行效果
访问地址
http://localhost:8080/day25_request_war_exploded/_0401data.html
运行效果
点击注册,控制台输出效果
注意:乱码后面处理
小结
-
获取请求参数数据核心方法需要记住3个
request.getParameter(name) 获取对应一个value,返回String request.getParameterValues(name) 获取对应一组value, 返回String[]
request.getParaemeterMap() 获取所有键值对Map集合数据,返回Map<String,String[]>
### 08.request作用1-解决Post请求数据中文乱码【应用】
##### 目标
请求参数以post方式提交中文会乱码,我们要知道如何解决和产生的原因
##### 问题
1. 让客户端post提交中文
提交中文:传智
2. 服务器端获取请求参数数据没有解决中文乱码的效果
![\[外链图片转存失败(img-mpttR5HP-1566097077564)(assets/)\]](https://img-blog.csdnimg.cn/20190818110634608.png)
##### 原理分析
servlet中的request读取数据的时候默认采用iso8859-1进行解码,iso8859-1码表不支持中文
request应该使用与浏览器提交时使用的码表一致才不会乱码
![\[外链图片转存失败(img-Ig19RpQE-1566097077564)(assets/1546074461467.png)\]](https://img-blog.csdnimg.cn/20190818110653975.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0J1bGlkX0V2b2x0bw==,size_16,color_FFFFFF,t_70)
由于页面使用的utf-8,所有需要设置request也是用utf-8,api方法如下:
```java
//解决POST提交中文乱码问题
request.setCharacterEncoding("utf8");
解决代码
运行效果
小结
request获取post提交中文数据为什么会乱码?如何解决?
request读取post请求的中文数据默认采用iso8859-1码表,不支持中文
设置request码表为utf-8
09.request作用1-BeanUtils封装数据【应用】
思考
如果客户端提交大量数据,服务器端一个一个获取是非常麻烦,如何解决?
需要使用工具类实现自动封装数据,第三方工具BeanUtils
目标
使用第三方工具BeanUtils实现自动封装对象数据
BeanUtils介绍
BeanUtils 是 Apache commons组件的成员之一,主要用于简化JavaBean封装数据的操作。它可以将一个表单提交的所有数据封装到JavaBean中。
BeanUtils工具jar包与api方法介绍
BeanUtils相关Jar包
jar包下载地址:http://www.commons.apache.org/
- commons-beanutils-1.9.3.jar 工具核心包
- commons-logging-1.2.jar 日志记录包
- commons-collections-3.2.2.jar 增强的集合包
BeanUtils工具类的api方法
案例需求
将用户注册信息页面的表单数据提交给服务器端,服务器采用BeanUtils自动封装数据到User对象中。
实现步骤
- 创建实体类User类,用于封装数据的类
- 导入beansUtils的jar包到项目WEB-INF/lib目录下
- 在servlet里面使用BeanUtils工具类方法封装数据到User对象中
- 打印测试
类结构
User实体类
package com.itheima.entity;
import java.util.Arrays;
public class User {
//这里设计的属性名与Map的key保持一致,Map的数据可以来自于浏览器提交的表单数据
private String name;
private String gender;
private String city;
private String[] hobby;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", city='" + city + '\'' +
", hobby=" + Arrays.toString(hobby) +
'}';
}
public User() {
}
public User(String name, String gender, String city, String[] hobby) {
this.name = name;
this.gender = gender;
this.city = city;
this.hobby = hobby;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
}
导入jar
servlet使用BeanUtils获取请求参数封装到User对象中
package com.itheima.request._04body;
import com.itheima.entity.User;
import 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.Arrays;
@WebServlet(name = "_01BodyServlet", urlPatterns = "/GetRequestDataServlet")
public class _01BodyServlet 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 {
//解决post提交中文乱码
request.setCharacterEncoding("utf-8");//码表有2中写法:utf-8或utf8
//目标:使用BeanUtils一次性将浏览器提交的表单所有数据封装到JavaBean中
//1.创建一个User的java类设计属性可以封装表单的所有数据
//2.实例User类
User user = new User();
try {
//3.使用BeanUtils的方法进行一次性将表单所有数据自动封装到User对象中
// 核心方法: BeanUtils.populate(封装的对象,Map<String,Object>)
// 这个方法可以将Map中的key的值自动封装到对象属性中,属性名与Map的key一样
BeanUtils.populate(user,request.getParameterMap());
} catch (Exception e) {
e.printStackTrace();
//如果发生系统异常,给出用户友好信息
response.setContentType("text/html;charset=utf8");
response.getWriter().write("服务器忙。。。");
return;
}
}
}
效果
小结
-
request获取所有请求数据(所有表单数据)api方法?
request.getParameterMap() 返回 Map<String,String[]>
2.使用BeanUtils给JavaBean对象封装数据的api方法是什么?
BeanUtils.populate(javaBean,map);
10.request作用2-请求转发页面跳转【应用】
思考
前端跳转页面包含:
a标签超链接
form表单的提交
location.href操作浏览器地址栏
后端跳转页面有2种:
1.request请求转发跳转
2.response重定向跳转
目标
可以使用request对象进行页面跳转
请求转发跳转的api方法
request.getRequestDispatcher("/要跳转到的地址").forward(request, response);
实现步骤
- 创建2个Servlet, OneServlet和TwoServlet
- 实现OneServlet跳转到TwoServlet
代码结构
OneServlet代码
package com.itheima.request._05请求转发跳转;
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(name = "OneServlet", urlPatterns = "/OneServlet")
public class OneServlet 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 {
//目标:实现从OneServlet跳转到TwoServlet
request.getRequestDispatcher("/TwoServlet").forward(request,response);
}
}
TwoServlet代码
package com.itheima.request._05请求转发跳转;
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(name = "TwoServlet", urlPatterns = "/TwoServlet")
public class TwoServlet 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 {
response.getWriter().write("TwoServlet");
}
}
效果
页面跳转前访问地址
http://localhost:8080/day25_request_war_exploded/OneServlet
运行效果
页面跳转后的地址
http://localhost:8080/day25_request_war_exploded/OneServlet
小结
request可以实现页面跳转,并且url没有变化
11.request作用2-response对象重定向页面跳转【应用】
目标
服务器进行页面跳转有2种方式:
request请求转发跳转
response重定向页面跳转
会使用进行response重定向页面跳转
response重定向跳转的api方法
response.sendRedirect("/资源部署目录名字/资源路径");
实现步骤
- 创建2个Servlet, OneServlet2和TwoServlet2
- 实现OneServlet2重定向跳转到TwoServlet2
代码结构
OneServlet2代码
package com.itheima.request._06response实现重定向跳转;
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(name = "OneServlet2", urlPatterns = "/OneServlet2")
public class OneServlet2 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 {
//目标:实现从OneServlet2重定向跳转到TwoServlet2
// 重定向url="/资源部署目录名字/资源路径"
// "/资源部署目录名字"获取语法:request.getContextPath();
response.sendRedirect(request.getContextPath()+"/TwoServlet2");
}
}
TwoServlet2代码
package com.itheima.request._06response实现重定向跳转;
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(name = "TwoServlet2", urlPatterns = "/TwoServlet2")
public class TwoServlet2 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 {
response.getWriter().write("TwoServlet2");
}
}
效果
重定向跳转前访问地址:
http://localhost:8080/day25_request_war_exploded/OneServlet2
运行效果
重定向跳转后的地址
http://localhost:8080/day25_request_war_exploded/TwoServlet2
小结
response也可以实现跳转,url改变了
12.request作用2-请求转换与重定向的区别【理解】
目标
可以理解转发与重定向的实现跳转资源原理
request请求转发跳转结果:url不变
response重定向跳转结果:url变了
request请求转换页面跳转原理
response重定向页面跳转原理
小结
转发:跳转前后的2个资源共享同一个request和response
重定向:跳转前后的2个资源不共享request和response
13.request作用3-是一个作用域对象(请求域)【应用】
目标
使用request对象存储数据到服务器内存,资源之间在服务器端可以通过服务器内存传递数据
servlet作用域介绍
-
作用域介绍
就是服务器的内存对象,可以操作内存存储数据
-
作用域对象一共有3个
请求域request,今天学习这个
会话域session,
上下文域servletContext
-
作用域对象作用
实现动态资源之间传递数据,使用服务器内存域对象
作用域存储数据的api方法
request内存请求域对象的应用场景
实现请求转发跳转前后2个资源传递数据.
请求域传递数据步骤
- 创建2个资源,OneServlet3和TwoServlet3
- 在OneServlet3设置request对象存储数据,请求转发跳转到TwoServlet3, TwoServlet3获取request里面的数据
实现代码
OneServlet3代码
package com.itheima.request._07请求域实现请求转发跳转传递数据;
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(name = "OneServlet3", urlPatterns = "/OneServlet3")
public class OneServlet3 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 {
//目标:OneServlet3存储数据,跳转到TwoServlet3
//1.写入数据到请求域
request.setAttribute("name","隔壁老王");
//2.跳转到TwoServlet3
request.getRequestDispatcher("/TwoServlet3").forward(request,response);
}
}
TwoServlet3代码
package com.itheima.request._07请求域实现请求转发跳转传递数据;
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(name = "TwoServlet3", urlPatterns = "/TwoServlet3")
public class TwoServlet3 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 name = (String) request.getAttribute("name");
//打印输出
response.setContentType("text/html;charset=utf8");
response.getWriter().write(name);
}
}
效果
访问地址:
http://localhost:8080/day25_request_war_exploded/OneServlet3
运行效果
小结
-
域对象将数据存储到哪里去了?
存储数据到服务器的内存中
-
request请求域的范围
一次请求内,请求来到服务器创建request和respons对象,服务器响应完后request和response就会被销毁
-
域对象的作用?
实现资源之间传递数据
-
什么时候使用重定向?什么时候使用转发?
如果跳转前后2个页面传递数据使用请求转发,其他情况建议使用重定向
14.案例-登录功能1-案例介绍与环境搭建【理解】
需求
实现用户登录, 输入用户名与密码提交到服务器后端,用户名与密码正确就登录成功,否则登录失败
环境搭建步骤
-
创建项目
-
导入页面原型
-
创建数据库表
create table `user2`( id int primary key auto_increment, username varchar(20), password varchar(32) ); insert into `user2`(username, password) values ('Jack','123'),('Rose','456'); select * from `user2`;
-
创建实体类User
package com.itheima.entity; public class User { private int id; private String username; private String password; @Override public String toString() { return "User{" + "id=" + id + ", useranme='" + username + '\'' + ", password='" + password + '\'' + '}'; } public User() { } public User(int id, String username, String password) { this.id = id; this.username = username; this.password = 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; } }
-
导入相关jar包
mysql数据库驱动包 mybatis的jar包 log4j的jar包 BeanUtils的jar包
-
导入配置文件
-
目录结构
15.案例-登录功能2-三层架构分析与数据访问层实现【理解】
目标
掌握三层架构的好处,并应用与开发
实现分析
三层架构解决问题
三层如下
三层架构的好处
1.分层开发,职责明确
dao,数据访问层,专门负责操作数据库增、删、改、查数据
service,处理业务逻辑,举例子:一个业务方法可以操作调用dao多个方法,实现操作多条sql语句
web,表现层,专门负责与用户浏览器交互
2.适合团队开发,三层架构将代码写到很多类中,适合多人一起开发。
实现步骤
实现代码
package com.itheima.dao;
import com.itheima.entity.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface IUserDao {
//根据用户名与密码查询用户对象
//@Param 给参数起别名,之后在sql语句中使用别名,一般这个注解应用在多个参数的时候
@Select("SELECT * FROM user2 WHERE username=#{username} and password=#{password}")
User findUser(@Param("username") String username,@Param("password") String password);
}
小结
-
三层架构指哪三层?
dao service web
-
三层架构的好处?
分层开发,职责清晰 适合团队开发,维护成本低
### 16.案例-登录功能3-业务层与web层实现【应用】
##### 整个代码结构
##### 实现代码
1. 实现service代码
```java
package com.itheima.service;
import com.itheima.dao.IUserDao;
import com.itheima.entity.User;
import com.itheima.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
public class UserService {
//登录的业务方法
public User login(String username, String password){
//调用dao根据用户名与密码查询用户并返回
//1.获取sqlSession
SqlSession sqlSession = MybatisUtils.getSession();
//2.获取dao代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//3.调用方法获取数据
User user = userDao.findUser(username, password);
//4.释放资源sqlSession
MybatisUtils.closeSession(sqlSession);
//5. 返回数据
return user;
}
}
-
实现LoginServlet代码
package com.itheima.web; import com.itheima.entity.User; import com.itheima.service.UserService; 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(name = "LoginServlet", urlPatterns = "/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } //实例业务(放在这里只会创建一次) private UserService userService = new UserService(); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //处理登录请求 //解决post传递中文乱码问题 request.setCharacterEncoding("utf8"); //处理输出数据乱码问题 response.setContentType("text/html;charset=utf8"); //1.获取用户名与密码 String username = request.getParameter("name"); String password = request.getParameter("password"); //2.调用业务根据用户名与密码获取用户对象 User loginUser = userService.login(username, password); if(loginUser==null) { //3.用户对象为null, 输出登录失败 //response.getWriter().write("登录失败"); //跳转到失败页面 response.sendRedirect(request.getContextPath()+"/failure.html"); }else { //4.用户对象有效,输出登录成功 //response.getWriter().write("登录成功"); //将用户对象存储到请求域,跳转到SuccessServlet,显示用户名 request.setAttribute("loginUser",loginUser); //转发跳转 request.getRequestDispatcher("/SuccessServlet").forward(request,response); } } }
Failure.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>登录失败</h3> </body> </html>
SuccessServlet代码
package com.itheima.web; import com.itheima.entity.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(name = "SuccessServlet", urlPatterns = "/SuccessServlet") public class SuccessServlet 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 { //目标:显示欢迎XX登录成功 //1.从请求域里面获取登录用户对象 User loginUser = (User) request.getAttribute("loginUser"); //2.输出数据 response.getWriter().write("欢迎"+loginUser.getUsername()+"登录成功"); } }
17.总结
1) 能够使用工具查看 HTTP 协议内容
浏览器开发者工具
2) 能够理解 HTTP 协议请求内容
包含3个部分
请求行
请求头
请求体
3) 能够使用 Request 对象获取 HTTP 协议请求内容
使用request可以获取请求行,头,体数据
4) 能够处理 HTTP 请求参数的乱码问题
处理解决post请求参数中文乱码
request.setCharacterEncoding("utf8")
5) 能够使用 Request 域对象
request.setAttribute(key,vlaue);
request.getAttribute(key);
request.removeAttribute(key);
6) 能够使用 Request 对象做请求转发
request.getRequestDispatcher(url).forward(request,response);
theima.web;
import com.itheima.entity.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(name = “SuccessServlet”, urlPatterns = “/SuccessServlet”)
public class SuccessServlet 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 {
//目标:显示欢迎XX登录成功
//1.从请求域里面获取登录用户对象
User loginUser = (User) request.getAttribute("loginUser");
//2.输出数据
response.getWriter().write("欢迎"+loginUser.getUsername()+"登录成功");
}
}