- 多个servlet共享方案
- ServletContext接口和cookie
- HttpSession接口
- HttpServletRequest接口实现数据共享
- servlet监听器接口
- ServletContextListener接口:
- ServletContextAttributeListener接口:
- Filter接口 过滤器
- 防止用户恶意登录/访问
- 结语
看Java(二十五)的内容
HttpSession接口HttpSession接口来自于Servlet规范下一个接口,存在于Tomcat中servlet-api.jar,其实现类由Http服务器提供;
如果两个Servlet来自同一个网站,并且为同一个浏览器、用户提供服务。此时借助于HttpSession对象进行数据共享;
开发人员将HttpSession接口修饰对象称为会话作用域对象;
HttpSessino 与 cookie 区别:
存储位置:
cookie:放在客户端计算机(浏览器内存/硬盘)
HttpSession:存放在服务端计算机内存
数据类型:
cookie对象存储共享数据类型只能时String
HttpSession对象可以存储任意类型的共享数据Object
数据数量:
一个cookie只能存储一个共享数据
HttpSession使用Map集合存储共享数据,可以存储任意数量共享数据
参照物:
cookie相当于客户端在服务端【会员卡】
HttpSession相当于客户端在服务端【私人保险柜】
实现步骤:
看代码
购物首页
| 商品名称 | 商品单价 | 评价 | 放入购物车 |
| 笔记本 | 6000 | 好 | 放入购物车 |
| 电视 | 800 | 好 | 放入购物车 |
| 苹果 | 5.5 | 变质 | 放入购物车 |
package com;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class OneServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String goodsName;
//请求头获取商品名称
goodsName = request.getParameter("goodsName");
System.out.println(goodsName);
//调用请求对象,向Tomcat索要当前用户在服务端的储物柜
HttpSession session = request.getSession();
//将用户选购的商品添加到当前用户私人储物柜
Integer goodsNum = (Integer)session.getAttribute(goodsName);
if(goodsName == null){
session.setAttribute(goodsName,1);
}else{
session.setAttribute(goodsName,goodsNum + 1);
}
}
}
package com;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Enumeration;
public class TwoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//调用请求对象,向Tomcat索要当前对象在服务端私人储物柜
HttpSession session = request.getSession();
//将session中的所有key读取出来,存放一个枚举对象
Enumeration goodsNames = session.getAttributeNames();
while (goodsNames.hasMoreElements()){
String goodsName = (String)goodsNames.nextElement();
int goodsNum = (int)session.getAttribute(goodsName);
System.out.println("商品名称:" + goodsName + "商品数量:" + goodsNum);
}
}
}
结果:
代码有bug,容我改改!!!
HttpSession的销毁
用户与HttpSession关联时使用的cookie只能存放在浏览器缓存中;
在浏览器关闭时,意味着用户与他的HttpSession关联被切断;
由于Tomcat无法检测浏览器何时关闭,因此在浏览器关闭时并不会导致Tomcat将浏览器关联的HttpSesssion销毁;
为了解决这个问题,Tomcat为每个HttpSession对象设置了空闲时间,这个空闲时间默认为30min,如果档期那HttpSession对象空闲时间达到30分钟,此时Tomcat认为用户已经放弃了自己的HttpSession,此时Tomcat就会销毁掉这个HttpSession;
设定空闲时间
设定5s
HttpServletRequest接口实现数据共享5
同一个网站中,如果两个Servlet之间通过请求转发方式进行调用,彼此之间共享同一个请求协议包。二一个请求协议包只对应一个请求对象,因此servlet之间共享同一个请求对象,此时可以利用这个请求对象在两个Servlet之间实现数据共享 ;
在请求对象实现Servlet之间数据共享功能时,开发人员将请求对象称为请求作用域;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//将数据添加到请求作用域,作为共享数据
request.setAttribute("key1","http");
//代替浏览器,向Tomcat索要TwoServlet完成剩余任务
request.getRequestDispatcher("/one").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//从OneServlet中得到共享数据
String result = request.getAttribute("key1").toString();
System.out.println(result);
}
servlet监听器接口
一组来自Servlet规范下接口,共有8个接口。在Tomcat存在servlet-api.jar包
监听器接口需要由开发人员亲自实现,Http服务器提供jar包没有对应的实现类;
监听器接口用于监控作用域对象生命周期变化时刻以及作用域对象共享数据变化时刻;
作用域对象:服务端内存中可以子某些条件下为两个Servlet之间提供数据共享方案的对象,被称为作用域对象
servlet规范下作用域对象:
servletContext:全局作用域对象;
HttpSession:会话作用域对象;
HttpServletRequest:请求作用域对象;
监听器接口实现类开发规范:三步:
1、根据监听的实际情况,选择对应监听器接口进行实现
2、重写监听器接口声明监听事件处理方法
3、在web.xml文件将监听器接口实现类注册到Http服务器
作用:通过这个接口合法的检测 全局作用域对象被初始化时刻以及被销毁时刻
监听事件处理方法:
public void contextInitlized() : 在全局作用域对象被Http服务器初始化被调用;
public void contextDestory() : 在全局作用域对象被Http服务器销毁时触发调用;
OneListener.java
监听类要放在一个listener的文件夹当中
package com.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class OneListener implements ServletContextListener
{
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("创建时");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("销毁时");
}
}
在web.xml中声明
com.listener.OneListener
结果:
作用:通过这个接口合法的检测全局作用域对象共享数据变化时刻
监听事件处理方法:
public void contextAdd() : 在全局作用域对象添加共享数据
public void context replace() : 在全局作用域对象更新对象更新共享数据
public void contextRemove() : 在全局在于对象删除共享数据
package com.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
public class OneListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("新增共享数据");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("删除共享数据");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("更新共享数据");
}
}
package com.controller;
import javax.servlet.ServletContext;
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")
public class OneServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext application = request.getServletContext();
application.setAttribute("key1","学习java");
application.setAttribute("key1","学习C++");
application.removeAttribute("key1");
}
}
com.listener.OneListener OneServlet com.controller.OneServlet OneServlet /one
结果:
来自于Servlet规范下接口,在Tomcat中存在于servler-api.jar包
Filter接口实现类由开发人员负责提供,Http服务器不负责提供
Filter接口在Http服务器调用资源文件之前,对Http服务器进行拦截
作用:拦截Http服务器,帮助Http服务器检测当前请求合法性,对当前请求进行增强操作。
开发步骤:
1、创建一个java类实现Filter接口
2、重写Filter接口中doFilter方法
3、web.xml将过滤器接口实现类注册到Http服务器
例子
package com.filter;
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
public class OneFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String age = (String)servletRequest.getParameter("age");
System.out.println(age);
if(Integer.parseInt(age) < 18){
//拒绝本次请求
servletResponse.setContentType("text/html;charset=utf-8");
PrintWriter out = servletResponse.getWriter();
out.println("未成年人不得访问");
}else{
filterChain.doFilter(servletRequest,servletResponse);//放行
}
}
@Override
public void destroy() {
}
}
OneFilter com.filter.OneFilter OneFilter /mm.jpg
结果:
age属性<18,拦截不显示图片
用过滤器对浏览器进行增强
Title
先写一个htm,用来给用户传一个userName的参
然后用两个Servlet来获取这个userName
package com.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class OneServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//直接从请求体中读取请求参数
String userName = (String)request.getParameter("userName");
System.out.println("oneServlet从请求体得到的:" + userName);
}
}
package com.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TwoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//直接从请求体中读取请求参数
String userName = (String)request.getParameter("userName");
System.out.println("twoServlet从请求体得到的:" + userName);
}
}
如果没有设置utf-8,那么获得的中文字符在控制台打印出来是???,如果在每个Servlet都设置一次,则比较麻烦,因此,可以在过滤器中统一进行设置
OneServlet.java
package com.filter;
import javax.servlet.*;
import java.io.IOException;
public class OneFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
结果
拦截地址格式
如上例子,有
在当前网站中调用任意文件都经过过滤器
OneFilter if(user != null){ HttpSession session = request.getSession(); } HttpSession session = request.getSession(false); if(session == null){ System.out.println("你是非法用户!"); }else{ System.out.println("你是合法的!"); response.sendRedirect("/myWeb/this.html"); } } }
一个负责拦截的Filter
package com.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.http.HttpRequest;
public class OneFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request= (HttpServletRequest) servletRequest;
HttpSession session = request.getSession(false);
if(session == null){
System.out.println("你是非法的");
return;
}else{
System.out.println("欢迎欢迎!!!");
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
被访问的this.html
Title
这是一个被保护的html
结果:
正常访问this.html
经过servlet,跳到了this.html
再来个非法访问
直接输入localhost:……this.html访问,页面不显示
控制台输出:
2021.9.29结束,没什么感想,还要搞很多东西



