day41_servlet

news2024/12/25 12:30:19

今日内容

零、 复习昨日
一、Cookie
二、Session
三、拦截器
四、登录认证、全局编码格式

零、 复习昨日

注解

热部署

请求转发

重定向

路径问题

  • 总结使用经验: 无论请求路径是多层是单层,在写路径时都从/开始,即从根开始
  • 如果是服务器动作,从/开始直接写
  • 如果是浏览器动作,从/开始,需要再加上项目名

一、状态管理


1.1 现有问题

  • HTTP协议是无状态的,不能保存每次提交的信息

  • 如果用户发来一个新的请求,服务器无法知道它是否与上次的请求有联系。

  • 对于那些需要多次提交数据才能完成的Web操作,比如登录来说,就成问题了。

1.2 概念

将浏览器与web服务器之间多次交互当作一个整体来处理,并且将多次交互所涉及的数据(即状态)保存下来

1.3 状态管理分类

  • 客户端状态管理技术:将状态保存在客户端。代表性的是Cookie技术。

  • 服务器状态管理技术:将状态保存在服务器端。代表性的是session技术(服务器传递sessionID时需要使用Cookie的方式)

二、Cookie的使用


2.1 什么是Cookie

  • Cookie是在浏览器访问Web服务器的某个资源时,由Web服务器在HTTP响应消息头中附带传送给浏览器的一小段数据

  • 一旦Web浏览器保存了某个Cookie,那么它在以后每次访问该Web服务器时,都应在HTTP请求头中将这个Cookie回传给Web服务器。

  • 一个Cookie主要由标识该信息的名称(name)和值(value)组成。

Cookie原理
image-20230524220414095

2.2 创建Cookie

// 在服务器中
Cookie cookie = new Cookie(key,value);
// 响应出去到浏览器
resp.addCookie(cookie)

2.3 获取cookie

// 从请求中获得cookie.一次获得全部的cookie对象
// 但是一次获得当前站点所有cookie对象,没有获得单独某一个cookie
Cookie[] cookies = req.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
    Cookie ck = cookies[i];
    String name = ck.getName( );
    String value = ck.getValue( );
    System.out.println(name+"="+value );
}

2.4 删除cookie

  • 没有删除的方法
  • 主要靠最大生命值来确定
  • 默认保存至会话结束(浏览器关闭)
  • 也可以通过在创建时指定生命周期时间
    • setMaxAge
    • 大于0,存在指定的秒
    • 等于0,直接删除
    • 小于0,一般是-1 ,保存至浏览器关闭
        // 创建cookie
        Cookie cookie = new Cookie("username","admin");// 中文会乱码

        // 创建的cookie,默认存储到浏览器关闭.
        // 可以设置时间,单位是秒!!
        // cookie.setMaxAge(30);
        // cookie.setMaxAge(0); // 直接删除该cookie
        cookie.setMaxAge(-1); // 保存至浏览器关闭

2.5 修改Cookie

只需要保证Cookie的名和路径一致即可修改

//修改Cookie
Cookie ck=new Cookie("code", code);
ck.setPath("/webs");//设置Cookie的路径
ck.setMaxAge(-1);
response.addCookie(ck);//让浏览器添加Cookie
  • 注意:如果改变cookie的name和有效路径会新建cookie, 而改变cookie值、有效期会覆盖原有cookie

2.6 设置cookie的路径

所谓路径,其实就是cookie中数据保存的位置

Cookie不设置路径,默认路径是当前项目下

设计两个Servlet,来读取CookieServlet1设置的cookie

一个叫UserServlet,映射路径/user/ck,读取cookie

一个叫AdminServlet,映射路径/admin/ck,读取cookie

演示1:

​ CookieServlet1设置的cookie的路径默认是http://localhost/day40/

​ 通过http://localhost/day40/user/ck 能读取到cookie值

​ 通过http://localhost/day40/admin/ck 能读取到cookie值


演示2

​ CookieServlet1设置的cookie的路径为是==/day40/user==

​ 通过http://localhost/day40/user/ck 能读取到cookie值

​ 通过http://localhost/day40/admin/ck 能读取不到cookie值

// 设置cookie路径
cookie.setPath("/day40/user");

总结: cookie设置路径,其实就是设置cookie的读取范围

2.7 中文乱码解决

// 中文编码 URLEncoded.encoded("value","UTF-8")
// 将乱码解码成中文  URLDecode.decode(value,"UTF-8")
// cookie中文解决
// jdk自带有将中文编码和解码的方法
Cookie cookie = new Cookie(
    URLEncoder.encode("姓名","UTF-8"),
    URLEncoder.encode("张三","UTF-8"));
for (int i = 0; cookies != null && i < cookies.length; i++) {
    Cookie ck = cookies[i];
    String name = ck.getName( );
    String value = ck.getValue( );

    // 解码
    String u = URLDecoder.decode(name, "UTF-8");
    String v = URLDecoder.decode(value, "UTF-8");

    System.out.println(u+"="+v );
}

2.8 Cookie优点和缺点

2.8.1 优点

  • 可配置到期规则。

  • 简单性:Cookie 是一种基于文本的轻量结构,包含简单的键值对。

  • 数据持久性:Cookie默认在过期之前是可以一直存在客户端浏览器上的。

2.8.2 缺点

  • 大小受到限制:大多数浏览器对 Cookie 的大小有 4K、8K字节的限制。

  • 用户配置为禁用:有些用户禁用了浏览器或客户端设备接收 Cookie 的能力,因此限制了这一功能。、

  • 潜在的安全风险:Cookie 可能会被篡改。会对安全性造成潜在风险或者导致依赖于Cookie 的应用程序失败。

三、Session对象【重点


3.1 Session概述

  • Session用于记录用户的状态。Session指的是在一段时间内,单个客户端与Web服务器的一连串相关的交互过程。
  • 在一个Session中,客户可能会多次请求访问同一个资源,也有可能请求访问各种不同的服务器资源。

3.2 Session原理

  • 服务器会为每一次会话分配一个Session对象

  • 同一个浏览器发起的多次请求,同属于一次会话(Session)

  • 首次使用到Session时,服务器会自动创建Session,并创建Cookie存储SessionId发送回客户端

  • 注意:session是由服务端创建的。

3.3 Session使用

  • Session作用域:拥有存储数据的空间,作用范围是一次会话有效
    • 一次会话是使用同一浏览器发送的多次请求。一旦浏览器关闭,则结束会话
    • 可以将数据存入Session中,在一次会话的任意位置进行获取
    • 可传递任何数据(基本数据类型、对象、集合、数组)

3.3.1 获取Session

session是服务器端自动创建的,通过request对象获取

        //获取Session对象
		HttpSession session=request.getSession();
		System.out.println("Id:"+session.getId());//唯一标记,

3.3.2 Session保存数据

​ setAttribute(属性名,Object)保存数据到session中

	session.setAttribute("key",value);//以键值对形式存储在session作用域中。

ps: 登录后将登录信息存储到session

3.3.3 Session获取数据

​ getAttribute(属性名);获取session中数据

	session.getAttribute("key");//通过String类型的key访问Object类型的value

ps: 后续其他请求获取session,判断是否有对应的权限或者是否登录

3.3.4 Session移除数据

​ removeAttribute(属性名);从session中删除数据

	session.removeAttribute("key");//通过键移除session作用域中的值

3.3.5 Session失效

session.setMaxInactiveInterval(60*60);//设置session最大有效期为一小时

session.invalidate();//手工销毁

ps: 退出登录后,清空session

3.4 Session与Request应用区别

  • request是一次请求有效,只有一次请求转发内数据可以获得
  • session是一次会话内有效,无论请求转发还是重定向都是可以获得数据的

3.5 模拟登录认证

现有2个资源,一个是登录/login,一个是/add,没有登录认证之前,可以不用登录就可以访问/add所对应的资源,但是不合理,因此我们需要实现登录信息的认证!

即在操作/add等其他请求时我们需要判断这次请求前有没有登录,如果没有登录就响应(请求转发)到登录页面,如果登录过,那就该干什么干什么…

如何实现?

  • 需要在登录成功时,将登录信息存入session
  • 需要在操作/add等请求时先判断session有无登录信息
@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 登录成功,session存储数据
        HttpSession session = req.getSession( );
        session.setAttribute("username","tomcat");

        System.out.println("登录...");
    }
}
@WebServlet("/add")
public class AddServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 先判断有无登录
        HttpSession session = req.getSession( );
        String username = (String) session.getAttribute("username");
        if (username != null && !"".equals(username)) {
            // 假设这下面就是操作的功能,用输出语句代替,,,
            System.out.println("添加...");
        } else {
            // 没有登录,应该跳转到登录页面
            System.out.println("没有登录,无法操作..." );
        }
    }
}

四、过滤器Filter【重点


4.1 现有问题

在以往的Servlet中,有没有冗余的代码,多个Servlet都要进行编写。

4.2 概念

过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术。

过滤器
image-20230524220124509

4.3 过滤器作用

  • 执行地位在Servlet之前,客户端发送请求时,会先经过Filter,再到达目标Servlet中;响应时,会根据执行流程再次反向执行Filter

  • 可以解决多个Servlet共性代码的冗余问题(例如:乱码处理、登录验证)

4.4 编写过滤器

Servlet API中提供了一个Filter接口,开发人员编写一个Java类实现了这个接口即可,这个Java类称之为过滤器(Filter)

4.4.1 实现过程

  • 编写Java类实现Filter接口

  • 在doFilter方法中编写拦截逻辑

  • 设置拦截路径

4.5 过滤器配置

4.5.1 注解配置

在自定义的Filter类上使用注解@WebFilter(value=“/过滤目标资源”)

4.5.2 xml配置

<!--过滤器的xml配置  -->
  <filter>
  <!--名称-->
    <filter-name>sf</filter-name>
    <!--过滤器类全称-->
    <filter-class>com.qf.web.filter.SecondFilter</filter-class>
  </filter>
 <!--映射路径配置-->
  <filter-mapping>
     <!--名称-->
    <filter-name>sf</filter-name>
     <!--过滤的url匹配规则和Servlet类似-->
    <url-pattern>/*</url-pattern>
  </filter-mapping>

4.5.3 过滤器路径

过滤器的过滤路径通常有三种形式:

精确过滤匹配 ,比如/index.jsp   /myservlet1

后缀过滤匹配,比如*.jsp、*.html、*.jpg

通配符过滤匹配/*,表示拦截所有。注意过滤器不能使用/匹配。
	/aaa/bbb/* 允许

4.6 过滤器链和优先级

4.6.1 过滤器链

客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。

每个过滤器实现某个特定的功能,当第一个Filter的doFilter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则Web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

过滤器链
image-20230524220221983

4.6.2 过滤器优先级

在一个Web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
优先级:

  • 如果为注解的话,是按照类全名称的字符串顺序决定作用顺序

  • 如果web.xml,按照 filter-mapping注册顺序,从上往下

  • web.xml配置高于注解方式

  • 如果注解和web.xml同时配置,会创建多个过滤器对象,造成过滤多次。

4.7 过滤器应用1:全局编码

以前: 在每个servlet为了防止乱码,在进行操作之前,都先设置请求和响应的编码格式.

现在: 使用拦截器,对所有请求拦截器,设置编码,然后放行


package com.qf.servlet.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 对所有请求都是设置编码格式
 */
@WebFilter("/*")
public class EncodingFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 设置编码格式
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");


        // 放行
        chain.doFilter(request,response);
    }

    @Override
    public void destroy() { }
}

4.8 过滤器应用2: 身份认证拦截器

以前: 在web项目中,在每个Servlet中都要对身份进行认证

现在: 使用拦截器,将身份过滤的代码前置到拦截器,对每个请求先身份认证

package com.qf.servlet.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
@WebFilter("/*")
// @WebFilter("/hw/*")
// @WebFilter("*.do")
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    /**
     * 对请求的身份进行认证
     * 请求中获得session,且session中有登录时存入的数据,说明登录成功,放行
     * 请求中获得session,但是session中没有数据,说明没有登录,重定向到登录页
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        // 获取session
        HttpServletRequest req = (HttpServletRequest) request;
        HttpSession session = req.getSession( );

        String requestURI = req.getRequestURI( );

        /**
         * 因为是拦截所有 /*
         * 所以要放行 静态资源以及第一次登录的请求
         */
        if(requestURI.contains("/login") ||requestURI.contains("html") || requestURI.contains("js") || requestURI.contains("css")) {
            // 放行
            chain.doFilter(request, response);
        }

        // 从session获得数据
        String username = (String) session.getAttribute("username");

        // 判断
        if (username != null){
            // 放行
            chain.doFilter(request, response);
        } else {
            HttpServletResponse resp = (HttpServletResponse) response;
            resp.sendRedirect(req.getContextPath()+"/index.html");
        }

    }

    @Override
    public void destroy() { }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CVPR 2018 | Spotlight论文:单摄像头数秒构建3D人体模型

想把自己的身体形象投射进电子游戏里?现在已经是很容易的事了。人工智能算法此前已被广泛应用于虚拟现实头像、监视、服装试穿或电影等多种任务的人体建模上,但大多数方法需要特殊的照相设备来检测景深,或从多个角度探查人体。近日,来自德国布伦瑞克工业大学和 Max Planck …

js获取Element元素的常用方法

js中获取Element元素的常用方法有以下四种&#xff1a; 【方法一】根据元素ID&#xff1a;document.getElementById() 【方法二】根据元素标签&#xff1a;document.getElementsByTagName() 【方法三】根据元素class名&#xff1a;document.getElementsByClassName() 【方法…

yolov5刚开始train时的环境问题

torch会自动被requirement.txt替换 在对yolov5_5.0进行pip install requirement.txt后&#xff0c;yolo5_5.0会将虚拟环境中中的torch替换为2.0.1版本的&#xff0c;但要注意查看该torch是否为gpu版本&#xff0c;查看方式如下&#xff1a;打开Anaconda Prompt&#xff0c;激活…

渗透测试 | 端口扫描

0x00 免责声明 本文仅限于学习讨论与技术知识的分享&#xff0c;不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;本文作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担…

推荐系统算法详解

文章目录 基于人口统计学的推荐算法用户画像 基于内容的推荐算法相似度计算基于内容推荐系统的高层次结构特征工程数值型特征处理类别特征处理时间型特征处理统计型特征处理 推荐系统常见反馈数据基于UGC的推荐TF-IDFTF-IDF算法示例1. 引入依赖2. 定义数据和预处理3. 进行词数统…

12.区块链系列之比特币NFT

1. NFT协议Ordinals 2023年1月30日&#xff0c;比特币核心开发者Casey Rodarmor创建了NFT协议Ordinals Ordinals序数: 比特币的最小单位是Satoshi聪,1BTC1亿聪&#xff0c;每个聪的比特币都是同质化代币&#xff0c;它们之间并没有任何差别。Ordinals给聪打上了编号&#xff0…

vue3项目创建步骤,以及项目运行失败的原因和解决方法

vue3项目创建步骤&#xff0c;以及项目运行失败的原因和解决方法 vue3项目创建前提&#xff1a;搭建node.js环境第一步&#xff1a;创建一个空文件夹第二步&#xff1a;打开空文件夹&#xff0c;如图所示第三步&#xff1a;在此输入cmd&#xff0c;并按下回车键&#xff0c;进入…

Mysql面试必知的知识点-干货分享

文章目录 底层索引为什么使用B树,而不用B树?为什么Innodb索引建议必须建主键?为什么主键推荐使用整形自增?Mysql底层索引只有B树吗?联合索引底层长什么样子?数据库隔离级别中串行化是怎么实现的?查询方法需要加事务吗?大事务有什么影响? 底层索引为什么使用B树,而不用B…

Ai时代降临,我们的未来又在哪里?

文章目录 背景AI智能迭代进步码农的未来展望借助gpt快速成长总结 背景 随着人工智能的不断发展&#xff0c;自然语言处理技术也一直在不断的进步和发展&#xff0c;GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型作为自然语言处理领域最前沿的技术之一&a…

什么是Redission可重入锁,其实现原理是什么?

一、概述 Redission是一个可重入锁&#xff0c;它可以在分布式系统中用于实现互斥锁。这种锁可以允许多个线程同时获取锁&#xff0c;但在任何给定时间只有一个线程可以执行受保护的代码块。 Redission锁提供了一种简单的方法来保证在分布式系统中的互斥性&#xff0c;同时支…

chatgpt赋能python:Python中的父类方法和super函数

Python中的父类方法和super函数 在Python中&#xff0c;我们经常会涉及到继承父类的方法和属性。当我们在子类中重写一个父类方法时&#xff0c;有时我们需要在子类方法中访问父类方法&#xff0c;可以使用Python的内置函数super()来实现。 什么是父类方法 在面向对象编程中…

runway gen2

来自Runway文生成视频ai大模型Gen-2_哔哩哔哩_bilibili来自Runway文生成视频ai大模型Gen-2&#xff0c;距离视频制作自由又近了一步。, 视频播放量 1651、弹幕量 0、点赞数 21、投硬币枚数 2、收藏人数 42、转发人数 22, 视频作者 旭升说, 作者简介 一起聊下互联网的那些事&…

10大白帽黑客专用的 Linux 操作系统

平时在影视里见到的黑客都是一顿操作猛如虎&#xff0c;到底他们用的都是啥系统呢&#xff1f; 今天给大家分享十个白帽黑客专用的Linux操作系统。 ▍1. Kali Linux Kali Linux是最著名的Linux发行版&#xff0c;用于道德黑客和渗透测试。Kali Linux由Offensive Security开发&…

[k8s]Kubernetes简介

文章目录 Kubernetes介绍术语Label StatefulSet 存储类VolumePersistent Volume IP地址Node IPPod IPService Cluster IPExternal IP PodPod定义Pod生命周期与重启策略NodeSelector&#xff08;定向调度&#xff09;NodeAffinity&#xff08;亲和性调度&#xff09;PodAffinity…

164. 最大间距

题目描述&#xff1a; 主要思路&#xff1a; 利用桶排序的思路&#xff0c;取最大最小值的差值/个数&#xff0c;答案一定是大于等于这个数的&#xff0c;每个块为一个桶&#xff0c;维护这个桶内的最大最小值。 class Solution { public:int maximumGap(vector<int>&a…

【软件开发】Redis 理论篇(一)

Redis 理论篇&#xff08;一&#xff09; 一、概述 1.什么是 Redis&#xff1f; Redis 是一个使用 C 语言写成的&#xff0c;开源的高性能 Key-Value 非关系缓存数据库。它支持存储的 Value 类型相对更多&#xff0c;包括 string&#xff08;字符串&#xff09;、list&#x…

MyBatis基本操作及SpringBoot单元测试

目录 一、什么是单元测试&#xff1f; 1.1 单元测试的好处 1.2 单元测试的实现步骤 1.2.1 生成单元测试类&#xff1a; 1.2.2 SpringBootTest注解 1.2.3 检验方法结果&#xff1a; 二、利用MyBatis实现查询操作 2.1单表查询 2.2 参数占位符 #{} 和 ${} 2.2.1 ${} 字符…

全网最细,Selenium自动化测试项目实战技巧,从0到1精通自动化测试...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Selenium4自动化测…

重学Ajax

概述 Ajax&#xff08;Asynchronous JavaScript And XML&#xff09;即异步 JavaScript 和 XML&#xff0c;是一组用于在网页上进行异步数据交换的Web开发技术&#xff0c;可以在不刷新整个页面的情况下向服务器发起请求并获取数据&#xff0c;然后将数据插入到网页中的某个位置…

【Docker】Swarm学习

文章目录 什么是Docker Swarm定义与Docker Compose对比 基本结构图关键概念工作模式NodeService任务与调度服务副本与全局服务 Swarm的调度策略Swarm的特性批量创建服务强大的集群的容错性服务节点的可扩展性调度机制 集群部署基础架构准备工作创建Swarm并添加节点在Swarm中部署…