JaveWeb

JavaWeb

1. 基本概念

1.1 前言

web开发:

  • web,网页的意思
  • 静态web
    • html,css
    • 提供给所有人看的数据始终不会发生变化
  • 动态web
    • 提供给所有人看到数据始终会发生变化,每个人在不同的时间,不同地点看到的信息各不相同
    • 技术栈:Servlet/JSP,ASP,PHP

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

1.2 web应用程序

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

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

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

1.3 静态web

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

1.4 动态web

页面会动态展示

在这里插入图片描述

缺点:

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

优点:

  • Web页面可以动态更新,所有用户看到都不是同一个页面
  • 可以与数据库交互(数据持久化,注册)

2. web服务器

2.1 技术讲解

ASP

  • 微软,国内最早流行
  • 在HTML中嵌入了VB的脚本,ASP+COM
  • IIS

PHP

  • PHP开发速度很快,功能很强大,跨平台,代码很简单
  • 无法承接大访问量的情况(局限性)、

JSP/Servlet

  • SUN公司主推的B/S架构
  • 基于Java语言的
  • 可以承载三高问题到来的影响

2.2 web服务器

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

IIS

微软的

Tomcat

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

3. Tomcat

3.1 安装Tomcat

在这里插入图片描述

在这里插入图片描述

3.2 Tomcat启动和配置

在这里插入图片描述

启动和关闭Tomcat

在这里插入图片描述

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

可能遇到的问题:

  • Java环境变量没有配置
  • 闪退问题:需要配置兼容性
  • 乱码问题:配置文件中设置

3.3 配置

修改localhost为www.haiwang.com能否生效

  1. 找到C盘->Windows->System32->drivers->etc->hosts

    在这里插入图片描述

  2. tomcat–>conf–><connector/>

    在这里插入图片描述

  3. 配置主机名称

    • 默认主机名为:localhost->127.0.0.1
    • 默认网站应用存放位置是:webapps
    <Host name="www.haiwang.com" appBase="webapps" unpackWARs="true" autoDeploy="true"></Host>
    

可以配置启动的端口号

  • Tomcat默认端口号为:8080
  • mysql:3306
  • http:80
  • https:443
<connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>

面试题

网站是如何进行访问的?

  1. 输入一个域名,回车

  2. 检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射

    • 有,直接返回对应的IP地址
    • 没有,去DNS服务器上找,DNS服务器不在本地,在云端,找到就返回,找不到报错404

    在这里插入图片描述

  3. 可以配置环境变量

3.4 发布一个网站

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

    在这里插入图片描述

    访问:http://localhost:8080

    自己写的网站:http://localhost:8080/haiwang/

  2. 网站应该有的结构

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

4. Http

4.1 什么是Http

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

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

HTTPS:安全的,加上SSL

  • 443

4.2 两个时代

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

4.3 Http请求

客户端–发请求—>服务器

Request URL: chrome-extension://mhloojimgilafopcmlcikiidgbbnelip/dist/index.html   //请求地址
Request Method: GET  //请求方法
Status Code: 200 OK  //状态码
Referrer Policy: strict-origin-when-cross-origin

请求行

  • 请求行中的请求方式:Get
  • 请求方式:Get、Post、Head、Delete、put、tract
    • get:请求能够写到的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
    • post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效

消息头

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

4.4 Http响应

服务器–响应–客户端

cache-control: no-cache
Content-Security-Policy: script-src 'self' 'unsafe-eval' https://www.google-analytics.com; object-src 'self';
Content-Type: text/html
ETag: "LBtrPERv7M5b9VMeLmqw0Xka8eU="
Last-Modified: Mon, 07 Mar 2022 16:42:08 GMT

响应体

Accept: 告诉浏览器,它所支持的数据类型
Accept-Encoding: 支持哪种编码格式
Accept-Language: 告诉浏览器,它的语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器,请求完成是断开还是保持连接
Refresh: 告诉客户端,多久刷新一次
Location: 让网页重新定位

状态码

  • 200:请求响应成功
  • 3**:请求重定向
    • 重定向:重新到新位置去
  • 4**:找不到资源
  • 5**:服务器代码错误
    • 502 网关错误

5. Maven

在Java中,我们要导入大量的jar包,Maven能帮我们自动导入和配置这些jar包

5.1 Maven项目架构管理工具

方便我们导入jar包

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

Maven会规定好我们如何去编写我们的Java代码

5.2 下载安装Maven

https://archive.apache.org/dist/maven/maven-3/3.6.2/binaries/

下载好后,解压即可

5.3 配置环境变量

在我们的系统环境变量中,配置如下配置:

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

在这里插入图片描述

在这里插入图片描述

5.4 阿里云镜像

  • 镜像:mirrors
    • 作用:加速我们的下载
  • 国内建议使用阿里云的镜像

在这里插入图片描述

<mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
  <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
</mirror>

5.5 本地仓库

建立一个本地仓库:localRepository

在这里插入图片描述

5.6 在IDEA中使用Maven

  1. 启动IDEA
  2. 创建一个Maven项目

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  1. IDEA中的Maven设置

在这里插入图片描述

5.7 创建一个普通Maven项目

在这里插入图片描述

在这里插入图片描述

这个只有在web应用下才有

在这里插入图片描述

5.8 在IDEA中标记文件夹功能

方式1

在这里插入图片描述

方式2

在这里插入图片描述

5.9 在IDEA中配置Tomcat

在这里插入图片描述

解决警告问题

为什么会有这个问题:我们访问一个网站,需要指定一个文件夹的名字

在这里插入图片描述

在这里插入图片描述

启动

在这里插入图片描述

5.10 pom文件

pom.xml是Maven的核心配置

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>

<!--Maven版本和头文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!--我们刚配置的GAV-->
    <groupId>com.jian</groupId>
    <artifactId>javaweb-01-maven</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--项目打包方式
    jar:java应用
    war:Javaweb应用
    -->
    <packaging>war</packaging>

    <name>javaweb-01-maven Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>
    <!--配置-->
    <properties>
        <!--项目的默认构建编码-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!--编译版本-->
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>
    <!--项目依赖-->
    <dependencies>
        <!--具体依赖的jar包配置文件-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <!--项目构建用的东西-->
    <build>
        <finalName>javaweb-01-maven</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

maven由于它的约定大于配置,我们之后可能遇到我们写的配置文件,无法导出或者生效的问题,解决方案:

<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
</build>

maven默认web项目中的web.xml版本问题

替换为tomcat–>webapps–>ROOT–>WEB-INF–>web.xml

5.11 Maven仓库的使用

地址:https://mvnrepository.com/

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5.12 第一个servlet程序

在这里插入图片描述

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">

  <!--web.xml中是配置我们web的核心应用-->
  <!--注册Servlet-->
  <servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>com.jian.servlet.HelloServlet</servlet-class>
  </servlet>
  <!--一个Servlet对应一个Mapping:映射-->
  <servlet-mapping>
    <!--名字要跟servlet中的对应-->
    <servlet-name>helloServlet</servlet-name>
    <!--请求路径:/**-->
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

</web-app>

HelloServlet

package com.jian.servlet;

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

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //响应类型:HTML
        resp.setContentType("text/html");
        //设置响应编码
        resp.setCharacterEncoding("utf-8");
        //获取响应输出流
        PrintWriter out = resp.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Hello World!</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>海王的世界</h1>");
        out.println("</body>");
        out.println("</html>");
    }

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

6. Servlet

6.1 Servlet简介

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

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

6.2 HelloServlet

  1. 构建一个maven项目,创建好后删除src目录,以后就在这个项目里面建立Module,这个空工程就是Maven主工程

    在这里插入图片描述

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

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

    父项目pom.xml中有:

    <modules>
            <module>servlet-01</module>
    </modules>
    <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>4.0.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>javax.servlet.jsp-api</artifactId>
                <version>2.3.3</version>
                <scope>provided</scope>
            </dependency>
    </dependencies>
    

    子项目pom.xml中有:

    <parent>
            <artifactId>javeweb-02-servlet</artifactId>
            <groupId>com.jian</groupId>
            <version>1.0-SNAPSHOT</version>
    </parent>
    
  3. Maven环境优化

    1. 修改web.xml为Tomcat中root下的web.xml

      <?xml version="1.0" encoding="UTF-8"?>
      
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                            http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
               version="4.0"
               metadata-complete="true">
      
      
      </web-app>
      
    2. 将maven的结构搭建完整,主要就是在子module的main目录下新建java跟resources两个文件夹,同时要标记

  4. 编写一个Servlet程序

    1. 编写一个普通类
    2. 实现Servlet接口,我们直接继承HttpServlet即可
    package com.jian.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    public class HelloServlet extends HttpServlet {
        //由于get和post只是请求的实现方式不同,可以互相调用,业务逻辑都是一样的
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //ServletOutputStream outputStream = resp.getOutputStream();
            PrintWriter out = resp.getWriter();
            out.println("Hello,World!");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req,resp);
        }
    }
    
  5. 在webapp下的WEB-INF中的web.xml里编写Servlet映射

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

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0"
             metadata-complete="true">
        <!--配置Servlet-->
        <servlet>
            <servlet-name>hello</servlet-name>
            <servlet-class>com.jian.servlet.HelloServlet</servlet-class>
        </servlet>
        <!--配置Servlet映射-->
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
    </web-app>
    
  6. 配置Tomcat服务器启动

    在这里插入图片描述

  7. 启动测试

6.3 Servlet原理

Servlet是由web服务器调用,web服务器在收到浏览器请求后,会:

在这里插入图片描述

6.4 Mapping问题

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

    <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
    <!--......-->
    
  2. 一个Servlet可以指定通用路径

    <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>
    
  3. 默认请求路径,比index.jsp优先级高

    <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
  4. 指定一些后缀或前缀如*.haiwang等,但是*前面不能加项目映射路径**/**

    <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>*.haiwang</url-pattern>
    </servlet-mapping>
    
  5. 优先级

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

    <servlet>
            <servlet-name>error</servlet-name>
            <servlet-class>com.jian.servlet.ErrorServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>error</servlet-name>
            <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
    <!--配置Servlet-->
    <servlet>
         <servlet-name>hello</servlet-name>
         <servlet-class>com.jian.servlet.HelloServlet</servlet-class>
        </servlet>
        <!--配置Servlet映射-->
        <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
  6. web.xml中可以配置一些参数

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0"
             metadata-complete="true">
      <!--配置全局参数
      <context-param>
        <param-name></param-name>
        <param-value></param-value>
      </context-param>
      -->
      <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.jian.servlet.HelloServlet</servlet-class>
        <!--可以配置初始化参数
        <init-param>
          <param-name></param-name>
          <param-value></param-value>
        </init-param>
        -->
      </servlet>
      <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
      </servlet-mapping>
    </web-app>
    

6.5 ServletContext

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

作用:

  • 共享数据

    我们在一个Servlet中通过它保存的数据,可以在另一个Servlet中通过它拿到

    设置数据

    package com.jian.servlet;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //this.getInitParameter()  获取初始化参数
            //this.getServletConfig()  获取Servlet配置文件
            //this.getServletContext() 获取Servlet上下文
            ServletContext context = this.getServletContext();
            String username = "海王";
            context.setAttribute("username", username); //将一个数据保存在ServletContext中,key:value
        }
    }
    

    获取数据

    package com.jian.servlet;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class GetServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            String name = (String) context.getAttribute("username");
            resp.setContentType("text/html;charset=utf-8");
            resp.getWriter().print("姓名:" + name);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0"
             metadata-complete="true">
      <!--配置全局参数
      <context-param>
        <param-name></param-name>
        <param-value></param-value>
      </context-param>
      -->
      <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.jian.servlet.HelloServlet</servlet-class>
        <!--可以配置初始化参数
        <init-param>
          <param-name></param-name>
          <param-value></param-value>
        </init-param>
        -->
      </servlet>
      <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
      </servlet-mapping>
      
      <servlet>
        <servlet-name>getc</servlet-name>
        <servlet-class>com.jian.servlet.GetServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
      </servlet-mapping>
    </web-app>
    
  • 获取初始化参数

    web.xml

    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>
    <servlet>
        <servlet-name>gp</servlet-name>
        <servlet-class>com.jian.servlet.ServletDemo03</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>gp</servlet-name>
        <url-pattern>/gp</url-pattern>
      </servlet-mapping>
    

    getParameter

    package com.jian.servlet;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class ServletDemo03 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            String url = context.getInitParameter("url");
            resp.setContentType("text/html;charset=utf-8");
            resp.getWriter().print(url);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  • 请求转发getRequestDispatcher()

    getRequestDispatcher()

    package com.jian.servlet;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class ServletDemo04 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
    //        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");  //请求转发的路径
    //        requestDispatcher.forward(req,resp);  //实现请求转发
            //等价于上两条
            context.getRequestDispatcher("/gp").forward(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

    web.xml

    <servlet>
        <servlet-name>sd</servlet-name>
        <servlet-class>com.jian.servlet.ServletDemo04</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>sd</servlet-name>
        <url-pattern>/sd</url-pattern>
    </servlet-mapping>
    
  • 读取资源文件

    Properties

    • 在Java目录下新建properties,需要在pom.xml中添加一下内容,Maven资源过滤问题

      <build>
              <resources>
                  <resource>
                      <directory>src/main/resources</directory>
                      <includes>
                          <include>**/*.properties</include>
                          <include>**/*.xml</include>
                      </includes>
                      <filtering>true</filtering>
                  </resource>
                  <resource>
                      <directory>src/main/java</directory>
                      <includes>
                          <include>**/*.properties</include>
                          <include>**/*.xml</include>
                      </includes>
                      <filtering>true</filtering>
                  </resource>
              </resources>
      </build>
      
    • 在resources目录下新建properties

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

    在这里插入图片描述

    db.properties

    username=root
    password=123456
    

    ReadProperties

    package com.jian.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    public class ReadProperties extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
            Properties properties=new Properties();
            properties.load(is);
            String username = properties.getProperty("username");
            String password = properties.getProperty("password");
            resp.getWriter().print(username+": "+password);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req,resp);
        }
    }
    

    web.xml

      <servlet>
        <servlet-name>rp</servlet-name>
        <servlet-class>com.jian.servlet.ReadProperties</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>rp</servlet-name>
        <url-pattern>/rp</url-pattern>
      </servlet-mapping>
    

6.6 HttpServletResponse

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

  • 如果要获取客户端请求过来的参数:HttpServletRequest
  • 如果要给客户端响应一些信息:HttpServletResponse
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);
2. 下载文件
  1. 向浏览器输出信息
  2. 下载文件
    • 要获取下载文件的路径
    • 下载的文件名是啥?
    • 设置让浏览器能够支持下载我们需要的东西
    • 获取下载文件的输入流
    • 创建缓冲区
    • 获取OutputStream对象
    • 将FileOutputStream流写入到buffer缓冲区
    • 使用OutputStream将缓冲区中的数据输出到客户端
package com.jian.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        - 要获取下载文件的路径
        String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/1.png");
//        - 下载的文件名是啥?
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
//        - 设置让浏览器能够支持下载我们需要的东西,解决中文文件名问题:URLEncoder.encode();
        resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,"utf-8"));
//        - 获取下载文件的输入流
        FileInputStream fis=new FileInputStream(realPath);
//        - 创建缓冲区
        int count=0;
        byte[] buf=new byte[1024];
//        - 获取OutputStream对象
        ServletOutputStream os = resp.getOutputStream();
//        - 将FileOutputStream流写入到buffer缓冲区- 使用OutputStream将缓冲区中的数据输出到客户端
        while ((count=fis.read(buf))!=-1){
            os.write(buf,0,count);
        }
        os.close();
        fis.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">
    <servlet>
        <servlet-name>down</servlet-name>
        <servlet-class>com.jian.servlet.FileServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>down</servlet-name>
        <url-pattern>/down</url-pattern>
    </servlet-mapping>
</web-app>
3.验证码实现
  • 前端实现
  • 后端实现,需要用到java图片类

ImageServlet

package com.jian.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class ImageServlet extends HttpServlet {
    @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 graphics = (Graphics2D) image.getGraphics();
        //设置图片背景颜色
        graphics.setColor(Color.white);
        graphics.fillRect(0,0,80,20);
        //给图片写数据
        graphics.setColor(Color.yellow);
        graphics.setFont(new Font(null,Font.BOLD,20));
        graphics.drawString(getRandom(),0,20);
        //告诉浏览器,这个请求用图片的方式打开
        resp.setContentType("image/jpeg");
        //网站存在缓存,不让浏览器缓存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");
        //把图片写给浏览器
        ImageIO.write(image,"jpg",resp.getOutputStream());
    }
    private String getRandom(){
        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;
    }

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

web.xml

    <servlet>
        <servlet-name>image</servlet-name>
        <servlet-class>com.jian.servlet.ImageServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>image</servlet-name>
        <url-pattern>/image</url-pattern>
    </servlet-mapping>
4. 重定向

一个Bweb资源收到客户端A请求后,它B会通知客户端A去访问另外一个Cweb资源,这个过程叫重定向

常用场景:

  • 用户登录
void sendRedirct(String val) throws IOException;
package com.jian.servlet;

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

public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        *重定向原理
        * resp.setHeader("Location","/r/image");
        * resp.setStatus(302);
        */
        resp.sendRedirect("/r/image");
    }

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

重定向和转发的区别

相同点:

  • 页面都会实现跳转

不同点:

  • 请求转发的时候,URL不会产生变化
  • 重定向的时候,URL地址会发生变化

在这里插入图片描述

登录login

<html>
<body>
<%--这里提交的路径需要寻找项目的路径--%>
<%--${pageContext.request.contextPath}代表当前项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    <label for="username">用户名:<input type="text" name="username" id="username"></label><br>
    <label for="password">密码:<input type="password" name="password" id="password"></label><br>
    <input type="submit" value="提交">
</form>
</body>
</html>

java

package com.jian.servlet;

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理请求
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username+": "+password);
        //重定向
        resp.sendRedirect("/r/success.jsp");
    }

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

6.7 HttpServletRequest

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

获取前段传递的参数、请求转发

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Login</title>
</head>
<body>
<div style="text-align: center">
    <form action="${pageContext.request.contextPath}/login" method="post">
        <p>用户名:<input type="text" name="username"></p>
        <p>密码:<input type="password" name="password"></p>
        <p>
            爱好:
            <input type="checkbox" name="hobbies" value="踢球">踢球
            <input type="checkbox" name="hobbies" value="编程">编程
            <input type="checkbox" name="hobbies" value="泡妞">泡妞
            <input type="checkbox" name="hobbies" value="跑车">跑车
        </p>
        <p><input type="submit" value="提交"></p>
    </form>
</div>
</body>
</html>

LoginServlet

package com.jian.servlet;

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies=req.getParameterValues("hobbies");
        System.out.println(username+": "+password);
        System.out.println(Arrays.toString(hobbies));
        //通过req进行请求转发
        //注意这里的/代表当前应用
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }

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

7. Cookie、Session

  1. 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了:cookie
  2. 服务器登记客户端来过了,下次再来的时候服务器来匹配:session

7.1 保存会话的两种技术

cookie

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

session

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

常见应用:登录后,下次不用在登录

7.2 Cookie

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
  3. cookie:一般会保存在本地的用户目录下的Appdata中

一个网站Cookie是否存在上限

  • 一个Cookie只能保存一个信息
  • 一个web站点可以给浏览器发送多个cookie,一个站点最多存放20个cookie
  • Cookie大小有限制4kb
  • 300个cookie浏览器上限
package com.jian.servlet;

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.text.SimpleDateFormat;
import java.util.Date;

public class CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        PrintWriter out = resp.getWriter();
        //服务器端从客户端请求req中获取Cookie
        Cookie[] cookies = req.getCookies();  //说明cookie有多个
        //判断cookie是否为空,为空的话则是第一次访问本站
        if (cookies!=null){
            for (int i=0;i<cookies.length;i++){
                //获取cookie的名字
                if (cookies[i].getName().equals("lastLoginTime")){
                    //获取cookie的值
                    long lastLoginTime=Long.parseLong(cookies[i].getValue());
                    Date date=new Date(lastLoginTime);
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    out.write(sdf.format(date));
                }
            }
        }else {
            out.write("这是你第一次访问本站!");
        }
        //服务端给客户端响应一个cookie
        Cookie cookie=new Cookie("lastLoginTime",System.currentTimeMillis()+"");
        //设置cookie过期时间为1天,以秒为单位
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);
    }

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

删除Cookie

  • 不设置有效期,关闭浏览器,自动失效
  • 设置有效时间为0
package com.jian.servlet;

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 CookieDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建一个cookie,名字必须要和删除的相同
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
        cookie.setMaxAge(0);
        resp.addCookie(cookie);
    }

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

编码解码

URLEncoder.encode("海王","utf-8");
URLDecoder.decode(cookie.getValue(),"utf-8");

7. 3 Session

什么是Session:

  • 服务器会给每一个用户(浏览器)创建一个session对象
  • 一个Session独占一个浏览器,只要浏览器没关,这个Session就存在
  • 用户登录之后,整个网站它都可以访问

Session和Cookie的区别:

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

Session使用场景:

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

SessionDemo

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //获得一个Session
        HttpSession session = req.getSession();
        //往session中添加一个值
        //session.setAttribute("name","海王");
        session.setAttribute("person",new Person("海王",22));
        if (session.isNew()){
            resp.getWriter().write("Session创建成功,SessionID为:"+session.getId());
        }else {
            resp.getWriter().write("Session在服务器中已经存在了,ID为:"+session.getId());
        }
        //Session创建时做了什么事情
        //Cookie cookie=new Cookie("JSESSIONID",session.getId());
        //resp.addCookie(cookie);
    }
public class SessionDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //从请求中取到session
        HttpSession session = req.getSession();
        Person person = (Person) session.getAttribute("person");
        System.out.println(person.toString());
    }
}
public class SessionDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("person");
        //手动注销session
        session.invalidate();
    }
}

会话自动过期web.xml

    <!--设置Session的默认失效时间-->
    <session-config>
        <!--以分钟为单位-->
        <session-timeout>1</session-timeout>
    </session-config>

在这里插入图片描述

8. JSP

8.1 什么是JSP

Java Server Pages:Java服务器端页面,也和Servlet一样,用于动态web技术

最大特点:

  • 写JSP就像在写HTML
  • 区别:
    • HTML只给用户提供静态的数据
    • JSP页面可以嵌入Java代码,为用户提供动态数据

8.2 JSP原理

  • 代码层面没有区别

  • 服务器层面

    在这里插入图片描述

    路径:C:\Users\hj151\AppData\Local\JetBrains\IntelliJIdea2021.3\tomcat\3745e8a5-4436-4548-8626-8c3b8664793f\work\Catalina\localhost\ROOT\org\apache\jsp

    发现页面变成了Java程序

    在这里插入图片描述

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

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

    JSP本质就是一个Servlet

    index_jsp.java源码分析

    //初始化
    public void _jspInit() {
      }
    //销毁
      public void _jspDestroy() {
      }
    //JSP Service
      public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
    
    1. 判断请求
    2. 内置了一些对象
    final javax.servlet.jsp.PageContext pageContext;  //页面上下文
    javax.servlet.http.HttpSession session = null; //session
    final javax.servlet.ServletContext application;
    //applicationContext==ServletContext
    final javax.servlet.ServletConfig config;  //config
    javax.servlet.jsp.JspWriter out = null;  //out
    final java.lang.Object page = this;  //当前页面page
    
    1. 输出页面前增加的代码
          response.setContentType("text/html");
          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;
    
    1. 以上这些对象可以在JSP页面直接使用

    在这里插入图片描述

    1. 在JSP页面中:只要是Java代码就会原封不动输出,如果是HTML代码,就会被转换为下面这样的格式,输出到前端
    out.write("<html>\r\n");
    

8.3 JSP基础语法

JSP作为Java技术的一种应用,它拥有一些自己的扩充语法,Java所有语法都支持

JSP表达式

<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%=变量或者表达式%>
--%>
<%= new java.util.Date()%>

JSP脚本片段

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

脚本片段再实现

<%
    int x=10;
    out.println(x);
%>
<p>上面定义了x,下面不能重复定义</p>
<%
    int y=20;
    out.println(x+y);
%>
<%--在代码块中嵌入HTML代码--%>
<%
    for (int i = 0; i < 5; i++) {
%>
<h1>循环嵌入+<%=i%></h1>
<%
    }
%>

定义成员变量(全局变量)

<%!
    static {
        System.out.println("静态代码块");
    }
    private int globeVar=100;
    public void Call(){
        System.out.println("Run!!!");
    }
%>

会被编译到JSP生成的Java类中,其他的就会生成到_jspService方法中

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

8.4 JSP指令

<%@ page args...%>
<%@ page errorPage="error/500.jsp" %>

<%--@include会将两个页面合二为一--%>
<%@include file="commons/header.jsp"%>
<h1>
    网页主题
</h1>
<%@include file="commons/footer.jsp"%>

<%--
    JSP标签
    jsp:include:拼接页面,本质还是三个
--%>
<jsp:include page="/commons/header.jsp"></jsp:include>
<h1>
    网页主体
</h1>
<jsp:include page="/commons/footer.jsp"></jsp:include>

在web.xml中配置错误页面

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">
    <!--配置404页面-->
    <error-page>
        <error-code>404</error-code>
        <location>/error/404.jsp</location>
    </error-page>
</web-app>

8.5 9大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application [ServletContext] 存东西
  • config [ServletConfig]
  • out
  • page
  • exception
<%--内置对象--%>
<%
    pageContext.setAttribute("name1", "神舟一号");  //保存的数据只在一个页面中有效
    request.setAttribute("name2", "神舟二号");  //保存的数据在一次请求中有效,请求转发会携带这个数据
    session.setAttribute("name3", "神州三号");  //保存的数据在一次会话中有效,从浏览器打开到关闭
    application.setAttribute("name4", "神州四号");  //保存的数据在服务器中有效,从服务器打开到关闭
%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<%
    //指定作用域
    pageContext.setAttribute("name5","神舟五号",PageContext.SESSION_SCOPE);
    //上面等价于  session.setAttribute("name5,"神州五号");
%>
<%
    //转发
    pageContext.forward("/index.jsp");
    //等价于  request.getRequestDispatcher("/index.jsp").forward(request,response);
%>

request:客户端向服务器发送请求,产生的数据,用户看完就没有用了,比如新闻,用户看完没用的

session:客户端向服务器发送请求,产生的数据,用户看完了一会还有用,比如购物车

application:客户端向服务器发送请求,产生的数据,一个用户看完了,其他用户还可能使用,比如:聊天数据

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

pom.xml中导入一下两个包:

    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.taglibs</groupId>
      <artifactId>taglibs-standard-impl</artifactId>
      <version>1.2.5</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>

EL表达式:${ }

  • 获取数据
  • 执行运算
  • 获取web开发常用对象

JSP标签

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSPTag</title>
</head>
<body>
<%--
转发且携带参数标签
http://localhost?name=json&password=123456
--%>
<jsp:forward page="jsptag2.jsp">
    <jsp:param name="name" value="json"/>
    <jsp:param name="password" value="123456"/>
</jsp:forward>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSPTag2</title>
</head>
<body>
<h1>
    姓名:<%=request.getParameter("name")%><br>
    密码:<%=request.getParameter("password")%>
</h1>
</body>
</html>

JSTL标签

JSTL标签库的使用是为了弥补HTML标签的不足,它自定义许多标签,可以供我们使用,标签的功能和Java代码一样

核心标签

在这里插入图片描述

JSTL标签库使用步骤

  • 引入对应的taglib

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
  • 使用其中的方法

  • 不一定管用(在Tomcat中的lib目录下也要引入jstl和standard包,否则可能会报错)

  • 额外导入一个jstl-api的包,大概率有用

C:IF

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--使用jstl前引入对应的taglib--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Coreif</title>
</head>
<body>
<h1>coreif测试</h1>
<form action="coreif.jsp" method="get">
    <%--
    EL表达式获取表单中的数据
    ${param.username}
    --%>
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="提交">
</form>
<c:if test="${param.username=='admin'}" var="isAdmin">
    <c:out value="欢迎你管理员"/>
</c:if>
<c:out value="${isAdmin}"/>
</body>
</html>

C:When

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Corewhen</title>
</head>
<body>
<%--定义一个变量--%>
<c:set var="score" value="80"/>
<c:choose>
    <c:when test="${score>=90}">
        优秀!
    </c:when>
    <c:when test="${score>=80}">
        良好!
    </c:when>
    <c:when test="${score>=70}">
        一般!
    </c:when>
    <c:when test="${score>=60}">
        及格!
    </c:when>
</c:choose>
</body>
</html>

C:Foreach

<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>CoreForeach</title>
</head>
<body>
<%
    ArrayList<String> person=new ArrayList<String>();
    person.add(0,"张三");
    person.add(1,"李四");
    person.add(2,"王五");
    request.setAttribute("list",person);
%>
<%--
var:每一次遍历的变量
items:要遍历的对象
begin:哪里开始遍历,默认0
end:到哪里结束遍历
step:步长
--%>
<c:forEach var="people" items="${list}">
    <c:out value="${people}"/><br>
</c:forEach>
<hr>
<c:forEach var="people" items="${list}" begin="1" end="2" step="1">
    <c:out value="${people}"/>
</c:forEach>
</body>
</html>

9. JavaBean

实体类

JavaBean有特定写法:

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

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

ORM:对象关系映射

  • 表–>类
  • 字段–>属性
  • 行记录–>对象
CREATE TABLE IF NOT EXISTS people(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
`age` INT NOT NULL,
`address` VARCHAR(200) NOT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8

jsp标签操作JavaBean

<%@ page import="com.jian.pojo.People" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JavaBean</title>
</head>
<body>
<%--
    People people = new People();
    people.setId(1);
    people.setName("南昌号");
    people.setAge(6);
    people.setAddress("南昌");
--%>
<%--上面的代码等价于下面的jsp标签--%>
<jsp:useBean id="people" class="com.jian.pojo.People" scope="page"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="name" value="南昌号"/>
<jsp:setProperty name="people" property="age" value="6"/>
<jsp:setProperty name="people" property="address" value="南昌"/>
<%--<%=people.getName()%>--%>
<h3>编号:<jsp:getProperty name="people" property="id"/></h3>
<h3>舰名:<jsp:getProperty name="people" property="name"/></h3>
<h3>年限:<jsp:getProperty name="people" property="age"/></h3>
<h3>产地:<jsp:getProperty name="people" property="address"/></h3>
</body>
</html>

10. MVC三层架构

什么是三层架构:Model、View、Controller、模型、视图、控制器

10.1 MVC

在这里插入图片描述

Model

  • 业务处理:业务逻辑(service)
  • 数据持久层:CRUD(Dao)

View

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

Controller

  • 接收用户的请求(req:请求参数,Session信息)
  • 交给业务层处理对应的代码
  • 控制视图的跳转

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

11. Filter

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

  • 处理中文乱码
  • 登录验证

在这里插入图片描述

Filter开发步骤:

  1. 导包

  2. 编写

    • 实现的接口不要导错

    在这里插入图片描述

    • 实现Filter接口,重写对应的方法
    package com.jian.filter;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class CharacterEncodingFilter implements Filter {
        //初始化:Web服务器启动时便初始化了,随时等待过滤对象出现
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("CharacterEncodingFilter初始化");
        }
        //销毁:Web服务器关闭时候销毁
        @Override
        public void destroy() {
            System.out.println("CharacterEncodingFilter销毁");
        }
        /*
        1.过滤中的所有代码,在过滤特定请求时都会执行
        2.必须让过滤器继续通行
          filterChain.doFilter(servletRequest,servletResponse);
        */
        @Override
        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("执行后...");
        }
    }
    
    • 配置web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        <servlet>
            <servlet-name>ShowServlet</servlet-name>
            <servlet-class>com.jian.servlet.ShowServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>ShowServlet</servlet-name>
            <url-pattern>/servlet/show</url-pattern>
        </servlet-mapping>
    
        <filter>
            <filter-name>CharacterEncodingFilter</filter-name>
            <filter-class>com.jian.filter.CharacterEncodingFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>CharacterEncodingFilter</filter-name>
            <!--只要是/servlet下的所有请求,都会经过这个过滤器-->
            <url-pattern>/servlet/*</url-pattern>
        </filter-mapping>
    </web-app>
    

12. 监听器

实现一个监听器的接口:

  1. 编写一个监听器

    • 实现监听器的接口
    package com.jian.listener;
    
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
    
    //统计网站在线人数:统计session
    public class OnlineCountListener implements HttpSessionListener {
        //一旦Session创建就会触发一次这个事件
        @Override
        public void sessionCreated(HttpSessionEvent se) {
            ServletContext context = se.getSession().getServletContext();
            Integer onlineCount = (Integer) context.getAttribute("onlineCount");
            if (onlineCount==null){
                onlineCount=new Integer(1);
            }else {
                int count=onlineCount.intValue();
                onlineCount=new Integer(++count);
            }
            context.setAttribute("onlineCount",onlineCount);
        }
        //一旦Session销毁就会触发一次这个事件
        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            ServletContext context = se.getSession().getServletContext();
            Integer onlineCount = (Integer) context.getAttribute("onlineCount");
            if (onlineCount==null){
                onlineCount=new Integer(0);
            }else {
                int count=onlineCount.intValue();
                onlineCount=new Integer(--count);
            }
            context.setAttribute("onlineCount",onlineCount);
        }
    }
    
  2. web.xml中注册监听器

        <!--注册监听器-->
        <listener>
            <listener-class>com.jian.listener.OnlineCountListener</listener-class>
        </listener>
        <session-config>
            <session-timeout>1</session-timeout>
        </session-config>
    
  3. index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>在线人数</title>
    </head>
    <body>
     <h1>当前在线<span style="color: red"><%=application.getAttribute("onlineCount")%></span>人</h1>
    </body>
    </html>
    

12.1 常见应用-登录拦截

  1. 用户登录成功后向Session中存放用户的数据
  2. 进入主页要判断用户是否已经登录,用过滤器实现

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Login</title>
</head>
<body>
<form action="/servlet/login" method="post">
    <p>用户名:<input type="text" name="username"></p>
    <p>密码:<input type="password" name="password"></p>
    <p><input type="submit" value="登录"></p>
</form>
</body>
</html>

LoginServlet

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if ("admin".equals(username)&&"123456".equals(password)){
            req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
            resp.sendRedirect("/sys/success.jsp");
        }else {
            resp.sendRedirect("/error.jsp");
        }
    }

/sys/success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>后台首页</title>
</head>
<body>
<%--
    Object user_session = request.getSession().getAttribute("USER_SESSION");
    if (user_session==null){
        response.sendRedirect("/login.jsp");
    }
--%>
<h1 style="color: aqua;text-align: center">欢迎你管理员</h1>
<h3 style="text-align: center"><a href="/servlet/logout" style="text-decoration: none">注销</a> </h3>
</body>
</html>

SysFilter

@Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req= (HttpServletRequest) servletRequest;
        HttpServletResponse resp= (HttpServletResponse) servletResponse;
        if (req.getSession().getAttribute("USER_SESSION")==null){
            resp.sendRedirect("/login.jsp");
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }

LogoutServlet

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object user_session = req.getSession().getAttribute("USER_SESSION");
        if (user_session!=null){
            req.getSession().removeAttribute("USER_SESSION");
            resp.sendRedirect("/login.jsp");
        }
    }

web.xml

    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.jian.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <url-pattern>/sys/*</url-pattern>
    </filter-mapping>
    <!--注册监听器-->
    <listener>
        <listener-class>com.jian.listener.OnlineCountListener</listener-class>
    </listener>
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.jian.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/servlet/login</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>com.jian.servlet.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/servlet/logout</url-pattern>
    </servlet-mapping>

12.2 Junit

依赖:pom.xml

<!--单元测试-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

简单使用

@Test注解只在方法上有效,只要加了这个注解的方法,就可以直接运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值