Java24:会话管理 过滤器 监听器

2024-06-11 05:20

本文主要是介绍Java24:会话管理 过滤器 监听器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


一 会话管理


 1.cookie
  是一种客户端会话技术,cookie由服务端产生,它是服务器存放在浏览器的一小份数据,浏览器
  以后每次访问服务器的时候都会将这小份的数据带到服务器去。
    //创建cookie对象
        Cookie cookie1=new Cookie("keya","valuea");
        Cookie cookie2=new Cookie("keyb","valueb");
        //设置cookie的时效性,单位为秒
        cookie1.setMaxAge(10);
        //设置访问路径
        cookie1.setPath("/servlet1");
        //把cookie对象返回客户端
        resp.addCookie(cookie1);
        resp.addCookie(cookie2);
   2. session
    HttpSession 是一种保留更多信息在服务端的一种技术,服务器会为每个客户端开辟一块内存空     间,即session对象,
    客户端在发送请求时,都可以使用自己的session,这样服务端就可以通过session来记录
    某个客户端的状态了
      服务器在为客户端创建session时,会同时将session对象的id即,JSESSIONID以cookie的
      形式放入响应对象
      后端在创建完session后,客户端会收到一个特殊的cookie,叫做JSESSIONID
      客户端下一次请求时携带JSESSINID,后端收到后,根据JESSINID找到对应的session对象
      通过该机制,服务端通过session 就可以存储一些专门针对某个客户端的信息了。
      session 也是域对象
     
        //创建session对象
        HttpSession session = req.getSession();
        //设置session属性
        session.setAttribute("name","zhanasan");
        //获取sessionid
        String id = session.getId();
        System.out.println(id);
        //判断session是否新建
        System.out.println(session.isNew());
 
    3.ServletContext
      应用域对象是ServletContext,传递数据范围是本应用之内,可以跨多个会话
     创建ServletContext对象
     getServletContext()
     三大域使用场景:
     请求转发时,请求域可以传递数据:请求域内一般存放本次请求业务相关的数据,如查询到的所有部门信息
     同一个会话内,不用请求转发,会话域可以传递数据,会话域内一般放本次会话的客户端有关的数据,如当前客户端登录的用户
     同一个app内,不同的客户端应用域可以传递数据,应用域内一般放本程序应用有关的数据 ,如Spring框架的IOC容器

4.实例:获取三大域属性 :ServletA 设置三个域的属性,ServletB获取三个域的属性,通过变更访问路径验证三个域的范围
     

@WebServlet("/servletA")
public class ServletA extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 请求域req.setAttribute("request","requestvalue");// 会话域HttpSession session = req.getSession();String id = session.getId();System.out.println("session:"+id);session.setAttribute("session","sessionvalue");//应用域ServletContext servletContext = this.getServletContext();servletContext.setAttribute("application","applicationvalue");//请求转发req.getRequestDispatcher("/servletB").forward(req,resp);}
}

      

@WebServlet("/servletB")
public class ServletB extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取请求域对象属性值String  requestvalue = (String) req.getAttribute("request");System.out.println("request:"+requestvalue);// 获取会话域属性值HttpSession session = req.getSession();String id = session.getId();System.out.println("session:"+id);String sessionvalue = (String) session.getAttribute("session");System.out.println("session:"+sessionvalue);//应用域ServletContext servletContext = this.getServletContext();servletContext.setAttribute("application:","applicationvalue");String applicationvalue = (String) servletContext.getAttribute("application");System.out.println("application:"+applicationvalue);}
}

二:过滤器

1.定义

过滤器 是JAVAEE技术规范之一,作用目标资源的请求进行过滤的一套技术规范,是java web项目中最为实用的技术之一。

2.过滤器位置

3.过滤器原理及实现

 》Filter接口定义了过滤器的开发规范,所有的过滤器都要实现该接口

》Filter的工作位置是项目中所有目标资源之前,容器在创建HttpServletRequest和HttpServletResponse对象后,会先调用Filter的doFilter方法

》Filter的doFilter方法可以控制请求是否继续,如果放行,则请求继续,如果拒绝,则请求到此为止,由过滤器本身做出响应

》Filter 不仅可以对请求做出过滤,也可以在目标资源做出响应前,对响应再次进行处理

》过滤器实现过滤需在web.xml 配置过滤资源路径或者通过注解实现(@WebFilter)

》web.xml配置方式:

<filter><filter-name>filter1</filter-name><filter-class>com.cn.filter.Filter1</filter-class>
</filter><filter-mapping><filter-name>filter1</filter-name><url-pattern>/*</url-pattern></filter-mapping>

 4.过滤器实现访问资源耗时统计

@WebFilter("/*")
public class FilterTest implements Filter {private SimpleDateFormat simpleDateFormat= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//请求父转子,获取请求资源HttpServletRequest httpServletRequest= (HttpServletRequest) servletRequest;HttpServletResponse httpServletResponse= (HttpServletResponse) servletResponse;StringBuffer requestURL = httpServletRequest.getRequestURL();String format = simpleDateFormat.format(new Date());String  info="在"+format+"访问资源"+requestURL;System.out.println(info);long t1 = System.currentTimeMillis();//放行过滤器filterChain.doFilter(servletRequest,servletResponse);//统计访问资源耗时long t2 = System.currentTimeMillis();System.out.println(info+"共耗时"+(t2-t1)+"毫秒");}
}
@WebServlet("/servlet1")
public class MyServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("servlet。。。");resp.getWriter().write("hello");}
}

5.过滤器生命周期

阶段            对应方法                                            执行时机       执行次数

创建对象    构造器                                                web应用启用     1

初始化方法 void init(FilterConfig filterConfig)  构造完毕            1

过滤请求    void doFilter(三个参数)                      每次请求           多次

销毁          defalut void destroy()                       weby 应用关闭     1

6.过滤器链执行顺序 

一个web项目中 ,可以同时定义多个过滤器,多个过滤器对同一个资源过滤时,工作位置有先后,整体形成一个工作链,称之为过滤器链

》过滤器链中的过滤器顺序由filter-mapping顺序决定

》每个过滤器过滤的范围不同,针对同一个资源来说,过滤器链中的过滤器个数可能是不同的

》如果某个Filter是使用ServletName进行匹配规则的配置,那么这个Filter执行的优先级要更低

过滤器执行顺序实现

三个过滤器

public class Filter1 implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("dofilter1 before invoke");filterChain.doFilter(servletRequest,servletResponse);System.out.println("dofilter1 after invoke");}
}
public class Filter2 implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("dofilter2 before invoke");filterChain.doFilter(servletRequest,servletResponse);System.out.println("dofilter2 after invoke");}
}
public class Filter3 implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("dofilter3 before invoke");filterChain.doFilter(servletRequest,servletResponse);System.out.println("dofilter3 after invoke");}
}
访问资源
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("servlet1");resp.getWriter().write("good!");}
}

过滤路径配置:(如果使用注解,则按照过滤器类名排序)

<filter><filter-name>filter1</filter-name><filter-class>com.cn.filter.Filter1</filter-class>
</filter><filter-mapping><filter-name>filter1</filter-name><url-pattern>/*</url-pattern></filter-mapping><filter><filter-name>filter2</filter-name><filter-class>com.cn.filter.Filter2</filter-class>
</filter><filter-mapping><filter-name>filter2</filter-name><url-pattern>/*</url-pattern>
</filter-mapping><filter><filter-name>filter3</filter-name><filter-class>com.cn.filter.Filter3</filter-class>
</filter><filter-mapping><filter-name>filter3</filter-name><url-pattern>/*</url-pattern></filter-mapping>

7.过滤器实现登录控制 :实现浏览器在不登录的情况下不能直接访问资源:ScheduleController 和loginsucess.html

ScheduleController代码:

@WebServlet("/schedule/*")
public class ScheduleController extends BaseController{protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("add");}
}

loginsucess.html代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body>
<h1>登录成功!请浏览你的日程吧!</h1></body>
</html>
SysUserController 修改后的代码
@WebServlet("/sysuser/*")
public class SysUserController extends BaseController {private SysUserService userservice = new SysUserServiceImpl();protected void login(HttpServletRequest req, HttpServletResponse resp) throws Exception {//1获取请求参数String username = req.getParameter("username");String userPwd = req.getParameter("pwd");//调用服务层处理SysUser sysuer = userservice.login(username);if(null==sysuer){resp.sendRedirect("/loginusernameerror.html");}else if( !userPwd.equals(sysuer.getUserPwd())){resp.sendRedirect("/loginpassworderror.html");}else{ //登录成功后,把用户信息存入session域HttpSession session = req.getSession();session.setAttribute("sysuer",sysuer);resp.sendRedirect("/loginsucess.html");}}}
LoginFilter过滤器代码:

@WebFilter(urlPatterns = {"/schedule/*","/loginsucess.html"})
public class LoginFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest httpservletRequest= (HttpServletRequest) servletRequest;HttpServletResponse httpservletRespone = (HttpServletResponse) servletResponse;HttpSession session = httpservletRequest.getSession();Object sysuer = session.getAttribute("sysuer");if(sysuer==null){//未登录,直接跳转登录界面httpservletRespone.sendRedirect("/login.html");}else{//登录成功,直接放行filterChain.doFilter(servletRequest,servletResponse);}}
}

三.监听器


1. 定义:

专门用于对域对象身上发生的事件或状态改变进行监听和相应处理的对象
  
 》监听器时GOF设计模式中,观察者模式的典型案例
 》观察者模式:当被观察的对象发生某些改变时,观察者自动采取对应的行动的一种设计模式
 》监听器使用的感受类似JS中的事件,被观察的对象发生某些情况时,自动触发代码的执行
 》监听器并不监听web项目的所有组件,仅仅是对三大域对象做相关的事件监听
 
 2.监听器分类

 application域监听器:ServletContextListener, ServletContextAttributeListener
 session域监听器:HttpSessionListener , HttpSessionAttributeListener
 rquest域监听器:ServletRequestListener,ServletRequestAttributeListener

3.实例

servlet代码:

@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext ServletContext = getServletContext();ServletContext.setAttribute("keya","keyavalue");HttpSession session = req.getSession();session.setAttribute("k1","v1");}
}
@WebServlet("/servlet2")
public class Servlet2 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext ServletContext = getServletContext();ServletContext.setAttribute("keya","keyaXXXX");HttpSession session = req.getSession();session.setAttribute("k1","v11");}
}
@WebServlet("/servlet3")
public class Servlet3 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext ServletContext = getServletContext();ServletContext.removeAttribute("keya");HttpSession session = req.getSession();session.removeAttribute("k1");}
}

监听器代码:

@WebListener
public class MyListener implements ServletContextListener, ServletContextAttributeListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {ServletContext servletContext = sce.getServletContext();System.out.println(sce.hashCode()+"初始化了");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {ServletContext servletContext = sce.getServletContext();System.out.println(sce.hashCode()+"销毁了");}@Overridepublic void attributeAdded(ServletContextAttributeEvent sce) {ServletContext servletContext = sce.getServletContext();String name = sce.getName();Object value = sce.getValue();System.out.println(sce.hashCode()+"新增属性"+name+"值为:"+value);}@Overridepublic void attributeReplaced(ServletContextAttributeEvent sce) {ServletContext servletContext = sce.getServletContext();String name = sce.getName();Object value = sce.getValue();Object newvalue = servletContext.getAttribute(name);System.out.println(sce.hashCode()+"修改属性"+name+"值为:"+value+"新值"+newvalue);}@Overridepublic void attributeRemoved(ServletContextAttributeEvent sce) {ServletContext servletContext = sce.getServletContext();String name = sce.getName();servletContext.removeAttribute(name);System.out.println(sce.hashCode()+"删除属性"+name);}
}

四.Ajax

1.简介

Ajax=Asynchronous JavaScript and XML(异步的JavaScript和XML)
Ajax 不是新的编程语言,,而是一种使用现有标准的新方法
Ajax 最大的优点是在不重新加载整个界面的情况下,可以与服务器交换数据并更新部分网页内容
Ajax 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行
XMLHttpRequest只是实现Ajax的一种方式

2.实例:实现用户注册,用户名重复的提示功能,并使用json格式返回给前端

枚举类定义响应码和响应信息:ResultCodeEnum 
public enum ResultCodeEnum {SUCESS(200,"sucess"),USERNAME_ERROR(501,"username_error"),PASSWORD_ERROR(502,"password_error"),NOTLOGIN(503,"notlogin"),NAMEDUSED(505,"nameused");private Integer code;private String message;private ResultCodeEnum(Integer code,String message){this.code=code;this.message=message;}public Integer getCode() {return code;}public String getMessage() {return message;}
}
响应结果的实体类定义:Result<T> 

public class Result<T> {private Integer code;private String message;private  T data;public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public T getData() {return data;}public void setData(T data) {this.data = data;}public Result(){}protected  static <T> Result<T> build(T data){Result<T> result= new Result<T>();if(data!=null){result.setData(data);}return result;}public static <T> Result<T>build(T body,Integer code,String message){Result<T> result=build(body);result.setCode(code);result.setMessage(message);return result;}public static <T> Result<T> build(T body , ResultCodeEnum resultCodeEnum){Result<T> result=build(body);result.setCode(resultCodeEnum.getCode());result.setMessage(resultCodeEnum.getMessage());return result;}public  static <T> Result<T> ok(T data){Result<T> result=build(data);return build(data,ResultCodeEnum.SUCESS);}}

 控制器新增方法:SysUserController

WebServlet("/sysuser/*")
public class SysUserController extends BaseController {
    protected void checkusernameused(HttpServletRequest req, HttpServletResponse resp) throws Exception {String username = req.getParameter("username");SysUser user = userservice.findByName(username);Result result=Result.ok(null);if(user!=null){result=Result.build(null, ResultCodeEnum.NAMEDUSED);}//把对象转换为json格式ObjectMapper objectMapper =new ObjectMapper();String info = objectMapper.writeValueAsString(result);//返回信息,设置格式为jsonresp.setContentType("application/json;charset=utf-8");resp.getWriter().write(info );}
}

前端register.html 修改的代码(红色部分为Ajax实现的部分)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>span{font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;color: red;}</style><script>//校验用户名function checkusername(){var reg=/^[a-zA-Z0-9]{6,10}$/var usernameobj= document.getElementById("user1")var uservalue=usernameobj.valuevar usercheck=reg.test(uservalue)var sp1= document.getElementById("sp1")if(!usercheck){sp1.innerText="用户名不正确"return false}//用户名登录正确,校验是否被占用 //1.创建对象var request=  new XMLHttpRequest()//2.设置回调函数request.onreadystatechange=function (){if(request.readyState==4&&request.status==200){var info= JSON.parse(request.responseText)if(info.code==505){sp1.innerText="不可用"}}}// 3.设置访问路径request.open("get","/sysuser/checkusernameused?username="+uservalue)//4.发送访问request.send()sp1.innerText="OK"return true}//校验密码function checkpassword(){var reg=/^\d{6}$/var pwdobj= document.getElementById("pw1")var pwdvalue=pwdobj.valuevar pwdcheck=reg.test(pwdvalue)var sp2= document.getElementById("sp2")if(!pwdcheck){sp2.innerText="密码不正确"return false}sp2.innerText="OK"return true}//校验确认密码function checkconformpassword(){var reg=/^\d{6}$/var pwdobj2= document.getElementById("pw2")var pwdvalue2=pwdobj2.valuevar pwdcheck2=reg.test(pwdvalue2)var sp3= document.getElementById("sp3")if(!pwdcheck2){sp3.innerText="密码格式不正确"return false}//获取密码输入,并和确认密码比较是否相等var pwdobj= document.getElementById("pw1")var pwdvalue=pwdobj.valueif(pwdvalue2!=pwdvalue){sp3.innerText="密码和确认密码不相等"return false}sp3.innerText="OK"return true}//表单提交校验function checkregister(){
var flag1=checkpassword()
var flag2=checkpassword()
var flag3=checkconformpassword()return flag1&&flag2&&flag3}</script>
</head>
<body>
<h1 >登录管理系统</h1><form action="/sysuser/register" method="get" οnsubmit="return checkregister()"><table cellspacing="0px"  ><tr><td>用户名:</td><td><input type="text" name="username" id="user1"  οnblur="checkusername()"><span id="sp1"></span><br></td></tr><tr><td>密 码:</td><td><input type="password"name="userpwd" id="pw1" οnblur="checkpassword()"><span id="sp2"></span><br></td></tr><tr><td>确认密 码:</td><td><input type="password" id="pw2" οnblur="checkconformpassword()"><span id="sp3"></span><br></td></tr><tr><td colspan="2"><input type="submit" value="注册"><input  type="reset" value="重置"><button> <a  href="login.html">登录</a> </button></td></tr></table></form>
</body>
</html>

这篇关于Java24:会话管理 过滤器 监听器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1050293

相关文章

SpringBoot实现多环境配置文件切换

《SpringBoot实现多环境配置文件切换》这篇文章主要为大家详细介绍了如何使用SpringBoot实现多环境配置文件切换功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 示例代码结构2. pom文件3. application文件4. application-dev文

JavaScript实战:智能密码生成器开发指南

本文通过JavaScript实战开发智能密码生成器,详解如何运用crypto.getRandomValues实现加密级随机密码生成,包含多字符组合、安全强度可视化、易混淆字符排除等企业级功能。学习密码强度检测算法与信息熵计算原理,获取可直接嵌入项目的完整代码,提升Web应用的安全开发能力 目录

java对接第三方接口的三种实现方式

《java对接第三方接口的三种实现方式》:本文主要介绍java对接第三方接口的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录HttpURLConnection调用方法CloseableHttpClient调用RestTemplate调用总结在日常工作

Spring 缓存在项目中的使用详解

《Spring缓存在项目中的使用详解》Spring缓存机制,Cache接口为缓存的组件规范定义,包扩缓存的各种操作(添加缓存、删除缓存、修改缓存等),本文给大家介绍Spring缓存在项目中的使用... 目录1.Spring 缓存机制介绍2.Spring 缓存用到的概念Ⅰ.两个接口Ⅱ.三个注解(方法层次)Ⅲ.

Spring Boot 整合 Redis 实现数据缓存案例详解

《SpringBoot整合Redis实现数据缓存案例详解》Springboot缓存,默认使用的是ConcurrentMap的方式来实现的,然而我们在项目中并不会这么使用,本文介绍SpringB... 目录1.添加 Maven 依赖2.配置Redis属性3.创建 redisCacheManager4.使用Sp

Spring Cache注解@Cacheable的九个属性详解

《SpringCache注解@Cacheable的九个属性详解》在@Cacheable注解的使用中,共有9个属性供我们来使用,这9个属性分别是:value、cacheNames、key、key... 目录1.value/cacheNames 属性2.key属性3.keyGeneratjavascriptor

redis在spring boot中异常退出的问题解决方案

《redis在springboot中异常退出的问题解决方案》:本文主要介绍redis在springboot中异常退出的问题解决方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴... 目录问题:解决 问题根源️ 解决方案1. 异步处理 + 提前ACK(关键步骤)2. 调整Redis消费者组

一文教你Java如何快速构建项目骨架

《一文教你Java如何快速构建项目骨架》在Java项目开发过程中,构建项目骨架是一项繁琐但又基础重要的工作,Java领域有许多代码生成工具可以帮助我们快速完成这一任务,下面就跟随小编一起来了解下... 目录一、代码生成工具概述常用 Java 代码生成工具简介代码生成工具的优势二、使用 MyBATis Gen

springboot项目redis缓存异常实战案例详解(提供解决方案)

《springboot项目redis缓存异常实战案例详解(提供解决方案)》redis基本上是高并发场景上会用到的一个高性能的key-value数据库,属于nosql类型,一般用作于缓存,一般是结合数据... 目录缓存异常实践案例缓存穿透问题缓存击穿问题(其中也解决了穿透问题)完整代码缓存异常实践案例Red

SpringCloud整合MQ实现消息总线服务方式

《SpringCloud整合MQ实现消息总线服务方式》:本文主要介绍SpringCloud整合MQ实现消息总线服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、背景介绍二、方案实践三、升级版总结一、背景介绍每当修改配置文件内容,如果需要客户端也同步更新,