ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

servlet知识点大全总结

2022-01-06 22:02:39  阅读:148  来源: 互联网

标签:知识点 resp req public import servlet javax 大全


目录

四、 IDEA创建Web项目

4.1 IDEA创建Web项目

4.2 IDEA开发Servlet

使用开发工具编写Servlet,仍要手工导入servlet-api.jar文件,并与项目关联。
在这里插入图片描述

4.2.1 编写 Servlet

创建MyServlet,实现Servlet接口,覆盖5个方法

package com.hyqwsq.servlet;
import javax.servlet.*;
import java.io.IOException;

public class MyServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    // 提供服务
        System.out.println("My First Web Project");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

4.2.2 配fiweb.xml

<?xml version="1 .0" encoding=,,UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	 xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    	 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/]avaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd 
         version="3.1">

	<! --1 添加servlet节点-->
	<servlet>
		<servlet-name>MyServlet</servlet-name>
		<servlet-class>com.qf.servlet.MyServlet</servlet-class>
	</servlet>

	<!--2 添加 servlet-mapping 节点一>
	<servlet-mapping>
		<servlet-name>MyServlet</servlet-name>
		<url-pattern>/myservlet</url-pattern>
	</servlet-mapping>

</web-app>

4.2.3部署Web项目

  • 在Tomcat的webapps目录下,新建WebProject项目文件夹

    1. 创建WEB-INF,存放核心文件

    2. 在WEB-INF下,创建classes文件夹,将编译后的MyServlet.class文件复制至此。

  • 问题:每当我们编写了新的Servlet或者重新编译,都需要手工将新的.class部署到Tomcat中,较为麻烦。如何实现自动部署?

4.3 IDEA部署Web项目

前面我们是在Tomcat的webapps目录新建应用程序目录myweb,然后把静态资源和Servlet复制到相关目录下。使用IDEA不需要我们复制 了。可以通过IDEA集成Tomcat服务器,实现自动部署。

4.3.1 IDEA 集成 Tomcat

只是继承了tomcat,和项目还没有关系

4.3.2项目部署Tomcat

二次配置:

Apply–>OK

4.4其他操作

4.4.1关联第三方回包

在 WEB-INF 目录下新建lib目录

在这里插入图片描述

输入lib目录

在这里插入图片描述

复制 jar 包到 lib 目录中
在这里插入图片描述

右键lib目录,选择Add as Library集成

选择Project Library,完成。

  • Global Library表示所有工程都可以使用。

  • Project Library表示当前工程中所有模块都可以使用。

  • Module Library表示当前模块可以使用。
    在这里插入图片描述

4.4.2如何导出war包

项目完成后,有时候需要打成war方便部署。war包可以直接放入Tomcat的webapps目录中,启动Tomcat后自动解压,即可访问。

点击项目结构

九、Servlet生命周期

9.1生命周期四个阶段

9.1.1实例化

当用户第一次访问Servlet时,由容器调用Servlet的构造器创建具体的Servlet对象。也可以在容器启动之后立刻创建实例。使用如下代 码可以设置Servlet是否在服务器启动时就创建

•注意:只执行一次

9.1.2初始化

在初始化阶段,init()方法会被调用。这个方法ajavax.servlet.Servlet}g口中定义。其中,方法以一个ServletConfig类型的对象作为参 数

•注意:init方法只被执行一次

9.1.3服务

当客户端有一个请求时,容器就会将请求ServletRequest与响应ServletResponse对象转给Servlet,以参数的形式传给service方法

•此方法会执行多次

9.1.4 销毁

当Servlet容器停止或者重新启动都会引起销毁Servlet对象并调用destroy方法

• destroy方法执行一次

9.1.5 Servlet执行流程

在这里插入图片描述

package com.hyqwsq.Life;

import javax.servlet.ServletConfig;
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("/lifeservlet")
public class LifeServlet extends HttpServlet {

    public LifeServlet() {
        super();
        System.out.println("1.完成实例化");
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        System.out.println("2. 完成初始化");
    }

    //因为要不断接收请求,响应结果
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("3. 就绪中");
        //
        resp.getWriter().append("Served at: ").append(req.getContextPath());
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    public void destroy() {
        super.destroy();
        System.out.println("4.销毁了");
    }
}

十、Servlet特性

10.1线程安全问题

Servlet在访问之后,会执行实例化操作,仓腱一个Servlet对象。而我们Tomcat容器可以同时多个线程并发访问同一个Servlet,如果在 方法中对成员变量做修改操作,就会有线程安全的问题。

10.2如何保证线程安全

  • synchronized

    • 将存在线程安全问题的代码放到同步代码块中
  • 实现 SingleThreadModel 接口

    • servlet实现SingleThreadModel接口后,每个线程都会创建servlet实例,这样每个客户端请求就不存在共享资源的问题,但是 servlet响应客户端请求的效率太低所以已经淘汰。
  • 尽可能使用局部变量

package com.hyqwsq.servletSafe;

import com.hyqwsq.servlet1.HttpServlet;

import javax.servlet.ServletException;
import javax.servlet.SingleThreadModel;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class SafeServlet extends HttpServlet implements SingleThreadModel {
    /**
     * 不安全代码:
     * 当A,B需要调用这个servlet,A执行的时候出发了servlet的实例化对象,
     * 创建了一个servlet,然后持有一个空的字符串message,然后A发送get请求,输入用户名和密码
     * A得到登录失败的结果,就在这是,A的线程时间片没了,A线程就会停留在 message = “登录失败” 这行的结果上
     * 这时候B线程进来,又将message初始化为空,接着也发送get请求登录,并且登录成功,得到登录成功的结果,完成message的赋值和客户端的响应
     * 等A线程醒来,发现message被改为了登录成功,并且响应了登录成功回去,但是没办法做下一步的操作
     * 结果就是在一个请求的方法里做了两次对成员变量的修改操作,就会导致数据不准确
     */
    private String message = "";
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String message = "";
        // 假设:
        //      1: 接收参数
        //      2. 调用业务逻辑 得到登录结果
        message = "登录成功";//或者登录失败
        PrintWriter printWriter = resp.getWriter();
        printWriter.println(message);

    }

    /**
     * 方法一:
     *      synchronized锁
     * 缺点:
     *      在多线程并发访问的情况下,效率极低,因为同一时间只能处理一个线程的登录
     */
    private String message = "";
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        synchronized(this){
            message = "登录成功";//或者登录失败
            PrintWriter printWriter = resp.getWriter();
            printWriter.println(message);

        }
    }

    /**
     * 方法三:
     *      创建局部变量,任何线程拿到的都是局部变量,不互相影响
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建局部变量
        String message = "";
        message = "登录成功";//或者登录失败
        PrintWriter printWriter = resp.getWriter();
        printWriter.println(message);
    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}


十一、状态管理

11.1 现有问题

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

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

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

11.2 概念

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

11.3 状态管理分类

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

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

十二、Cookie的使用

12.1 什么是 Cookie

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

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

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

在这里插入图片描述

12.2 创建 Cookie

package com.hyqwsq.Cookies;

import com.hyqwsq.servlet1.HttpServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/cs")
public class CookieServlet extends HttpServlet {
    @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 {
        // 1. 服务器创建Cookie对象
        Cookie cookie = new Cookie("username","gavin");

        // 1.1 设置Cookie的访问路径
        //cookie.setPath("//Servlet_code_demo1_war_exploded");    // 如果是项目名称,代表该项目下所有资源都可以使用这个cookie
        cookie.setPath("//Servlet_code_demo1_war_exploded/get");    //只有该项目里的get或者get下面的资源才可以访问

        // 1.2 设置Cookie的有效期
        cookie.setMaxAge(60*60);

        // 2. 将Cookie响应给客户端
        resp.addCookie(cookie); // 添加一个cookie到resp对象里,并响应给客户端
    }
}

查看创建的cookie

在这里插入图片描述

12.3 获取Cookie

只需要保证 Cookie 的 key 和 路径(Path) 一致即可修改

package com.hyqwsq.Cookies;

import com.hyqwsq.servlet1.HttpServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/get")
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 通过request对象获取所有的cookie
        Cookie[] cookies = req.getCookies();

        /**
         * 若是客户端没有cookie,则会获取一个空数组
         * 所以要加上判空,避免空指针异常
         */
        if(cookies != null){
            // 2. 因为得到的是cookie数组,不知道有几个cookie
            //      所以通过循环遍历cookie
            for(Cookie cookie : cookies){
                System.out.println(cookie.getName()+":"+cookie.getValue()+"路径:" +cookie .getPath());
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

在这里插入图片描述

  • 注意:如果改变cookie的name和有效路径会新建cookie,而改变cookie值、有效期会覆盖原有cookie

12.4 修改 Cookie

package com.hyqwsq.Cookies;

import com.hyqwsq.servlet1.HttpServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/csc")
public class ChangeCookie extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 修改cookie需要key和路径同时一致
        Cookie cookie = new Cookie("username","mark");
        cookie.setPath("/Servlet_code_demo1_war_exploded/get");

        cookie.setMaxAge(60*24*7);

        resp.addCookie(cookie);
    }
}

当访问cs后通过访问getServlet得到 username = ‘gavin’的cookie,这时候访问csc修改key为username 且Path为/Servlet_code_demo1_war_exploded/get的cookie,最后通过访问get来打印结果:

在这里插入图片描述

12.5 Cookie编码与解码

Cookie默认不支持中文,只能包含ASCII字符,所以Cookie需要对Unicode字符进行编码,否则会出现乱码

  • 编码可以使用java.net.URLEncoder类的encode(String str,String encoding) 方法
  • 解码使用java.net.URLEncoder类的decode(String str,String encoding)方法

12.5.1创建带中文Cookie

package com.hyqwsq.URLEncoder;

import com.hyqwsq.servlet1.HttpServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/cs3")
public class URLEncoderServlet extends HttpServlet {
    @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 = new Cookie("姓名","张三");

        cookie.setPath("/Servlet_code_demo1_war_exploded/get");

        cookie.setMaxAge(600);

        resp.addCookie(cookie);

    }
}

在这里插入图片描述

package com.hyqwsq.Cookies;

import com.hyqwsq.servlet1.HttpServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

@WebServlet("/cs3")
public class URLEncoderServlet extends HttpServlet {
    @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 = new Cookie(
                URLEncoder.encode("姓名","UTF-8"),
                URLEncoder.encode("何义竏","UTF-8")
        );

        cookie.setPath("/Servlet_code_demo1_war_exploded/get");

        cookie.setMaxAge(600);

        resp.addCookie(cookie);

    }
}

12.5.2读取带中文Cookie

package com.hyqwsq.Cookies;

import com.hyqwsq.servlet1.HttpServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;

@WebServlet("/get")
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 通过request对象获取所有的cookie
        Cookie[] cookies = req.getCookies();

        /**
         * 若是客户端没有cookie,则会获取一个空数组
         * 所以要加上判空,避免空指针异常
         */
        if(cookies != null){
            // 2. 因为得到的是cookie数组,不知道有几个cookie
            //      所以通过循环遍历cookie
            for(Cookie cookie : cookies){
                System.out.println(
                        URLDecoder.decode(cookie.getName(),"UTF-8")+
                        ":"+URLDecoder.decode(cookie.getValue(),"UTF-8")+
                        "  路径:" +cookie.getPath()
                );
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

在这里插入图片描述

12.6 Cookie优点和缺点

12.6.1 优点

  • 可配置到期规则
  • 简单性:Cookie是一种基于文本的轻量结构,包含简单的键值对
  • 数据持久性:Cookie默认在过期之前是可以一直存在客户端浏览器上的

12.6.2 缺点

  • 大小受到限制:大多数浏览器对Cookie的大小有4K、8K字节的限制。
  • 用户配置为禁用:有些用户禁用了浏览器或客户端设备接收Cookie的能力,因此限制了这一功能
  • 潜在的安全风险:Cookie可能会被篡改。会对安全性造成潜在风险或者导致依赖于Cookie的应用程序失败

十三、Session对象

13.1 Session 概述

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

13.2 Session原理

  • 服务器会为每一次会话分配一个Session对象
  • 同一个浏览器发起的多次请求,同属于一次会话(Session)(两台电脑打开两个浏览器那就是两个会话)
  • 首次使用Session时,服务器会自动创建Session,并创建Cookie存储Session的 id 发送回给客户端

注意:Session 是由服务器创建的

13.3 Session使用

13.3.1 获取 Session

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

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

package com.hyqwsq.sessions;

import com.hyqwsq.servlet1.HttpServlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/ss")
public class SessionServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 因为Seesion是自动创建的,所以通过request对象获取Seesion对象
        HttpSession session = req.getSession();
        //2. Session是借助cookie发送到客户端
        System.out.println("ID= "+session.getId());
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

访问结果:(在同一次会话中,session都是同一个)

在这里插入图片描述

session是借助cookie发送给客户端:

在这里插入图片描述

浏览器在没有关闭的情况下,当我们再一次访问的时候,响应头没有了set-cookie,反而是出现在了请求的时候发送给服务器的请求标头里:

在这里插入图片描述

13.3.2 Session保存数据

  • setAttribute(属性名,Object):保存数据到session中
package com.hyqwsq.sessions;

import ...

@WebServlet("/ss")
public class SessionServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 因为Seesion是自动创建的,所以通过request对象获取Seesion对象
        HttpSession session = req.getSession();
        //2. Session是借助cookie发送到客户端
        System.out.println("ID= "+session.getId());

        //2. 使用session保存数据
        session.setAttribute("username","gavin");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

13.3.3 Session获取数据

  • getAttribute(属性名):获取session中的数据
package com.hyqwsq.sessions;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/getValue")
public class GetValueServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.通过request获取session对象
        HttpSession session = req.getSession();

        String s = (String)session.getAttribute("username");

        System.out.println("从session中获取了:"+s);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

在这里插入图片描述

13.3.4 Session移除数据

  • removeAttribute(属性名):从session中删除数据
package com.hyqwsq.sessions;

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 javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/remove")
public class RemoveServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("username");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

在这里插入图片描述

13.4 Session 与 Request 应用区别

13.4.1 Session 应用

package com.hyqwsq.sessions;

import ...

@WebServlet("/ss")
public class SessionServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 因为Seesion是自动创建的,所以通过request对象获取Seesion对象
        HttpSession session = req.getSession();
        //2. Session是借助cookie发送到客户端
        System.out.println("ID= "+session.getId());

        //3. 使用session保存数据
        session.setAttribute("username","gavin");
        //4. 使用request保存数据
        req.setAttribute("password","123456");

        //重定向,二次跳转
        resp.sendRedirect("/Servlet_code_demo1_war_exploded/getValue");

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

13.4.2 GetValueServlet.java

package com.hyqwsq.sessions;

import ...

@WebServlet("/getValue")
public class GetValueServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.通过request获取session对象
        HttpSession session = req.getSession();

        String s = (String)session.getAttribute("username");
        String password = (String)req.getAttribute("password");

        System.out.println("从session中获取了:"+s);
        System.out.println("从request中获得了:"+password);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

访问结果:

请添加图片描述

13.5 Session的生命周期

  • 开始:第一次使用到Session的请求产生,则创建Session
  • 结束:
    • 浏览器关闭,则失效
    • Session超时,则失效
      1. session.setMaxinactiveInerval(seconds); //设置最大有效时间(单位:秒)
    • 手工销毁,则失效
      1. session.invalidate(); //登录退出、注销

13.5.1 Session 最大时长

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();

        //设置session有效期
        session.setMaxInactiveInterval(20);

        System.out.println("sessionID: "+session.getId());
    }

13.5.2 Session 失效

public class SessionLifeGetServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();

        System.out.println("sessionID: "+session.getId());

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

13.6 浏览器禁用Cookie解决方案

13.6.1 浏览器禁用Cookie的后果

服务器在默认情况下,会使用Cookie的方式将sessionID发送给浏览器,如果用户禁止Cookie,则sessionID不会被浏览器保存,此时,服务器可以使用像URL重写这样的方式来发送sessionID

13.6.2 URL重写

浏览器在访问服务器上的某个地址时,不再使用原来的那个地址,而是使用经过改写的地址(即在原来的地址后面z加上了sessionID)

13.6.3 实现URL重写

resp.encodeRedirectURL(String url) 生成重写的URL

HttpSession = req.getSession();
//重写URL追加SessionID
String newUrl = response.encodeRedirectURL("/Servlet_code_demo1_war_exploded/cs");
System.out.println(newUrl2);

resp.sendRedirect(newUrl2);

13.7 Session管理员实战权限验证

在这里插入图片描述

13.7.1 创建管理员表

create table manager(
	username varchar(20) primary key,
	password varchar(20) not null
)charset = utf8;
insert into manager(username,password) values('tom','123');

13.7.2 登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>管理员登录</title>
</head>
<body>
    <form action="/Servlet_code_demo1_war_exploded/loginMgr" method="post">
        用户名:<input type="text" name="username"/></br>
        密码:<input type="password" name="password"/></br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

13.7.3 Dao层

13.7.3.1 Dao层接口

AdminDao:

package com.hyqwsq.servletSessionProject.Dao;

import com.hyqwsq.servletSessionProject.entity.Admin;

import java.util.List;

public interface AdminDao {
    public List<Admin> selectAll();
}

ManagerDao:

package com.hyqwsq.servletSessionProject.Dao;

import com.hyqwsq.servletSessionProject.entity.Manager;

public interface ManagerDao {
    // 权限登录验证,返回一个Manager
    public Manager select(String username);
}

13.7.3.2 Dao层Impl实现类

AdminDaoImpl:

package com.hyqwsq.servletSessionProject.Dao.impl;

import com.hyqwsq.servletSessionProject.Dao.AdminDao;
import com.hyqwsq.servletSessionProject.entity.Admin;
import com.hyqwsq.servletSessionProject.utils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.SQLException;
import java.util.List;

public class AdminDaoImpl implements AdminDao {
    private QueryRunner queryRunner = new QueryRunner();
    @Override
    public List<Admin> selectAll() {
        List<Admin> admins = null;
        try {
            admins = queryRunner.query(
                    DbUtils.getConnection(),
                    "select * from admin",
                    new BeanListHandler<Admin>(Admin.class)
            );
            return admins;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        return null;
    }
}

ManagerDaoImpl:

package com.hyqwsq.servletSessionProject.Dao.impl;

import com.hyqwsq.servletSessionProject.Dao.ManagerDao;
import com.hyqwsq.servletSessionProject.entity.Manager;
import com.hyqwsq.servletSessionProject.utils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.SQLException;

public class ManagerDaoImpl implements ManagerDao {
    private QueryRunner queryRunner = new QueryRunner();

    @Override
    public Manager select(String username) {
        try {
            Manager manager = queryRunner.query(
                    DbUtils.getConnection(),
                    "select * from manager where username = ?",
                    new BeanHandler<Manager>(Manager.class),//封装成实体类对象
                    username);//参数
            return manager;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        return null;
    }
}

13.7.4 entity实体类

Admin:

package com.hyqwsq.servletSessionProject.entity;

public class Admin {
    private String username;
    private String password;
    private String phone;
    private String address;

    public Admin(String username, String password, String phone, String address) {
        this.username = username;
        this.password = password;
        this.phone = phone;
        this.address = address;
    }

    public Admin() {
    }

    @Override
    public String toString() {
        return "Admin{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", phone='" + phone + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

Manager:

package com.hyqwsq.servletSessionProject.entity;

public class Manager {
    private String username;
    private String password;

    public Manager() {
    }

    @Override
    public String toString() {
        return "manager{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public Manager(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

13.7.5 service业务方法实现类

13.7.5.1 service接口

AdminService:

package com.hyqwsq.servletSessionProject.service;

import com.hyqwsq.servletSessionProject.entity.Admin;

import java.util.List;

public interface AdminService {
    public List<Admin> showAllAdmin();
}

ManagerService:

package com.hyqwsq.servletSessionProject.service;

import com.hyqwsq.servletSessionProject.entity.Manager;

public interface ManagerService {
    public Manager login(String username, String password);
}

13.7.5.2 serviceImpl实现类

AdminServiceImpl:

package com.hyqwsq.servletSessionProject.service.impl;

import com.hyqwsq.servletSessionProject.Dao.AdminDao;
import com.hyqwsq.servletSessionProject.Dao.impl.AdminDaoImpl;
import com.hyqwsq.servletSessionProject.entity.Admin;
import com.hyqwsq.servletSessionProject.service.AdminService;
import com.hyqwsq.servletSessionProject.utils.DbUtils;

import java.util.List;

public class AdminServiceImpl implements AdminService {
    private AdminDao adminDao = new AdminDaoImpl();

    @Override
    public List<Admin> showAllAdmin() {
        List<Admin> admins = null;
        try {
            DbUtils.begin();
            admins =adminDao.selectAll();
            DbUtils.commit();
        } catch (Exception e) {
            DbUtils.rollback();
            e.printStackTrace();
        }
        return admins;
    }
}

ManagerServiceImpl:

package com.hyqwsq.servletSessionProject.service.impl;

import com.hyqwsq.servletSessionProject.Dao.ManagerDao;
import com.hyqwsq.servletSessionProject.Dao.impl.ManagerDaoImpl;
import com.hyqwsq.servletSessionProject.entity.Manager;
import com.hyqwsq.servletSessionProject.service.ManagerService;
import com.hyqwsq.servletSessionProject.utils.DbUtils;

public class ManagerServiceImpl implements ManagerService {
    private ManagerDao managerDao = new ManagerDaoImpl();
    @Override
    public Manager login(String username, String password) {
        Manager manager = new Manager();
        try {
            manager = null;
            DbUtils.begin();
            Manager temp = managerDao.select(username);
            if(temp != null){
                if(temp.getPassword().equals(password)){
                    manager = temp;
                }
            }
            DbUtils.commit();
        } catch (Exception e) {
            DbUtils.rollback();
            e.printStackTrace();
        }
        return manager;
    }
}

13.7.6 servlet

13.7.6.1 Controller

LoginMgrController:

package com.hyqwsq.servletSessionProject.servlet.controller;

import com.hyqwsq.servletSessionProject.entity.Manager;
import com.hyqwsq.servletSessionProject.service.ManagerService;
import com.hyqwsq.servletSessionProject.service.impl.ManagerServiceImpl;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 业务内容:
 *      访问查询所用用户信息的servlet需要验证是否登录
 */
@WebServlet("/loginMgr")
public class LoginMgrController extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 处理乱码
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");
        // 2. 收参
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 3. 调用业务逻辑方法
        ManagerService managerService = new ManagerServiceImpl();
        Manager mgr = managerService.login(username,password);
        // 4. 处理结果,流程跳转
        if(mgr!=null){
            //登录成功
            //将管理员信息存储在Session里
            HttpSession session = req.getSession();
            session.setAttribute("mgr",mgr);
            session.setMaxInactiveInterval(60*60);
            //跳转 目标,方式
            resp.sendRedirect("/Servlet_code_demo1_war_exploded/showallcontroller");
        }else{
            // mgr = null,表示登录失败,跳转会登录界面
            resp.sendRedirect("/Servlet_code_demo1_war_exploded/loginMgr.html");
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

ShowAllAdminController:

package com.hyqwsq.servletSessionProject.servlet.controller;

import com.hyqwsq.servletSessionProject.entity.Admin;
import com.hyqwsq.servletSessionProject.entity.Manager;
import com.hyqwsq.servletSessionProject.service.AdminService;
import com.hyqwsq.servletSessionProject.service.impl.AdminServiceImpl;

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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;

@WebServlet("/showallcontroller")
public class ShowAllAdminController extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        Manager manager = (Manager) session.getAttribute("mgr");
        if(manager!=null){
            AdminService adminService = new AdminServiceImpl();

            List<Admin> adminList = adminService.showAllAdmin();

            req.setAttribute("admins",adminList);

            req.getRequestDispatcher("/showalljsp").forward(req,resp);
        }else{
            resp.sendRedirect("/Servlet_code_demo1_war_exploded/loginMgr.html");
        }

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

13.7.6.2 JSP

ShowAllAdminJSP:

package com.hyqwsq.servletSessionProject.servlet.jsp;

import com.hyqwsq.servletSessionProject.entity.Admin;

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;
import java.util.List;

@WebServlet("/showalljsp")
public class ShowAllAdminJSP extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");

        List<Admin> adminList = (List)req.getAttribute("admins");

        // 2.通过流打印结果显示
        PrintWriter printWriter = resp.getWriter();
        if(adminList != null){
            printWriter.println("<html>");
            printWriter.println(    "<head>");
            printWriter.println(        "<meta charset = 'UTF-8'>");
            printWriter.println(        "<title>显示所有</title>");
            printWriter.println(    "</head>");

            printWriter.println(    "<body>");
            printWriter.println(        "<table border = '1'>");
            printWriter.println(            "<tr>");
            printWriter.println(                "<td>username</td>");
            printWriter.println(                "<td>password</td>");
            printWriter.println(                "<td>phone</td>");
            printWriter.println(                "<td>address</td>");
            printWriter.println(            "</tr>");

            for(Admin admin : adminList){
                printWriter.println(            "<tr>");
                printWriter.println(                "<td>"+admin.getUsername()+"</td>");
                printWriter.println(                "<td>"+admin.getPassword()+"</td>");
                printWriter.println(                "<td>"+admin.getPhone()+"</td>");
                printWriter.println(                "<td>"+admin.getAddress()+"</td>");
                printWriter.println(            "</tr>");

            }
            printWriter.println(        "</table>");
            printWriter.println(    "</body>");
            printWriter.println("</html>");

        }else{
            printWriter.println("<html>");
            printWriter.println(    "<head>");
            printWriter.println(        "<meta charset = 'UTF-8'>");
            printWriter.println(        "<title>显示所有</title>");
            printWriter.println(    "</head>");

            printWriter.println(    "<body>");
            printWriter.println(        "<h3>当前没有数据</h3>");
            printWriter.println(    "</body>");
            printWriter.println("</html>");

        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

}

十四、ServletContetxt对象

14.1 ServletContext概括

  • 全局对象,也拥有作用域,对应一个Tomcat中的Web应用
  • 当web服务器启动时,会为每一个web应用程序创建一块共享的存储区域(ServletContext)
  • ServletContext在web服务器启动时创建,服务器关闭时销毁

14.2 获取ServletContext对象

  • GenericServlet提供了getServletContext()方法,this.getServletContext()更好
  • HttpServletRequest提供了getServletContext()方法
  • HttpServlet提供了getServletContext()方法

14.3 ServletContext作用

14.3.1 获取项目真实路径

获取当前项目在服务器发布的真实路径

String realpath = servletContext.getRealPath("/");

14.3.2 获取项目上下文路径

获取当前项目上下文路径(应用程序名)

System.out.println(servletContext.getContextPath());    //上下文路径(应用程序名称)
System.out.println(request.getContextPath());

14.3.3 全局容器

ServletContext拥有作用域,可以存储数据到全局容器中

  • 存储数据:servletContext.setAttribute(“name”,value);
  • 获取数据:servletContext.getAttribute(“name”);
  • 移除数据:setvletContext.removeAttribute(“name”);

14.4 ServletContext特点

  • 唯一性:一个应用对应一个ServletContext
  • 生命周期:只要容器不关闭或者应用不卸载,ServletContext就一直存在

14.5 ServletContext应用场景

ServletContext统计当前项目访问次数

package com.hyqwsq.Context;

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 javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;

@WebServlet("/cc")
public class CounterController extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 获取ServletContext对象
        ServletContext servletContext = req.getServletContext();

        // 2. 获取计数器
        Integer counter = (Integer)servletContext.getAttribute("counter");

        if(counter == null){
            counter = 1;
            servletContext.setAttribute("counter",counter);
        }else{
            Random random = new Random();
            counter += random.nextInt(100);
            servletContext.setAttribute("counter",counter);
        }

        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset = utf-8");

        PrintWriter printWriter = resp.getWriter();
        printWriter.println("网站共访问次数:" + counter);
        System.out.println("counter: " + counter);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

package com.hyqwsq.Context;

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;
import java.io.PrintWriter;

@WebServlet("/showcc")
public class ShowCounterController extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 获取servletContext对象
        ServletContext servletContext = req.getServletContext();

        //2. 获取计数器
        Integer counter = (Integer) servletContext.getAttribute("counter");

        if(counter == null){
            counter = 1;
            servletContext.setAttribute("counter",counter);
        }else{
            counter++;
            servletContext.setAttribute("counter",counter);
        }
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset = utf-8");

        PrintWriter printWriter = resp.getWriter();
        printWriter.println("网站共访问次数:" + counter);
        System.out.println("showcounter: " + counter);



    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

14.6 总结

  • HttpServletRequest:一次请求,请求响应之前有效
  • HttpSession:一次会话开始,浏览器不关闭或者不超时之前有效
  • ServletContext:服务器启动开始,服务器停止之前有效

十五、过滤器

15.1 现有代码问题

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

15.2 概念

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

在这里插入图片描述

15.3 过滤器作用

  • 执行地位在Servlet之前,客户端发送请求时,会先经过Filter,再到达目标Servlet中;响应时,会根据执行流程再次反向执行Filter
  • 可以解决多个Servlet共性代码的冗余问题(例如:乱码处理,登录验证)

15.4 编写过滤器

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

15.4.1 实现过程

  • 编写Java类实现Filter接口
  • 在doFilter方法中编写拦截逻辑
  • 设置拦截路径
package com.qf.web.filter;

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

@WebFilter("/myservlet1") //过滤路径
public class MyFilter1 implements Filter{
    
    // 初始化过滤器
    @Override
    public void init(FilterConfig filterConfig) throws ServletException{
        System.out.println("过滤器初始化了......init..."+filterConfig);
    }
    
    // 执行过滤
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException{
        System.out.println("过滤前....doFilter");
        // 放行
        chain.doFilter(request,response);
        
        System.out.println("过滤器....doFilter");
    }
    
    // 销毁
    @Override
    public void destroy(){
        System.out.println("销毁了......destory");
    }
}

15.5 过滤器配置

15.5.1 注解配置

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

15.5.2 xml配置

我们每个碎片最终能拼成一张照片

标签:知识点,resp,req,public,import,servlet,javax,大全
来源: https://blog.csdn.net/weixin_44766232/article/details/122353587

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有