当前位置:首页>笔记分享>Java笔记>JavaWeb>JavaWeb

JavaWeb

1、基本概念

1.1、前言

web开发是什么:

  • web,网页的意思
  • 静态web
    • html,css
    • 提供给所有人看到数据,始终不会发生变化
  • 动态web
    • 淘宝、京东等,几乎所有的大型网站都是
    • 提供给所有人看的数据始终会发生变化,每个人在不同的时间,不同的地点看到的信息各不相同
    • 技术栈:Service/JSP,ASP,PHP

在Java中,动态web资源开发的技术统称为JavaWeb;

1.2、web应用程序

web应用程序:可以提供浏览器访问的程序;

  • a.html、b.html……多个web资源,这些web资源可以被外界访问,对外界提供服务;
  • 我们能访问到的任何一个页面或者资源,都存在于这个世界上的某个角落的的计算机上;
  • 这个统一的web资源会被放在同一个文件夹下,web应用程序—->Tomcat:服务器;
  • 一个web应用由多部分组成 (静态web,动态web)
    • html,css,js
    • jsp,servlet
    • Java程序
    • jar包
    • 配置文件(Properties)

web应用程序编写完后,若想提供给外界访问:需要一个服务器来统一管理;

1.3、静态web

  • .htm, .html, 这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接读取;
  • 静态web存在的缺点
    • Web页面无法动态的更新,所有用户看到都是一个页面
    • 轮播图,点击特效:伪动态
    • JavaScript (常用在实际开发中)
    • VBScript
    • 它无法和数据库交互(数据无法持久化,用户无法交互)

1.4、动态web

页面会动态展示:“Web页面展示的效果因人而异”

缺点:

  • 加入服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序

    • 停机维护

优点:

  • Web页面可以动态的更新,所有用户看到都是一个页面
  • 它可以和数据库交互

2、web服务器

2.1、技术讲解

  • ASP:

    • 微软:国内最早流行的就是ASP;

    • 在HTML 中嵌入VB的脚本,ASP + COM;

    • 在ASP开发中,基本一个页面都有几千行的业务代码,页面极其混乱(下面是实例)

    • 维护成本高

    • C#语言

    • IIS微软的

<h1>
    <h2>
        <h3>
            <h4>
            </h4>
            <h5>
                <%
                System.out.println("hello");   
                %>
            </h5>
        </h3>
    </h2>
</h1>
  • php

    • PHP开发速度很快,功能很强大,跨平台,代码很简单

    • 无法承载大访问量(局限性)

  • JSP/Servlet:

    • sun公司主推的B/S架构;

    • 基于Java语言;

    • 可以承载三高问题带来的影响;

    • 语法像ASP,ASP—->JSP,加强市场强度;

B/S:浏览器和服务器

C/S:客户端和服务器

2.2、web服务器

服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息;

  • IIS

    • 微软的:ASP……,Windows中自带的
  • Tomcat

Tomcat

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学JavaWeb者来说,它是最佳的选择。

Tomcat 实际上运行JSP 页面和Servlet。目前Tomcat最新版本为10.0.5

工作3-5年之后,可以尝试手写Tomcat服务器;

下载Tomcat:

  1. 安装 or 解压
  2. 了解配置文件及目录结构
  3. 这个东西的作用

3、Tomcat

3.1、安装Tomcat

下载地址:https://tomcat.apache.org

Apache Tomcat
安装包

下载后直接解压就好

3.2、Tomcat启动

文件夹作用:文件夹作用

启动/关闭:启停

也可以直接点击右上角关闭:关闭

访问测试:http://localhost:8080

进入tomcat表示成功

3.3、配置

配置

可以配置启动的端口号

  • Tomcat的默认端口号是8080
  • MySQL:3306
  • http:80
  • https:443
<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

可以配置主机的名称

  • 默认主机名为:localhost
  • 默认网站应用存放位置为:webapps
<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

核心配置文件中

高难度面试题:

请你谈谈网站是如何进行访问的?

  1. 输入另一个域名,回车
  2. 检查本机的 host 配置文件内是否有这个域名的映射;
    1. 有:直接返回对应的IP地址,这个地址中,有我们需要访问的web程序,可以直接访问
    2. 没有:去DNS服务器找,找到的话就返回,找不到就返回找不到

3.4、发布一个web网站

  • 将写好的网站文件放到服务器 (Tomcat) 中指定的web应用的文件夹 (webapps) 下,就可以访问了

网站应该有的结构

--webapps : Tomcat服务器的web目录
    -ROOT
    -xiaopeng: 网站的目录名
        -classes : java程序
        -lib : web应用所依赖的jar包
        -web.xml : 网站配置文件
        -index.html 默认的首页
        - static
            - css
                - style.css
            - js
            - img4
        - ……

4、Http

4.1、什么是http

HTTP(超文本传输协议/Hyper Text Transfer Protocol)是一个简单的请求-响应协议,它通常运行在TCP之上。

http:

  • 文本:html,字符串,~……
  • 超文本:图片,音乐,视频,定位,地图……
  • 端口80

https:安全的

  • 端口443

4.2、两个时代

  • http1.0
    • HTTP/1.0:客户端可以与web服务器连接后,只能获取一个web资源,然后就断开连接了。
  • http2.0
    • HTTP/2.0:客户端可以与web服务器连接,可以获得多个web资源。

4.3、Http请求

  • 客户端—-发请求—-服务器

百度:

Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK
Remote Address: 163.177.151.110:443
Accept: text/html, 
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive

4.3.1、请求行

  • 请求行中的请求方式:GET

  • 请求方式:

    GET,POST,HEAD,DELETE,PUT,TRACT等等

    • get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
  • post:请求能够携带的参数没有限制,没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效

4.3.2、消息头

消息头内容

Accept: 告诉浏览器,它所支持的数据类型
Accept-Encoding: 支持哪种编码格式    GBK    UTF-8    GB2312    ISO8859-1
Accept-Language: 告诉浏览器,它的语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器,请求完成是断开连接还是保持连接
Host: 主机....../.

4.4、Http响应

  • 服务器—-客户端

百度为例:

Cache-Control: private                    缓存控制
Connection: keep-alive                    连接
Content-Encoding: gzip                    编码
Content-Type: text/html;charset=utf-8    类型

4.4.1、响应体

Accept: 告诉浏览器,它所支持的数据类型
Accept-Encoding: 支持哪种编码格式    GBK    UTF-8    GB2312    ISO8859-1
Accept-Language: 告诉浏览器,它的语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器,请求完成是断开连接还是保持连接
Host: 主机....../.
Refrush: 告诉客户端,多久刷新一次

4.4.2、响应状态码

200:请求响应成功

3xx:请求重定向

  • 重定向:你重新到我给你的新位置去;

4xx:找不到资源 404

  • 资源不存在;

5xx:服务器代码错误 500 502:网关错误

常见面试题:

当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么

5、Maven

为什么学习这个技术

  1. 在JavaWeb开发中需要使用大量的的jar包,我们手动导入;

  2. 如何能够让一个东西自动帮我导入和配置这个jar包;

    由此,Maven诞生了

5.1、Maven架构管理工具

我们目前用来就是方便导入jar包的

Maven的核心思想:约定大于配置

  • 有约束,不要去违反。Maven会规定好你该如何去编写我们的Java代码,必须要按照这个规则来;

5.2、下载安装Maven

官网:https://maven.apache.org

Maven

下载完成后,解压即可;

5.3、配置环境变量

  • M2_HOME maven目录下的bin目录
  • MAVEN_HOME maven的目录
  • 在系统的 path 中配置 %MAVEN_HOME%\bin

maven版本

5.4、阿里云镜像

  • 镜像:mirrors
    • 作用:加速我们的下载
  • 国内建议使用阿里云的镜像
<!--在maven中的conf的setting.xml中设置-->
<mirror>
  <id>aliyunmaven</id>
  <mirrorOf>central</mirrorOf>
  <name>aliyun maven</name>
  <url>https://maven.aliyun.com/repository/public/</url>
</mirror>

5.5、本地仓库

本地仓库是在本机仓库,对立远程仓库;

建立一个本地仓库:

<!--在maven中的conf的setting.xml中设置-->
<localRepository>E:\environment\apache-maven-3.8.1\maven-repo</localRepository>

5.6、在IDEA中使用Maven

  1. 启动idea
  2. 创建一个MavenWeb项目

创建项目

创建项目步骤

创建项目步骤

  1. IDEA项目创建成功后

创建后注意

5.7、创建一个普通的Maven项目

普通Maven项目

目录结构说明

5.8、标记文件夹功能(IDEA特有)

标记功能

查看目录结构

5.9、在IDEA中配置tomcat

配置Tomcat

tomcat配置2

5.10、pom文件

pom.xml是Maven的核心配置文件

  • Maven由于它的约定大于配置,我们之后可以能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:
<!-- 在build中配置resources,我们之后可以能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案: -->
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>**/*.properties</exclude>
                <exclude>**/*.xml</exclude>
            </excludes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

5.11、IDEA操作

idea包依赖树

依赖树

5.12、解决遇到的问题

  1. Maven 3.6.2

    解决方法:降级为3.6.1

  2. Tomcat 闪退

  3. IDEA 中每次都要重复配置Maven在IDEA中的全局默认配置中去配置

问题

  1. Maven项目中Tomcat无法配置

问题2

tomact选对

6、Servlet

6.1、Servlet简介

  • Servlet是Sun公司开发动态web的一门技术
  • Sun在这些API中提供了一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要两个小步骤
    • 编写一个类实现Servlet接口
    • 把开发好的Java类部署到web服务器中

把实现了Servlet接口的Java程序叫做,Servlet

6.2、HelloServlet

Servlet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet

  1. 构建一个普通的Maven项目,删掉里面的src目录,以后就在这个项目里面建立Moudel;这个空的工程就是Maven主工程;

  2. 关于Maven父子工程的理解;

    父项目中会有

    
       servlet-01
    

    子项目中会有

    
     javaweb-02-servlet
     com.xiaopeng
     1.0-SNAPSHOT
    

    父项目中的jar包,子项目可以直接使用

  3. Maven环境优化

    1. 修改web.xml为最新的
    2. 将Maven的结构搭建完整
  4. 编写一个Servlet程序

    1. 编写一个普通类

    2. 实现Servlet接口,这里我们直接继承HTTPServlet,GenericServlet

      Tomcat 9以下版本的javax.servlet和Tomcat 10不兼容,Tomcat 10要用jaraka.servlet

      @WebServlet(name = "Servlet", value = "/Servlet")
      public class Servlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
            PrintWriter writer = res.getWriter(); // 响应流
            writer.print("hello, servlet");
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
            doGet(req, res); //doget和dopost原则上一样只用实现一个 然后调用就可以
        }
      }
  5. 编写Servlet的映射

    为什么需要映射:我们写的Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所有我们需要在web服务中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径;

    
    
       hello
       com.xiaopeng.servlet.Servlet
    
    
    
       hello
       /hello
    
    
  6. 配置Tomcat

    注意:配置项目发布的路径就可以了

  7. 启动

启动

6.3、Servlet原理

Servlet是由Web服务器调用,Web服务器在收到浏览器请求
Servlet原理

6.4、Mapping问题

  1. 一个Servlet可以指定一个映射路径

    
       hello
       /hello
    
  2. 一个Servlet可以指定多个映射路径

    
       hello
       /hello
    
    
       hello
       /hello2
    
    
       hello
       /hello3
    
    
       hello
       /hello4
    
  3. 一个Servlet可以指定通用映射路径

    
       hello
       /hello/*
      
    
  4. 默认请求路径

    
    
       hello
       /*
    
  5. 指定一个后缀或者前缀等等……

    
    
       hello
       *.suibian
    
  6. 优先级问题

    指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;

    
    
       error
       com.xiaopeng.servlet.ErrorServlet
    
    
       error
       /*
    

6.5、ServletContext

Web容器在启动的时候,它会为每一个Web程序都创建一个对应的ServletContext对象,它代表了当前的Web应用;

6.5.1、共享数据

我在这个Servlet中保存的数据,可以在另外一个Servlet中拿到;

//放置数据的类
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // this.getInitParameter()
        // this.getServletConfig()
        // this.getServletContext()
        // this.getServletName()
        ServletContext context = this.getServletContext();//servletcontext是共享的
        String username = "xiaopeng"; // 数据
        context.setAttribute("username", username); // 将一个数据保存在了ServletContext中,名字为: username,值为:username
    }
}
//读取数据的类
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();//获得的是同一个context
        String username = (String) context.getAttribute("username");
        resp.setContentType("text/html");//设置显示中文
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("请叫我" + username);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
//配置web.xml 注册映射servlet
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.xiaopeng.servlet.HelloServlet</servlet-class>//映射地址
</servlet>
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>GetServlet</servlet-name>
    <servlet-class>com.xiaopeng.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>GetServlet</servlet-name>
    <url-pattern>/GS</url-pattern>
</servlet-mapping>

测试访问结果:直接访问/GS,得出null,先访问/hello,再访问/GS就能拿到结果为 “xiaopeng”

6.5.2、获取初始化参数

// 初始化信息
//配置web.xml
<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    String url = context.getInitParameter("url");
    resp.getWriter().print(url);
}

6.5.3、请求转发

不会改变url 只是转发内容

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    // RequestDispatcher requestDispatcher = context.getRequestDispatcher("/SD");
    // requestDispatcher.forward(req,resp); // 调用forward实现请求转发
    context.getRequestDispatcher("/SD").forward(req, resp); //转发SD的内容
}

以上三个用的少

6.5.4、获取资源文件

Properties

  • 在Java目录下新建properties
  • 在resources目录下新建properties

发现:都被打包到了同一个路径下:classes,我们俗称这个路径—classpath

思路:需要一个文件流 ;

user=admin
password=admin
public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");//转换成流
        Properties prop = new Properties();
        prop.load(is);
        String user = prop.getProperty("username");
        String pwd = prop.getProperty("password");
        resp.getWriter().print(user + ":" + pwd);
    }
}

注意路径是target的相对路径第一个/不能省略代表当前目录

访问测试即可 ok;

6.6、HttpServletResponse

Web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse

  • 如果要获取客户端请求过来的参数:找HttpServletResuest
  • 如果要给客户端响应一些信息:找HttpServletResponse

6.6.1、简单分类

负责向浏览器发送数据的方法

ServletoutputStream getoutputStream() throws IOException;
PrintWriter getwriter() throws IOException;

负责向浏览器发送响应头的方法

void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setBufferSize(int var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
void setStatus(int var1);

相应的状态码

int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

6.6.2、常见应用

  1. 向浏览器输出消息(getWrite等上边一直在说)

  2. 下载文件

    1. 要获取下载文件的路径

    2. 下载的文件名是啥?

    3. 想办法设置让浏览器能够支持下载我们的东西

    4. 获取下载文件的输入流

    5. 创建缓冲区

    6. 获取OutoutStream对象

    7. 将FileOutputStream流写入到缓冲区

    8. 使用OutputStream将缓冲区中的数据输出到客户端

      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 要获取下载文件的路径
        String realPath = "E:\\JAVA_code\\JavaWeb\\javaweb-02-servlet\\response\\target\\classes\\天赐.png";
        System.out.println("下载文件的路径:" + realPath);
        // 2. 下载的文件名是啥?
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
        // 3. 想办法设置让浏览器能够支持下载我们的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
        resp.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
        // 4. 获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);
        // 5. 创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
        // 6. 获取OutoutStream对象
        ServletOutputStream out = resp.getOutputStream();
        // 7. 将FileOutputStream流写入到缓冲区, 使用OutputStream将缓 冲区中的数据输出到客户端
        while ((len = in.read(buffer)) > 0) {
            out.write(buffer, 0, len);
        }
        in.close();
        out.close();
      }
  3. 验证码功能

    验证码怎么来的?

    • 前端实现
    • 后端实现,需要用到Java 的图片类,生成一个图片
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       // 如何让浏览器3秒刷新一次
       resp.setHeader("refresh", "3");
       // 在内存中创建一个图片
       BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);、
       // 得到图片
       Graphics2D g = (Graphics2D) image.getGraphics(); // 笔
       // 设置图片的背景颜色
       g.setColor(Color.white);
       g.fillRect(0, 0, 80, 20);
       // 给图片写数据
       g.setColor(Color.blue);
       g.setFont(new Font(null, Font.BOLD, 20));
       g.drawString(makeNum(), 0, 20);
       // 告诉浏览器,这个请求用图片方式打开
       resp.setContentType("image/png");
       // 网站存在缓存,不让浏览器缓存
       resp.setDateHeader("expires", -1);
       resp.setHeader("Cache-Control", "no-cache");
       resp.setHeader("Pragma", "no-cache");
       // 图片IO流
       ImageIO.write(image,"png", resp.getOutputStream());
    }
    // 生成随机数
    private String makeNum() {
       Random random = new Random();
       String num = random.nextInt(9999999) + "";
       StringBuffer sb = new StringBuffer();
       for (int i = 0; i < 7 - num.length(); i++) {
           sb.append("0");
       }
       num = sb.toString() + num;
       return num;
    }
  4. 实现重定向(重点)

重定向

B收到A请求后,它会通知A去访问C,这个过程叫做重定向

常见场景:

  • 用户登录

    测试:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // resp.setHeader("Location", "/res/img");重定向原理是这两句
    // resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
    resp.sendRedirect("/res/img");//实现重定向
    }

    面试题:请你聊聊重定向和转发的区别

    相同点:

    • 页面都会实现跳转

    不同点:

    • 请求跳转的时候,url不会产生变化

    • 重定向的时候 url 地址栏会发生变化;

    异同

    小案例:获取登录的账号密码并跳转页面(重定向)

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
    
    
    
    

    Hello world!

    <%--这里提交的路径,需要寻找到项目的路径--%> <%--${pageContext.request.contextPath}代表当前项目 需要jsp包--%>
    用户名: 密码:
    
    request
    com.xiaopeng.servlet.RequestTest
    
    
    request
    /login
    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
    Title
    
    
    

    Success

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    if (req.getServletPath() == "/login") {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username + ": " + password);
        resp.sendRedirect("/r/demo.jsp");
    }
    }

6.7、HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,我们可以获得客户端的所有信息。

与respond对应

方法有如下:

方法

方法

6.7.1、获取前端传递的参数,请求转发

获取参数

//核心
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobbies");
if (username.equals("admin") && password.equals("admin")) {                 
        resp.sendRedirect("/req/success.jsp");
        }else {
            resp.sendRedirect("/req/error.jsp");
            }
            System.out.println(req.getContextPath());// 通过请求转发// 这里的 / 代表当前的web应用                         req.getRequestDispatcher("/success.jsp").forward(req, resp);

注意请求转发与重定向的关系

7、Cookies、Session

7.1、会话

会话:用户打开了一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话。

有状态会话

一个网站,怎么证明你来过?

客户端 服务端

  1. 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie

7.2、保存会话的两种技术

cookie

  • 客户端技术 (响应,请求)

session

  • 服务端技术,利用这个技术,可以保存用户的会话信息?我们可以把信息或者数据放在Session中!

7.3、Cookie

存储层级

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie

cookie相关方法

Cookie[] cookies = req.getCookies(); // 获得Cookie
cookie.getName(); // 获得cookie中的key
cookie.getValue(); // 获得cookie中的value
new Cookie("LastLoginTime", System.currentTimeMills() + ""); // 新建一个cookie
cookie.setMaxage(60 * 60 * 24); // 设置cookie的有效期
resp.addCookie(cookie); // 响应给客户端一个cookie

利用cookie实现上一次登录时间

package com.gong;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
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.Date;

public class CookiesDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");//中文编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        PrintWriter out = resp.getWriter();
        //ServletOutputStream out = resp.getOutputStream();
        Cookie[] cookies = req.getCookies();
        if (cookies.length!=0){
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                if (cookie.getName().equals("lastTime")){
                    Long l = Long.parseLong(cookie.getValue());
                    Date date = new Date(l);
                    out.write("上次登录时间:"+date.toLocaleString());
                }
            }
        }else {
            out.write("您是第一次登录本站");
        }
        Cookie lastTime = new Cookie("lastTime", System.currentTimeMillis()+"");
        resp.addCookie(lastTime);
    }

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

清空cookie

package com.gong;

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

public class CookiesDemo02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //cookie name必须一样
        Cookie lastTime = new Cookie("lastTime", System.currentTimeMillis() + "");
        lastTime.setMaxAge(0); //生存时间设置0
        resp.addCookie(lastTime);
    }
}

cookie是中文数据该如何传?

支持中文,但是传输中文时最好

URLEncoder.encode("小鹏", "utf-8");//编码
URLDecoder.decode("小鹏", "utf-8");//解码

解决乱码最快方法

cookie:一般会保存在本地目录的用户目录下 C:\Users\admin\AppData\Local\Microsoft\Windows\History

一个网站cookie是否存在上限?

  • 一个cookie只能保存一个信息;
  • 一个web站点可以给浏览器发送多个cookie,不同浏览器可以存放的个数各不相同;
  • cookie大小有限制,Firefox和Safari以及Chrome允许cookie有4097个字节,Opera允许cookie有4096个字节

如何删除cookie

  • 不设置有效期
  • 设置有效时间为0

7.4、Session (重点)

什么是Session:

  • 服务器会给每一个用户(浏览器)创建一个Session对象
  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
  • 用户登录之后,整个网站它都可以访问!>>> 保存用户的信息;保存购物车的信息……

session

Session和Cookie的区别:

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以存放多个)
  • Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要信息,减少服务器资源浪费)
  • Session对象由服务器创建;
  • cookie只能存字符串

使用场景:

  • 保存一个登录用户的信息;
  • 购物车信息;
  • 在整个网站中经常会使用的数据我们将它保存在Session中;

使用Session:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1.解决乱码问题
    req.setCharacterEncoding("UTF-8");
    resp.setCharacterEncoding("UTF-8");
    resp.setContentType("text/html;charset=utf-8");
    // 2.得到Session
    HttpSession session = req.getSession();
    // 3.给Session中存东西
    session.setAttribute("name", new Person("天赐",17));
    //  4.获取Session的ID
    String id = session.getId();
    // 5.判断是不是新创建的
    if (session.isNew()) {
        resp.getWriter().write("Session创建成功,ID:" + id);
    }else{
        resp.getWriter().write("Session已经在服务器中存在了 ,ID:" + id);
    }
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doGet(req, resp);
}

sesssion可以存对象


/**
 * 存对象session中
 */
public class SessionDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //乱码
        resp.setContentType("text/html;charset=utf-8");
        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");
        //得到session
        HttpSession session = req.getSession();
        //Session中添加东西 可以存对象
        session.setAttribute("name", new Person("小鹏",21));
        System.out.println(session.getAttribute("name").toString());
    }

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

注销session的方法

//法1 web.xml配置session失效时间
    <session-config>
      //分钟
        <session-timeout>1</session-timeout>
    </session-config>
//法2

public class SessionDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("name");
        session.invalidate();//注销session
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

session创建时候发生了什么?

创建一个名为JSESSIONID 值为sessionid的cookie

然后丢到Cookie中,从网页响应中可以看出来

8、JSP

8.1、什么是JSP

JSP(全称JavaServer Pages)是由Sun Microsystems公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。

JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。JSP引入了被称为“JSP动作”的XML标签,用来调用内建功能。另外,可以创建JSP标签库,然后像使用标准HTML或XML标签一样使用它们。标签库能增强功能和服务器性能,而且不受跨平台问题的限制。JSP文件在运行时会被其编译器转换成更原始的Servlet代码。JSP编译器可以把JSP文件编译成用Java代码写的Servlet,然后再由Java编译器来编译成能快速执行的二进制机器码,也可以直接编译成二进制码。( 摘抄自百度百科 )

特点:

  • 写JSP就像写HTML
  • 与HTML区别:
    • HTML只给用户提供静态资源
    • JSP页面中嵌入JAVA代码,为用户提供动态数据;

8.2、JSP原理

思路:JSP到底怎么执行的!

  • 代码层面没有任何问题
  • 服务器内部工作
    • Tomcat中有一个work目录;
    • IDEA中使用Tomcat的会在IDEA的Tomcat中生产一个work目录

浏览器向服务器发送请求,不管访问什么资源,其实都是访问Servlet!

JSP最终也会被转换成为一个Java类!

JSP 本质上就是一个Servlet

看看jsp的源码

1.判断请求

//初始化
public void _jspInit() { 
}
//销毁
public void _jspDestroy() { 
} 
//JSPService
public void _jspService(final jakarta.servlet.http.HttpServletRequest request, final jakarta.servlet.http.HttpServletResponse response)

2.内置一些对象

final jakarta.servlet.jsp.PageContext pageContext;    // 页面上下文
jakarta.servlet.http.HttpSession session = null;    // Session
final jakarta.servlet.ServletContext application;    // applicationContext
final jakarta.servlet.ServletConfig config;            // config
jakarta.servlet.jsp.JspWriter out = null;            // out
final java.lang.Object page = this;                    // page
HttpServletRequest request                            // 请求
HttpServletResponse response                        // 响应

3.输出页面前增加的代码

response.setContentType("text/html; charset=UTF-8");        // 设置响应的页面类型
pageContext = _jspxFactory.getPageContext(this, request, response,
            null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;

4.以上的这个对象我们可以在JSP页面中直接使用

请求反应

在JSP页面中:

只要是JAVA代码就会原封不动的输出,如果是HTML代码,就会被转换为

out.write("<html>\r\n");
out.print(name)

这样的格式,输出到前端!

8.3、JSP基础语法

任何语言都有自己的语法,JAVA中有,JSP作为Java技术应用的一种,它拥有一些自己扩充语法(了解),同时支持Java的全部语法

JSP表达式

作用:用来将程序的输出,输出到客户端

公式:<%= 变量或者表达式%>

<%= 变量或者表达式%>
<%= new Date().toLocaleString() %>

JSP脚本片段

<% %>

片段和片段是连着的中间可以加入html代码(比如循环放在两个片段中间方html)

<%-- JSP 脚本片段 --%>
<% 
    int sum = 0;   
    for (int i = 0; i <= 100; i++) {
            sum += i;    
            }
    out.print("<h1>" + sum + "</h1>");
%>

JSP声明

<%! %>

<%! static {
        System.out.println("Loading Servlet");
    }
    private int globalVar = 0;
    public void xiaopeng() {
        System.out.println("进入了方法xiaopeng!");
    } %>

区别

JSP声明:会被编译到JSP生成的Java类中!其他的,就会被生成到_jspService方法发中!

在JSP中,嵌入Java代码即可

总结

<%%> // 脚本片段
<%=%>  //jsp表达式
<%!%> //声明
<%-- 注释 --%>

JSP 的注释不会再客户端显示,HTML的注释会显示

8.4、JSP指令

<%@ %> 指令

①导入java包

<%@ page import="java.util.Date" %>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.Date" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%= new Date()%>
</body>
</html>

②定制错误界面

法1:<%@ page errorPage="./Error/500.jsp" %>

<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ page errorPage="./Error/500.jsp" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%= new Date().toLocaleString()%>
    <%
        int i = 1/0;
    %>
</body>
</html>

法2:配置web.xml

    <error-page>
        <error-code>500</error-code>
        <location>/Error/500.jsp</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/Error/404.jsp</location>
    </error-page>

③其他

显式标记错误页面和设置编码格式等等

<%@ page isErrorPage="true" %>  
<%@ page pageEncoding="utf-8" %>

④提取公共页面

法1:@include

  • @include是将页面合二为一 看源码可以发现
  • 用得少
<%@include file="common/header.jsp"%>
<h1>我是主体</h1>
<%@include file="common/footer.jsp"%>

法2:jsp标签jsp:include

  • jsp标签是实质上是拼接页面,实质是3个页面
  • 一般用这个
<jsp:include page="/common/header.jsp"/>
<h1>我是主体</h1>
<jsp:include page="/common/footer.jsp"/>

法1中的同名变量会相互影响因为是合成一个页面

法2中的变量不会影响因为实质是3个变量

8.5、9大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application [ServletContext] 存东西
  • config [ServletConfig]
  • out
  • page 几乎不用
  • exception 和java异常差不多

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
  //设置数据存数据
    pageContext.setAttribute("name1", "小鹏1号");
    request.setAttribute("name2", "小鹏2号");
    session.setAttribute("name3", "小鹏3号");
    application.setAttribute("name4", "小鹏4号");
    //双亲委派极致 逐层寻找
    String name1 = (String)pageContext.findAttribute("name1");
    String name2 = (String)pageContext.findAttribute("name2");
    String name3 = (String)pageContext.findAttribute("name3");
    String name4 = (String)pageContext.findAttribute("name4");
    String name5 = (String)pageContext.findAttribute("name5");
%>
{name1}{name2}
{name3}{name4}
${name5}
<%=name5%>
</body>
</html>

${name5}与<%=name5%>类似但是${name5}会过滤null

前端jsp页面实现跳转

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    pageContext.forward("/index.jsp");
    //类似于在servlet后端写的
    //request.getRequestDispatcher("/index.jsp").forward(request, response);
%>
</body>
</html>

应用场景:

  • request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻
  • session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如购物车;
  • application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如聊天

8.6、JSP标签、JSTL标签、EL表达式

需要导入包

<dependency>
  <groupId>javax.servlet.jsp.jstl</groupId>
  <artifactId>jstl-api</artifactId>
  <version>1.2</version>
</dependency>
<dependency>
  <groupId>taglibs</groupId>
  <artifactId>standard</artifactId>
  <version>1.1.2</version>
</dependency>

El表达式:${}

  • 获取数据
  • 执行运算
  • 获取web开发的常用对象
    • 例如获取表单数据 ${para.参数名}
  • 调用java方法

JSP标签携带参数转发数据

<%--
  备注:携带参数转发到JSPtag02.jsp
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    response.setContentType("text/html");
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
%>
    <jsp:forward page="JSPtag02.jsp">
        <jsp:param name="name" value="小鹏"/>
        <jsp:param name="age" value="18"/>
    </jsp:forward>
</body>
</html>
<%--
  备注:转发到JSPtag02.jsp并接受传过来的数据
--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>2</h1>
<%
    response.setContentType("text/html");
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
%>
姓名:<%=request.getParameter("name")%>
年龄:<%=request.getParameter("age")%>

</body>
</html>

JSTL表达式

JSTL标签库的使用就是为了弥补HTML的不足;他自定义了许多标签,供我们使用,标签的功能和java代码一样!

  • 核心标签(掌握部分)
  • 格式化标签
  • SQL标签
  • XML标签

菜鸟教程有使用方法

菜鸟

JSTL标签库使用步骤:

  • 引入对应的tiglib
  • 使用对应方法

注意在Tomcat中也需要引入jstl的包和standard包要不回来报错:JSTL解析错误

解决方法将这两个包放到Tomcat的包中即可

类似于java的if的JSTL

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="CoreTag01.jsp" method="get">
    姓名:<input type="text" name="username" value="{param.username}">
    <input type="submit">
    <c:if test="{param.username=='admin'}" var="isAdmin">
        <c:out value="欢迎Admin"/>
    </c:if>
    <c:out value="${isAdmin}"/>
</form>
</body>
</html>

取参数${param.参数name}

设置数据和类似于switch

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>When</h1>
<c:set var="score" value="76"/>
<c:choose>
    <c:when test="{score>=90}">
        <h1>优秀</h1>
    </c:when>
    <c:when test="{score>=80}">
        <h1>一般般</h1>
    </c:when>
    <c:when test="{score>=70}">
        <h1>及格</h1>
    </c:when>
    <c:when test="{score<=60}">
        <h1>差</h1>
    </c:when>
</c:choose>
</body>
</html>

var是声明变量 value是变量的值

遍历

c:ForEach

var遍历出来变量名

items=要遍历的数组

begin=起始位

end

step步长

<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    ArrayList<String> people = new ArrayList<>();
    people.add(0,"张三");
    people.add(1,"李四");
    people.add(2,"王五");
    people.add(3,"赵六");
    people.add(4,"田七");
    request.setAttribute("list", people);
%>
<c:forEach var="people" items="{list}">
    <c:out value="{people}"/>
</c:forEach>
<hr>
<c:forEach var="people" items="{list}" begin="1" end="3" step="2">
    <c:out value="{people}"/>
</c:forEach>
</body>
</html>

9、JavaBean

实体类

JavaBean有特点的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法

一般用来和数据库的字段做映射 ORM;

ORM:对象关系映射

  • 表 > 类
  • 字段 > 属性
  • 行记录 > 对象

10、MVC三层架构

什么是MVC:Model View Controller 模型、视图、控制器

Servlet专注于处理请求以及控制视图跳转

Jsp专注于显示数据

10.1、早些年没有第三层

早些年架构

用户直接访问控制层,控制层就可以直接操作数据库;

在servlet中写 CRUD 控制数据库 弊端导致程序十分臃肿

servlet的代码中:处理请求、响应、试图跳转、处理JDBC、处理业务代码、处理逻辑代码

10.2、MVC三层架构

三层架构

Model

  • 业务处理 :业务逻辑(Service)
  • 数据持久层:CRU D (Dao)

View

  • 展示数据
  • 提供链接发起Servlet请求 (a, form, img…)

Controller (Servlet)

  • 接收用户的请求

  • 交给业务层处理对应的代码

  • 控制视图的跳转

    登录 —-> 接收用户的登录请求—->处理用户的请求(获取用户登录的参数,username,password)————>交给业务层处理登录业务(判断用户名密码是否正确:事务) ——>Dao层查询用户名和密码是否正确——>数据库

11、Filter

Filter:过滤器,用来过滤网站的数据;

  • 处理中文乱码

  • 登录验证…

    请求流程

例子:利用过滤器处理中文乱码

首先导包

<dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

过滤器代码

package com.gong.Filter;

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

public class CharacterEncodingFilter implements Filter {
    //web服务器启动后就初始化了
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化....");
    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=UTF-8");
        System.out.println("过滤前....");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("过滤后....");
    }

    public void destroy() {
        //服务器关闭的时候才会销毁
        System.out.println("销毁了");
    }
}

web.xml映射

<servlet>
        <servlet-name>ServletTest01</servlet-name>
        <servlet-class>com.gong.Servlet.ServletTest01</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletTest01</servlet-name>
        <url-pattern>/servlet/s1</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ServletTest01</servlet-name>
        <url-pattern>/s1</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.gong.Filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/servlet/*</url-pattern><!--设置哪些路径用到过滤器 -->
    </filter-mapping>

Chain:链

  • 过滤中的所有代码,在过滤特定请求的时候都会执行
  • 必须让过滤器继续通行Chain.doFilter(request,response);

Fileter开发步骤

  • 导包
  • 编写过滤器
    • 导入包不要错 servlet的 filter
    • 编写代码
  • web.xml中配置fileter过滤器

12、监听器

实现监听器的接口

  1. 编写一个监听器实现监听器的接口

    // session 统计网站在线人数
    public class OnlineCountListener implements HttpSessionListener {
       // session监听
       // 一旦创建Session就会触发一次这个事件
       @Override
       public void sessionCreated(HttpSessionEvent se) {
           ServletContext ctx = se.getSession().getServletContext();
           System.out.println(se.getSession().getId());
           Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
           if (onlineCount == null) {
               onlineCount = new Integer(1);
           } else {
               int count = onlineCount.intValue();
               onlineCount = new Integer(count+1);
           }
           ctx.setAttribute("OnlineCount", onlineCount);
       }
       @Override
       public void sessionDestroyed(HttpSessionEvent se) {
           ServletContext ctx = se.getSession().getServletContext();
           System.out.println(se.getSession().getId());
           Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
           if (onlineCount == null) {
               onlineCount = new Integer(0);
           } else {
               int count = onlineCount.intValue();
               onlineCount = new Integer(count-1);
           }
           ctx.setAttribute("OnlineCount", onlineCount);
       }
    }
  2. web.xml中注册监听器

    
       com.xiaopeng.listener.OnlineCountListener
    
  3. 看情况是否使用

13、过滤器、监听器常见应用

监听器:GUI编程中经常使用;

用户登录后才能进入主页,注销后就不能进入主页

  1. 用户登录后,向Session中放入用户的数据
  2. 进入主页的时候要判断用户是否已经登录

Servlet代码

//登录
public class ServletLogin extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username"); //验证输入信息是否正确
        if (username.equals("admin")){
             req.getSession().setAttribute("USER_SESSION", req.getSession().getId());
            resp.sendRedirect("/sys/success.jsp");
        }else {
            resp.sendRedirect("/error.jsp");
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
//注销
public class Servletlogout extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object username = req.getSession().getAttribute("USER_SESSION");
        if (username!=null){
            req.getSession().removeAttribute("USER_SESSION");
            resp.sendRedirect("/login.jsp");
        }else {
            resp.sendRedirect("/login.jsp");
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

过滤器(有的页面需要登录才能访问)

public class SysFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
      //转换成HttpServletRequest好获得session
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        //session中没有USER_SESSION信息则无法进入某些页面跳转错误也
        if (request.getSession().getAttribute("USER_SESSION")==null){
            response.sendRedirect("/error.jsp");
        }
        filterChain.doFilter(request, response);
    }
    public void destroy() {
    }
}

前端页面比较简单

14、JDBC

什么是JDBC: Java DataBase Connect

之前文章有

给TA打赏
共{{data.count}}人
人已打赏
Java笔记MySQL笔记

Java数据库驱动JDBC

2021-12-5 16:57:29

JavaWebJava笔记

JavaWeb之文件上传与下载

2021-12-29 18:01:40

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
购物车
优惠劵
有新私信 私信列表
搜索