一、转发与重定向
1、简介
-
什么是转发
- 同一个请求作用域里面,从一个目标组件(jsp/Servlet)跳转到另一个目标组件(jsp/Servlet),url地址是不会发生改变的
-
什么是重定向
- 它其实也是从一个目标组件跳转到另一个目标组件,但不是在同一个请求作用域里面,并且url地址是发生改变的
2、原理问题
-
如图以下描述
结论 -
转发是属于同一个请求对象
-
重定向是属于不同的请求对象,并且url地址会发生改变
3、如何实现转发
- 实现转发有两种方式
写法一:
getServletContext().getRequestDispatcher("/BServlet").forward(request,response);
写法二:
request.getRequestDispatcher("/BServlet").forward(request,response);
举例
- AServlet
package servlet;
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(value = "/AServlet")
public class AServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("当前是A servlet");
//将数据存储到request对象
request.setAttribute("username","tom");
//转发到B Servlet组件
//request.getRequestDispatcher("/BServlet").forward(request,response);
getServletContext().getRequestDispatcher("/BServlet").forward(request,response);
}
}
- BServlet
package servlet;
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.io.PrintWriter;
@WebServlet(value = "/BServlet")
public class BServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
String username= (String) request.getAttribute("username");
resp.setCharacterEncoding("UTF-8");
//设置响应文档类型
resp.setContentType("text/html");
PrintWriter pw=resp.getWriter();
pw.println("<html>");
pw.println("<body>");
pw.println("<h1>");
pw.println("当前是B Servlet username="+username);
pw.println("</h1>");
pw.println("</body>");
pw.println("</html>");
}
}
4、如何实现重定向
- 如何实现重定向
response.sendRedirect("/DServlet");
举例
- CServlet类
package servlet;
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(value = "/CServlet")
public class CServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("当前是C servlet");
request.setAttribute("username","tom");
//重定向到D Servlet
response.sendRedirect("/DServlet");
}
}
package com.gec.servlet;
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.io.PrintWriter;
@WebServlet(value = "/DServlet")
public class DServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
String result="";
Object usernameObj=request.getAttribute("username");
if(usernameObj==null)
{
//前端将会输出不能从request获取数据,因为不同请求对象
result="不能从request获取数据";
}else {
result= (String) usernameObj;
}
resp.setCharacterEncoding("UTF-8");
//设置响应文档类型
resp.setContentType("text/html");
PrintWriter pw=resp.getWriter();
pw.println("<html>");
pw.println("<body>");
pw.println("<h1>");
pw.println("当前是D Servlet result="+result);
pw.println("</h1>");
pw.println("</body>");
pw.println("</html>");
}
}
二# 、Cookie用法
1、Cookie简介
- 服务端将数据存储到客户端的磁盘,就是通过cookie机制实现。它是在客户端访问Web服务器时,服务器在客户端硬盘上存放的信息,服务器可以根据Cookie来跟踪客户状态。
2、作用
- 服务器跟踪客户端的状态
3、原理
上述如图以下:
- 客户端发送请求(还没有产生cookie数据)
- 服务端生成cookie数据,将此cookie数据封装到响应头部信息内容
- 客户端接受到响应头信息,解释cookie数据,将cookie数据保存到本地文cookie件
- 下一次客户端再发请求给服务器,则从cookie文件取数据,将此数据封装到请求头,发送给服务器解释
- 服务器解释cooke的请求头部数据,获取数据
4、如何实现cookie操作
- 如何将数据存储到cookie
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//将数据存储到cookie
//新建一个cookie对象,是以键值对保存的
Cookie cookie=new Cookie("user","tom");
//设置cookie的存活时间
cookie.setMaxAge(7*24*60*60); //单位是“秒“,所以一星期内有效
//将cookie数据写到http协议响应部分的头部信息
response.addCookie(cookie);
}
如何从cookie读取数据
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//读取cookie数据
Cookie cookies[]=request.getCookies();
for (Cookie cookie : cookies) {
System.out.println("name="+cookie.getName()+" value="+cookie.getValue());
}
}
三、会话实现
1、简介
- 当客户端发送请求给服务器,则已经建立一次会话(Session)关系
2、产生会话的条件
-
当直接访问jsp页面
-
在Servlet组件,request调用getSession()方法
//创建一次会话,也就是产生一个Session对象
HttpSession session=request.getSession();
或者
HttpSession session=request.getSession(true);
//若尚未存在HttpSession实例,则直接返回null,它不会创建新的Session对象
HttpSession session=request.getSession(false);
3、会话作用
-
http协议它是一种无状态的协议
- http协议具有健忘症
- 前一次请求的数据,会全部丢失
- http协议具有健忘症
-
如何将数据保存,使得每次请求都获取,这就依赖于session机制。
4、如何操作会话
- 创建会话
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session=request.getSession();
//将数据保存到会话对象session里面,我们就可以在其他servlet里面访问到数据了
session.setAttribute("username",username);
session.setAttribute("password",password);
}
//我们就可以在其他servlet里面访问到数据了,代码如下
获取会话信息
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session=request.getSession();
//获取session数据
String username= (String) session.getAttribute("username");
String password= (String) session.getAttribute("password");
//这里就获取到了username值和password值
}
注销会话
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session对象
HttpSession session=request.getSession();
//注销会话
session.invalidate();
}
配置session有效期
- 在web.xml文件配置
<session-config>
<!--默认分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>
5、会话原理
-
每次会话,都会独立产生一个session对象
-
不同的主机,或者同一台主机(但不同的浏览器),产生会话对象是不同的
-
上述描述:
- ServletContext它是Web应用的共享对象,也就是全局对象
- 一般不用ServletContext对象保存数据,因为一个Web应用就对应一个ServletContext对象,当不同客户端同时访问这个Web应用时,对于ServletContext对象,后面的客户端的数据会覆盖前面客户端提交的数据。
- Session是会话里面的共享对象
-
Session工作机制
····客户端发送请求到服务端,当直接访问jsp页面或者request调用getSession()方法时,产生会话,同时生成SessionId。
····服务端容器产生SessionId之后,被封装到响应的头部信息,记住传的是id,而不是username值和password的值
····接下来的步骤和cookie差不多
····最后web容器拿到sessionid再解析之后,就可以找到对应这个sessionid的数据,比如图中username=tom,password=1111,
····因此可以看出,username=tom,password=1111是
四、监听器
1、简介
- 针对HttpServletRequest、HttpSession、ServletContext对象的创建及销毁,实现事件监听
2、监听器类别
- ServletContextListener
- ServletContextAttributeListener
- HttpSessionListener
- HttpSessionAttributeListener
- HttpSessionBindingListener
- ServletRequestListener
- ServletRequestAttributeListener
3、ServletContextListener用法
-
简介
- 监听ServletContext对象的创建及销毁
-
什么时候创建ServletContext对象
- 当启动Web应用
-
什么时候销毁ServletContext对象
- 当停止Web应用
-
如何实现监听器
-
加注解,实现接口,重写对应接口的两方法
- 方式一:使用注解
@WebListener
public class MyServletContextListener implements ServletContextListener
{
/*
* 当Web应用启动,会触发此方法
* */
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("servletContext对象创建");
}
/*
* 当Web应用停止,会触发此方法
* */
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("servletContext对象销毁");
}
}
方式二:并在web.xml文件注册
public class MyServletContextListener implements ServletContextListener
{
/*
* 当Web应用启动,会触发此方法
* */
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("servletContext对象创建");
}
/*
* 当Web应用停止,会触发此方法
* */
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("servletContext对象销毁");
}
}
在web.xml文件注册
<listener>
<listener-class>com.gec.listener.MyServletContextListener</listener-class>
</listener>
4、HttpSessionListener
-
简介
- 主要针对HttpSession对象的创建及销毁的监听
-
举例
- 通过注解创建监听器
package com.gec.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class MyHttpSessionListener implements HttpSessionListener {
/*
* 当会话创建,触发此方法
* */
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("会话创建 会话id="+se.getSession().getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("会话销毁 会话id="+se.getSession().getId());
}
}
5、ServletRequestListener用法
-
简介
- 针对每次请求的创建及销毁的监听
-
用法
- 监听器
package listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("请求对象销毁");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("请求对象创建");
}
}
6、HttpSessionAttributeListener用法
-
简介
- 针对session对象的数据进行操作(添加、删除、替换)
-
用法实现
@WebListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
/*
* 当数据添加到session,触发此方法
* */
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("当数据添加到session");
}
/*
* 当数据从session移除,触发此方法
* */
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("当数据从session移除");
}
/*
* 当数据从session替换,触发此方法
* */
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("当数据从session替换");
}
}