目录
HttpServletRequest
简介
常见API
HttpServletResponse
简介
常见API
请求转发和响应重定向
概述
请求转发
响应重定向
会话
会话跟踪方案:
会话跟踪方案对比:
1、Cookie
2、Session(底层基于Cookie实现)
Cookie与Session的交互
3、令牌技术
总结:
HttpServletRequest
简介
HttpServletRequest是什么
-
HttpServletRequest是一个接口,其父接口是ServletRequest
-
HttpServletRequest是Tomcat将请求报文转换封装而来的对象,在Tomcat调用service方法时传入
-
HttpServletRequest代表客户端发来的请求,所有请求中的信息都可以通过该对象获得
常见API
HttpServletRequest怎么用
-
获取请求行信息相关(方式,请求的url,协议及版本)
API | 功能解释 |
---|---|
StringBuffer getRequestURL(); | 获取客户端请求的url |
String getRequestURI(); | 获取客户端请求项目中的具体资源 |
int getServerPort(); | 获取客户端发送请求时的端口 |
int getLocalPort(); | 获取本应用在所在容器的端口 |
int getRemotePort(); | 获取客户端程序的端口 |
String getScheme(); | 获取请求协议 |
String getProtocol(); | 获取请求协议及版本号 |
String getMethod(); | 获取请求方式 |
-
获得请求头信息相关
API | 功能解释 |
---|---|
String getHeader(String headerName); | 根据头名称获取请求头 |
Enumeration<String> getHeaderNames(); | 获取所有的请求头名字 |
String getContentType(); | 获取content-type请求头 |
-
获得请求参数相关
API | 功能解释 |
---|---|
String getParameter(String parameterName); | 根据请求参数名获取请求单个参数值 |
String[] getParameterValues(String parameterName); | 根据请求参数名获取请求多个参数值数组 |
Enumeration<String> getParameterNames(); | 获取所有请求参数名 |
Map<String, String[]> getParameterMap(); | 获取所有请求参数的键值对集合 |
BufferedReader getReader() throws IOException; | 获取读取请求体的字符输入流 |
ServletInputStream getInputStream() throws IOException; | 获取读取请求体的字节输入流 |
int getContentLength(); | 获得请求体长度的字节数 |
-
其他API
API | 功能解释 |
---|---|
String getServletPath(); | 获取请求的Servlet的映射路径 |
ServletContext getServletContext(); | 获取ServletContext对象 |
Cookie[] getCookies(); | 获取请求中的所有cookie |
HttpSession getSession(); | 获取Session对象 |
void setCharacterEncoding(String encoding) ; | 设置请求体字符集 |
HttpServletResponse
简介
HttpServletResponse是什么
-
HttpServletResponse是一个接口,其父接口是ServletResponse
-
HttpServletResponse是Tomcat预先创建的,在Tomcat调用service方法时传入
-
HttpServletResponse代表对客户端的响应,该对象会被转换成响应的报文发送给客户端,通过该对象我们可以设置响应信息
常见API
-
设置响应行相关
API | 功能解释 |
---|---|
void setStatus(int code); | 设置响应状态码 |
-
设置响应头相关
API | 功能解释 |
---|---|
void setHeader(String headerName, String headerValue); | 设置/修改响应头键值对 |
void setContentType(String contentType); | 设置content-type响应头及响应字符集(设置MIME类型) |
-
设置响应体相关
API | 功能解释 |
---|---|
PrintWriter getWriter() throws IOException; | 获得向响应体放入信息的字符输出流 |
ServletOutputStream getOutputStream() throws IOException; | 获得向响应体放入信息的字节输出流 |
void setContentLength(int length); | 设置响应体的字节长度,其实就是在设置content-length响应头 |
-
其他API
API | 功能解释 |
---|---|
void sendError(int code, String message) throws IOException; | 向客户端响应错误信息的方法,需要指定响应码和响应信息 |
void addCookie(Cookie cookie); | 向响应体中增加cookie |
void setCharacterEncoding(String encoding); | 设置响应体字符集 |
MIME类型
-
MIME类型,可以理解为文档类型,用户表示传递的数据是属于什么类型的文档
-
浏览器可以根据MIME类型决定该用什么样的方式解析接收到的响应体数据
-
可以这样理解: 前后端交互数据时,告诉对方发给对方的是 html/css/js/图片/声音/视频/... ...
-
tomcat/conf/web.xml中配置了常见文件的拓展名和MIMIE类型的对应关系
-
常见的MIME类型举例如下
文件拓展名 | MIME类型 |
---|---|
.html | text/html |
.css | text/css |
.js | application/javascript |
.png /.jpeg/.jpg/... ... | image/jpeg |
.mp3/.mpe/.mpeg/ ... ... | audio/mpeg |
.mp4 | video/mp4 |
.m1v/.m1v/.m2v/.mpe/... ... | video/mpeg |
请求转发和响应重定向
概述
什么是请求转发和响应重定向
-
请求转发和响应重定向是web应用中间接访问项目资源的两种手段,也是Servlet控制页面跳转的两种手段
-
请求转发通过HttpServletRequest实现,响应重定向通过HttpServletResponse实现
-
请求转发生活举例: 张三找李四借钱,李四没有,李四找王五,让王五借给张三
-
响应重定向生活举例:张三找李四借钱,李四没有,李四让张三去找王五,张三自己再去找王五借钱
请求转发
请求转发运行逻辑图
请求转发特点
请求转发通过HttpServletRequest对象获取请求转发器实现
请求转发是服务器内部的行为,对客户端是屏蔽的
客户端只发送了一次请求,客户端地址栏不变
服务端只产生了一对请求和响应对象,这一对请求和响应对象会继续传递给下一个资源
因为全程只有一个HttpServletRequset对象,所以请求参数可以传递,请求域中的数据也可以传递
请求转发可以转发给其他Servlet动态资源,也可以转发给一些静态资源以实现页面跳转
请求转发可以转发给WEB-INF下受保护的资源
请求转发不能转发到本项目以外的外部资源
请求转发测试代码
-
ServletA
@WebServlet("/servletA")
public class ServletA extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求转发器
// 转发给servlet ok
RequestDispatcher requestDispatcher = req.getRequestDispatcher("servletB");
// 转发给一个视图资源 ok
//RequestDispatcher requestDispatcher = req.getRequestDispatcher("welcome.html");
// 转发给WEB-INF下的资源 ok
//RequestDispatcher requestDispatcher = req.getRequestDispatcher("WEB-INF/views/view1.html");
// 转发给外部资源 no
//RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.atguigu.com");
// 获取请求参数
String username = req.getParameter("username");
System.out.println(username);
// 向请求域中添加数据
req.setAttribute("reqKey","requestMessage");
// 做出转发动作
requestDispatcher.forward(req,resp);
}
}
-
ServletB
@WebServlet("/servletB")
public class ServletB extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
String username = req.getParameter("username");
System.out.println(username);
// 获取请求域中的数据
String reqMessage = (String)req.getAttribute("reqKey");
System.out.println(reqMessage);
// 做出响应
resp.getWriter().write("servletB response");
}
}
-
打开浏览器,输入以下url测试
http://localhost:8080/web03_war_exploded/servletA?username=atguigu
响应重定向
响应重定向运行逻辑图
响应重定向特点
响应重定向通过HttpServletResponse对象的sendRedirect方法实现
响应重定向是服务端通过302响应码和路径,告诉客户端自己去找其他资源,是在服务端提示下的,客户端的行为
客户端至少发送了两次请求,客户端地址栏是要变化的
服务端产生了多对请求和响应对象,且请求和响应对象不会传递给下一个资源
因为全程产生了多个HttpServletRequset对象,所以请求参数不可以传递,请求域中的数据也不可以传递
重定向可以是其他Servlet动态资源,也可以是一些静态资源以实现页面跳转
重定向不可以到给WEB-INF下受保护的资源
重定向可以到本项目以外的外部资源
响应重定向测试代码
-
ServletA
@WebServlet("/servletA")
public class ServletA extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
String username = req.getParameter("username");
System.out.println(username);
// 向请求域中添加数据
req.setAttribute("reqKey","requestMessage");
// 响应重定向
// 重定向到servlet动态资源 OK
resp.sendRedirect("servletB");
// 重定向到视图静态资源 OK
//resp.sendRedirect("welcome.html");
// 重定向到WEB-INF下的资源 NO
//resp.sendRedirect("WEB-INF/views/view1");
// 重定向到外部资源
//resp.sendRedirect("http://www.atguigu.com");
}
}
-
ServletB
@WebServlet("/servletB")
public class ServletB extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
String username = req.getParameter("username");
System.out.println(username);
// 获取请求域中的数据
String reqMessage = (String)req.getAttribute("reqKey");
System.out.println(reqMessage);
// 做出响应
resp.getWriter().write("servletB response");
}
}
-
打开浏览器,输入以下url测试
http://localhost:8080/web03_war_exploded/servletA?username=atguigu
cookie&session
会话
会话:用户打开浏览器,访问web服务器的资源,会话建立。直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应
会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一台浏览器,以便在同一次会话的多次请求间共享数据(保存用户的登录信息、购物车内容、个性化设置等。)
会话跟踪方案:
1、客户端会话跟踪技术:Cookie
2、服务端会话跟踪技术:Session
3、令牌技术
会话跟踪方案对比:
1、Cookie
当用户访问网站时,服务器会向浏览器发送一个 Cookie,浏览器会将其存储下来,以后访问该网站时会自动将 Cookie 发送给服务器(会话信息存储在cookie中)
优点:
HTTP协议中支持的技术(浏览器自动进行)
缺点:
- 移动端APP无法使用Cookie
- 不安全(存储在客户端,用户的浏览器上),用户可以自己禁用Cookie
- Cookie不能跨域
Cookie存活时间
默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
setMaxAge(int seconds):设置Cookie存活时间
1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
2负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则 Cookie被销毁
3.零:删除对应Cookie
Cookie存储中文
Cookie不能直接存储中文,如需要存储,则需要进行转码:URL编码
2、Session(底层基于Cookie实现)
当用户访问网站时,服务器会为该用户创建一个 Session,并分配一个唯一的 Session ID。
用户后续的请求会携带这个 Session ID,服务器根据 Session ID 找到对应的会话信息(会话信息存储在服务端)
优点:存储在服务端,安全
缺点:
- 服务器集群环境下无法直接使用Session(不同次请求可能转给不同服务器,新服务器无法找到旧服务器的Session对象)
- Cookie的所有缺点
Cookie与Session的交互
在实际应用中,Cookie和Session经常一起使用来实现用户会话管理。当用户首次访问网站时,服务器会创建一个Session,并将Session的ID作为Cookie发送给用户的浏览器。此后,用户的浏览器在每次请求时都会将这个Session ID作为Cookie发送给服务器,服务器通过Session ID来识别用户并恢复其会话状态。
3、令牌技术
优点:
- 支持PC端、移动端
- 解决集群环境下的认证问题
- 减轻服务器端存储压力
缺点:
需要自己实现
- 服务端会话跟踪技术:将数据保存到服务端
- JavaEE提供HttpSession接口,来实现一次会话的多次请求间数据共享功能使用:
- 使用:
1.获取Session对象
- HttpSession session = request.getSession();
2. Session对象功能:
- void setAttribute(String name, Object o):存储数据到session域中
- Object getAttribute(String name):根据key,获取值
- void removeAttribute(String name):根据key,删除该键值对
1、服务器关闭后对cookie无影响(存储在客户端),session数据由于钝化活化还可能存在
2、浏览器关闭后浏览器中的session id直接销毁(相当于session失效),浏览器中的cookie不一定销毁(可以设置cookie存活时间)
总结
- Cookie和Session都是来完成一次会话内多次请求间数据共享的
区别:
- 存储位置:Cookie是将数据存储在客户端,Session将数据存储在服务端
- 安全性:Cookie不安全,Session安全
- 数据大小:Cookie最大3KB,Session无大小限制
- 存储时间:Cookie可以长期存储,Session 默认30分钟
- 服务器性能:Cookie不占服务器资源,Session 占用服务器资源