JavaWeb

JavaWeb概述

B/S架构

B/S 架构:Browser/Server,浏览器/服务器架构模式,它的特点是:客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可。

028

静态资源

静态资源主要包含HTML、CSS、JavaScript、图片等,主要负责页面的展示。

动态资源

动态资源主要包含Servlet、JSP等,主要用来负责逻辑处理。

动态资源处理完逻辑后会把得到的结果交给静态资源来进行展示,动态资源和静态资源要结合一起使用。

数据库

数据库主要负责存储数据。

整个Web的访问过程就如下图所示:

029

HTTP协议

HTTP协议主要定义通信规则

Web服务器

Web服务器负责解析 HTTP 协议,解析请求数据,并发送响应数据

HTTP

HTTP概念

HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。

HTTP协议特点

  • 基于TCP协议:面向连接,安全。
  • 基于请求-响应模型的:一次请求对应一次响应
  • HTTP协议是无状态协议:对于事物处理没有记忆能力。每次请求-响应都是独立的。

请求数据格式

030

请求数据总共分为三部分内容:

  • 请求行:HTTP请求中的第一行数据,请求行包含三块内容,分别是 GET[请求方式] /[请求URL路径] HTTP/1.1[HTTP协议及版本]

    请求方式有七种,最常用的是GET和POST

  • 请求头:第二行开始,格式为key: value形式

    请求头中会包含若干个属性,常见的HTTP请求头有:

    Host: 表示请求的主机名
    User-Agent: 浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 ...Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT ...)like Gecko;
    Accept:表示浏览器能接收的资源类型,如text/*,image/*或者*/*表示所有;
    Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
    Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等。
    
  • 请求体:POST请求的最后一部分,存储请求参数

    031

    如上图红线框的内容就是请求体的内容,请求体和请求头之间是有一个空行隔开。此时浏览器发送的是POST请求。

    GET和POST的区别:

    • GET请求请求参数在请求行中,没有请求体,POST请求参数在请求体中。
    • GET请求请求参数大小有限制,POST没有。

响应数据格式

032

响应数据总共分为三部分内容:

  • 响应行:响应数据的第一行,响应行包含三块内容,分别是 HTTP/1.1[HTTP协议及版本] 200[响应状态码] ok[状态码的描述]。

  • 响应头:第二行开始,格式为key:value形式。

    响应头中会包含若干个属性,常见的HTTP响应头有:

    Content-Type:表示该响应内容的类型,例如text/html,image/jpeg;
    Content-Length:表示该响应内容的长度(字节数);
    Content-Encoding:表示该响应压缩算法,例如gzip;
    Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒
    
  • 响应体:最后一部分,存放响应数据。

    上图中…这部分内容就是响应体,它和响应头之间有一个空行隔开。

响应状态码

关于响应状态码,先主要认识三个状态码,其余的等后期用到了再去掌握:

  • 200 ok 客户端请求成功
  • 404 Not Found 请求资源不存在
  • 500 Internal Server Error 服务端发生不可预期的错误

Tomcat

简介

Web服务器是一个应用程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。Web服务器软件使用步骤:

  • 准备静态资源
  • 下载安装Web服务器软件
  • 将静态资源部署到Web服务器上
  • 启动Web服务器使用浏览器访问对应的资源

Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。因为Tomcat支持Servlet/JSP规范,所以Tomcat也被称为Web容器、Servlet容器。Servlet需要依赖Tomcat才能运行。

下载安装

Apache官网中找到Tomcat官网选择对应版本下载

直接解压即可,其中文件大致如下:

033

  • bin:目录下有两类文件:
    • 一种是以.bat结尾的,是Windows系统的可执行文件
    • 一种是以.sh结尾的,是Linux系统的可执行文件。
  • webapps就是以后项目部署的目录

启动

双击:bin\startup.bat

启动后,通过浏览器访问 http://localhost:8080能看到Apache Tomcat的内容就说明Tomcat已经启动成功。

034

关闭

关闭有三种方式 :

  • 直接x掉运行窗口:强制关闭[不建议]
  • bin\shutdown.bat:正常关闭
  • ctrl+c:正常关闭

配置

解决log中文乱码

默认采用UTF-8,在conf\logging.propertoes中如下位置改为GBK即可:

035

修改端口号

Tomcat默认的端口是8080,修改Tomcat启动的端口号,需要修改 conf/server.xml如下位置:

036

Tips:Tomcat的端口号取值范围是0-65535之间任意未被占用的端口,如果设置的端口号被占用,启动的时候就会包如下的错误

037

部署

将项目放置到webapps目录下,即部署完成。

随着项目的增大,项目中的资源也会越来越多,项目在拷贝的过程中也会越来越费时间,一般JavaWeb项目会被打包称war包,然后将war包放到Webapps目录下,Tomcat会自动解压缩war文件。

Web项目结构

Web项目的结构分为开发中的项目和开发完可以部署的Web项目,这两种项目的结构是不一样的。

  • 开发中的项目

    038

  • 开发完成部署的Web项目

    039

    • 开发项目通过执行Maven打包命令package,可以获取到部署的Web项目目录。
    • 编译后的Java字节码文件和resources的资源文件,会被放到WEB-INF下的classes目录下。
    • pom.xml中依赖坐标对应的jar包,会被放入WEB-INF下的lib目录下。

IDEA使用Tomcat

集成本地Tomcat
  • 在运行/调试配置中添加本地Tomcat

    040

  • 选择本低Tomcat路径,设置名称

    041

  • 选择需要部署的项目

    042
    043

    • xxx.war和 xxx.war exploded这两种部署项目模式的区别:
      • war模式是将WEB工程打成war包,把war包发布到Tomcat服务器上。
      • war exploded模式是将WEB工程以当前文件夹的位置关系发布到Tomcat服务器上。
      • war模式部署成功后,Tomcat的webapps目录下会有部署的项目内容。
      • war exploded模式部署成功后,Tomcat的webapps目录下没有,而使用的是项目的target目录下的内容进行部署。
      • 建议大家都选war模式进行部署,更符合项目部署的实际情况。
Tomcat Maven插件

在pom.xml中添加Tomcat插件

<build>
    <plugins>
    	<!--Tomcat插件 -->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
        </plugin>
    </plugins>
</build>

在IDEA中安装Maven Helper插件后右键项目即可运行

044

Servlet

简介

Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。使用Servlet就可以实现,根据不同的登录用户在页面上动态显示不同内容。

Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet。

快速入门

  1. 创建Web项目web-demo,导入Servlet依赖坐标

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    
  2. 创建:定义一个类,实现Servlet接口,并重写接口中所有方法,并在service方法中输入一句话

    package com.itheima.web;
    
    public class ServletDemo1 implements Servlet {
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("servlet hello world~");
        }
        
        public void init(ServletConfig servletConfig) throws ServletException {
    
        }
    
        public ServletConfig getServletConfig() {
            return null;
        }
    
        public String getServletInfo() {
            return null;
        }
    
        public void destroy() {
    
        }
    }
    
  3. 配置:在类上使用@WebServlet注解,配置该Servlet的访问路径

    @WebServlet("/demo1")
    
  4. 访问:启动Tomcat,浏览器中输入URL地址访问该Servlet

    http://localhost:8080/web-demo/demo1
    
  5. 浏览器访问后,在控制台会打印servlet hello world~ 说明servlet程序已经成功运行。

执行流程

045

  • 浏览器发出http://localhost:8080/web-demo/demo1请求,从请求中可以解析出三部分内容,分别是localhost:8080web-demodemo1
    • 根据localhost:8080可以找到要访问的Tomcat Web服务器
    • 根据web-demo可以找到部署在Tomcat服务器上的web-demo项目
    • 根据demo1可以找到要访问的是项目中的哪个Servlet类,根据@WebServlet后面的值进行匹配
  • 找到ServletDemo1这个类后,Tomcat Web服务器就会为ServletDemo1这个类创建一个对象,然后调用对象中的service方法
    • ServletDemo1实现了Servlet接口,所以类中必然会重写service方法供Tomcat Web服务器进行调用
    • service方法中有ServletRequest和ServletResponse两个参数,ServletRequest封装的是请求数据,ServletResponse封装的是响应数据,后期我们可以通过这两个参数实现前后端的数据交互

方法介绍

Servlet中总共有5个方法

  • 初始化方法,在Servlet被创建时执行,只执行一次

    void init(ServletConfig config) 
    
  • 销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet

    void destroy() 
    
  • 提供服务方法, 每次Servlet被访问,都会调用该方法

    void service(ServletRequest req, ServletResponse res)
    
  • 获取Servlet信息

    String getServletInfo() 
    //该方法用来返回Servlet的相关信息,没有什么太大的用处,一般我们返回一个空字符串即可
    public String getServletInfo() {
        return "";
    }
    
  • 获取ServletConfig对象

    ServletConfig getServletConfig()
    

体系结构

046

HttpServlet类

这玩意儿可以简化代码开发。

如果直接继承Servlet接口,为了能处理不同的请求方式,我们得在service方法中进行判断,然后写不同的业务处理:

package com.itheima.web;

@WebServlet("/demo5")
public class ServletDemo5 implements Servlet {
    public void init(ServletConfig config) throws ServletException {
    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        //如何调用?
        //获取请求方式,根据不同的请求方式进行不同的业务处理
        HttpServletRequest request = (HttpServletRequest)req;
       //1. 获取请求方式
        String method = request.getMethod();
        //2. 判断
        if("GET".equals(method)){
            // get方式的处理逻辑
        }else if("POST".equals(method)){
            // post方式的处理逻辑
        }
    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {
    }
}

现在这么写就行:

@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //TODO GET 请求方式处理逻辑
        System.out.println("get...");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //TODO Post 请求方式处理逻辑
        System.out.println("post...");
    }
}
  • 要想发送一个GET请求,请求该Servlet,只需要通过浏览器发送http://localhost:8080/web-demo/demo4,就能看到doGet方法被执行了。

  • 要想发送一个POST请求,请求该Servlet,单单通过浏览器是无法实现的,这个时候就需要编写一个form表单来发送请求,在webapp下创建一个a.html页面,内容如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/web-demo/demo4" method="post">
            <input name="username"/><input type="submit"/>
        </form>
    </body>
    </html>
    

urlPattern配置

Servlet类编写好后,要想被访问到,就需要配置其访问路径。

一个Servlet,可以配置多个urlPattern:

@WebServlet(urlPatterns = {"/demo7","/demo8"})

这样在浏览器上输入http://localhost:8080/web-demo/demo7,http://localhost:8080/web-demo/demo8这两个地址都能访问到ServletDemo7的doGet方法。

urlPattern配置规则

  • 精确匹配

    @WebServlet(urlPatterns = "/user/select")
    

    访问路径:http://localhost:8080/web-demo/user/select

  • 目录匹配

    @WebServlet(urlPatterns = "/user/*")
    

    访问路径:http://localhost:8080/web-demo/user/任意

  • 扩展名匹配

    @WebServlet(urlPatterns = "*.do")
    

    访问路径:http://localhost:8080/web-demo/任意.do

  • 任意匹配

    @WebServlet(urlPatterns = "/")
    @WebServlet(urlPatterns = "/*")
    

    访问路径:http://localhost:8080/demo-web/任意

    二者区别:

    • 当我们的项目中的Servlet配置了 “/”,会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时都会走这个Servlet。
    • 当我们的项目中配置了”/*”,意味着匹配任意访问路径。
    • DefaultServlet是用来处理静态资源,如果配置了”/”会把默认的覆盖掉,就会引发请求静态资源的时候没有走默认的而是走了自定义的Servlet类,最终导致静态资源不能被访问。

五种配置的优先级:精确匹配 > 目录匹配> 扩展名匹配 > /* > / ,无需记,以最终运行结果为准。

XML配置

前面对应Servlet的配置使用的是@WebServlet,这个是Servlet从3.0版本后开始支持注解配置,3.0版本前只支持XML配置文件的配置方法。

在webapp/WEB-INF/web.xml配置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">
    
    <!-- Servlet 全类名-->
    <servlet>
        <!-- servlet的名称,名字任意-->
        <servlet-name>demo13</servlet-name>
        <!--servlet的类全名-->
        <servlet-class>com.itheima.web.ServletDemo13</servlet-class>
    </servlet>

    <!-- Servlet 访问路径-->
    <servlet-mapping>
        <!-- servlet的名称,要和上面的名称一致-->
        <servlet-name>demo13</servlet-name>
        <!-- servlet的访问路径-->
        <url-pattern>/demo13</url-pattern>
    </servlet-mapping>
</web-app>

Fliter

Filter概述

Filter 表示过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一,过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。

浏览器可以访问服务器上的所有的资源(servlet、jsp、html等),而在访问到这些资源之前可以使过滤器拦截来下,也就是说在访问资源之前会先经过 Filter,如下图:

050

过滤器一般完成一些通用的操作,比如每个资源都要写一些代码完成某个功能,我们总不能在每个资源中写这样的代码吧,而此时我们可以将这些代码写在过滤器中,因为请求每一个资源都要经过过滤器。

Filter快速入门

开发步骤

进行 Filter 开发分成以下三步实现:

  1. 定义类,实现 Filter接口,并重写其所有方法

    public class FilterDemo implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void destroy() {
        }
    }
    
    
  2. 配置Filter拦截资源的路径:在类上定义 @WebFilter 注解。而注解的 value 属性值 /* 表示拦截所有的资源

    @WebFilter("/*")
    
  3. 在doFilter方法中输出一句话,并放行

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("1.FilterDemo...");
        //放行
        chain.doFilter(request,response);
    }
    

Filter执行流程

051

  1. 执行放行前逻辑
  2. 放行
  3. 访问资源
  4. 执行放行后逻辑

Filter拦截路径配置

拦截路径表示 Filter 会对请求的哪些资源进行拦截,使用 @WebFilter 注解进行配置。如:@WebFilter("拦截路径") ,拦截路径的配置方式和 Servlet 的请求资源路径配置方式一样,但是表示的含义不同,拦截路径有如下四种配置方式:

  • 拦截具体的资源:/index.jsp:只有访问index.jsp时才会被拦截
  • 目录拦截:/user/*:访问/user下的所有资源,都会被拦截
  • 后缀名拦截:*.jsp:访问后缀名为jsp的资源,都会被拦截
  • 拦截所有:/*:访问所有资源,都会被拦截

过滤器链

过滤器链是指在一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链:

052

上图中的过滤器链执行是按照以下流程执行:

  1. 执行 Filter1 的放行前逻辑代码
  2. 执行 Filter1 的放行代码
  3. 执行 Filter2 的放行前逻辑代码
  4. 执行 Filter2 的放行代码
  5. 访问到资源
  6. 执行 Filter2 的放行后逻辑代码
  7. 执行 Filter1 的放行后逻辑代码

代码演示

编写第一个过滤器 FilterDemo ,拦截所有资源

@WebFilter("/*")
public class FilterDemo implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //1. 放行前,对 request数据进行处理
        System.out.println("1.FilterDemo...");
        //放行
        chain.doFilter(request,response);
        //2. 放行后,对Response 数据进行处理
        System.out.println("3.FilterDemo...");
    }

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

    @Override
    public void destroy() {
    }
}

编写第二个过滤器 FilterDemo2 ,拦截所有资源

@WebFilter("/*")
public class FilterDemo2 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        //1. 放行前,对 request数据进行处理
        System.out.println("2.FilterDemo...");
        //放行
        chain.doFilter(request,response);
        //2. 放行后,对Response 数据进行处理
        System.out.println("4.FilterDemo...");
    }

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

    @Override
    public void destroy() {
    }
}

修改 hello.jsp 页面中脚本的输出语句

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>hello JSP~</h1>
    <%
        System.out.println("3.hello jsp");
    %>
</body>
</html>

运行效果:

053

Listener

Listener概述

Listener 表示监听器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一,监听器可以监听就是在 applicationsessionrequest 三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。

分类

监听器分类 监听器名称 作用
ServletContext监听 ServletContextListener 用于对ServletContext对象进行监听(创建、销毁)
ServletContextAttributeListener 对ServletContext对象中属性的监听(增删改属性)
Session监听 HttpSessionListener 对Session对象的整体状态的监听(创建、销毁)
HttpSessionAttributeListener 对Session对象中的属性监听(增删改属性)
HttpSessionBindingListener 监听对象于Session的绑定和解除对Session数据的钝化和活化的监听
HttpSessionActivationListener 对Request对象进行监听(创建、销毁)
Request监听 ServletRequestListener 对Request对象中属性的监听(增删改属性)
ServletRequestAttributeListener

这里面只有 ServletContextListener 这个监听器后期我们会接触到,ServletContextListener 是用来监听 ServletContext 对象的创建和销毁。

ServletContextListener 接口中有以下两个方法:

  • void contextInitialized(ServletContextEvent sce)ServletContext 对象被创建了会自动执行的方法
  • void contextDestroyed(ServletContextEvent sce)ServletContext 对象被销毁时会自动执行的方法

快速入门

演示一下 ServletContextListener 监听器

  • 定义一个类,实现ServletContextListener 接口
  • 重写所有的抽象方法
  • 使用 @WebListener 进行配置

代码如下:

@WebListener
public class ContextLoaderListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //加载资源
        System.out.println("ContextLoaderListener...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //释放资源
    }
}

启动服务器,可以在启动的日志信息中看到 contextInitialized() 方法输出的内容,同时也说明了 ServletContext 对象在服务器启动的时候被创建了。

版权声明:本文为AncilunKiang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/AncilunKiang/p/16674053.html