JavaWeb核心|Servlet

一、发布资源引入:

实现步骤;
1.创建一个 JavaWeb项目。
2.将静态页面所需资源导入到项目的web目录下。
3.修改 web.xml配置文件,修改默认主页。
4.将项目部署到 tomcat中。
5.启动 tomcat服务
6.打开浏览器测试查看页面。

在这里插入图片描述
在这里插入图片描述

<?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_3_1.xsd"
         version="3.1">
    <!--    修改默认主页-->
    <welcome-file-list>
        <welcome-file>/news/news.html</welcome-file>
    </welcome-file-list>
</web-app>

访问即可。

二、发布动态资源(Servlet基础)

实现步骤:

1.创建一个 JavaWeb项目。
2.将静态页面所需资源导入到项目的web目录下。
3.修改web.xml配置文件,修改默认主页
4.在项目的src路径下编写一个类,实现Servlet接口
5.重写service方法,输出一句话即可。
6.修改web.xml配置文件,配置servlet相关资源
7.将项目部署到tomcat中。
8.启动 tomcat服务。
9.打开浏览器测试功能。

1.创建一个 JavaWeb项目。
在这里插入图片描述2.将静态页面所需资源导入到项目的web目录下。
在这里插入图片描述
3.修改web.xml配置文件,修改默认主页

    <!--    修改默认主页-->
    <welcome-file-list>
        <welcome-file>/html/frame.html</welcome-file>
    </welcome-file-list>

4.在项目的src路径下编写一个类,实现Servlet接口

package com.itjc.servlet;

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

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

    }

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

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Servlet动态资源被访问了······");
    }

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

    @Override
    public void destroy() {

    }
}

5.重写service方法,输出一句话即可。

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Servlet动态资源被访问了······");
    }

6.修改web.xml配置文件,配置servlet相关资源

    <servlet>
        <servlet-name>studentServlet</servlet-name>
        <servlet-class>com.itjc.servlet.StudentServlet</servlet-class>
    </servlet>

    <!--    映射 注意 此处的name 一定要与 上面的name相同-->
    <servlet-mapping>
        <servlet-name>studentServlet</servlet-name> 
        <url-pattern>/studentServlet</url-pattern>
    </servlet-mapping>
理解:访问/studentServelt时,先会去寻找名称为studentServlet的资源,找到后在映射成class

7.将项目部署到tomcat中。
在这里插入图片描述

8.启动 tomcat服务。
9.打开浏览器测试功能。
访问:http://localhost:8088/crm/studentServlet
在这里插入图片描述

Serlvet执行流程:在这里插入图片描述

三、Servlet

3.1 Servlet介绍

查看JavaEE的文档,搜索Servlet

javax.servlet
Interface Servlet

All Known Subinterfaces: 
	HttpJspPage, JspPage 
All Known Implementing Classes: 
	FacesServlet, GenericServlet, HttpServlet 

	
public interface Servlet

Defines methods that all servlets must implement. 

A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol. 

To implement this interface, you can write a generic servlet that extends javax.servlet.GenericServlet or an HTTP servlet that extendsjavax.servlet.http.HttpServlet. 

This interface defines methods to initialize a servlet, to service requests, and to remove a servlet from the server. These are known as life-cycle methods and are called in the following sequence: 
	1.The servlet is constructed, then initialized with the init method. 
	2.Any calls from clients to the service method are handled. 
	3.The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized. 

In addition to the life-cycle methods, this interface provides the getServletConfig method, which the servlet can use to get any startup information, and the getServletInfo method, which allows the servlet to return basic information about itself, such as author, version, and copyright.

总结:
第一:Servlet是一个运行在web服务端的java小程序
第二:它可以用于接收和响应客户端的请求
第三:要想实现Servlet功能,可以实现Servlet接口,继承GenericServlet或者HttpServlet
第四:每次请求都会执行service方法
第五:Servlet还支持配置

● Servlet是运行在Java服务器端的程序,用于接收和响应来自客户端基于HTTP协议的请求。
● 如果想实现 Servlet的功能,可以通过实现 javax.servlet.Servlet接口或者继承它的实现类

在这里插入图片描述

3.2 Servlet快速入门

1.创建一个WEB项目。
2.创建一个类继承GenericServlet
3.重写 service方法
4.在 web.xml中配置 Servlet。
5.部署并启动项目。
6.通过浏览器测试。

1.创建一个WEB项目。
2.创建一个类继承GenericServlet

package com.itjc.servlet;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

public class ServletDemo01 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Service方法执行了······");
    }
}

3.重写 service方法

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Service方法执行了······");
    }

4.在 web.xml中配置 Servlet。

    <servlet>
        <servlet-name>ServletDemo01</servlet-name>
        <servlet-class>com.itjc.servlet.ServletDemo01</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletDemo01</servlet-name>
        <url-pattern>/ServletDemo01</url-pattern>
    </servlet-mapping>

5.部署并启动项目。
6.通过浏览器测试。
http://localhost:8888/demo01/ServletDemo01

在这里插入图片描述

3.3 Servlet执行过程

在这里插入图片描述

3.4 Servlet关系视图

在这里插入图片描述

3.5 Servlet实现方式

1. 第一种
●实现Servlet接口,实现所有的抽象方法。该方式支持最大程度的自定义。

2. 第二种
继承GenericServlet抽象类,必须重写service方法,其他方法可选择重写。该方式让我们开发Servlet变得简单。但是这种方式和HTTP协议无关

3. 第三种(较为常用)
继承Httpservlet抽象类,需要重写doGetdoPost方法。该方式表示请求和响应都需要和HTTP协议相关。

Httpservlet快速入门

  1. 创建一个类继承Httpservlet
  2. 重写doGetdoPost方法。
  3. web.xml中配置Servlet
  4. 部署并启动项目。
  5. 通过浏览器测试

为什么需要重写doGetdoPost?查阅HttpServlet.class

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request;
        HttpServletResponse response;
        try {
            request = (HttpServletRequest)req;
            response = (HttpServletResponse)res;
        } catch (ClassCastException var6) {
            throw new ServletException("non-HTTP request or response");
        }

        this.service(request, response);
    }
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }

第一个service使得传入的ServletRequest 和 ServletResponse类型的变量发生了转换,都转成了HTTP类型,然后调用下面那个service进行判断,判断是什么请求,从而发出GET或者POST请求。

  1. 创建一个类继承Httpservlet
  2. 重写doGetdoPost方法。
public class ServletDemo02 extends HttpServlet {
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       System.out.println("Get方法执行了······");
   }

   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req, resp);
   }
}
  1. web.xml中配置Servlet
    <servlet>
        <servlet-name>ServletDemo02</servlet-name>
        <servlet-class>com.itjc.servlet.ServletDemo02</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletDemo02</servlet-name>
        <url-pattern>/ServletDemo02</url-pattern>
    </servlet-mapping>
  1. 部署并启动项目。
  2. 通过浏览器测试
    测试链接http://localhost:8888/demo01/ServletDemo02
    在这里插入图片描述

3.6 Servlet生命周期

  • 对象的生命周期,就是对象从出生到死亡的过程。即:出生->活着->死亡。官方说法是对象创建到销毁的过程!
  • 出生:请求第一次到达Servlet时,对象就创建出来,并且初始化成功。只出生一次,将对象放到内存中
  • 活着:服务器提供服务的整个过程中,该对象一直存在,每次都是执行service方法
  • 死亡:当服务停止时,或者服务器宕机时,对象死亡。
  • 结论:Servlet对象只会创建次,销段次。所以Servlet对象只有一个实例。如果一个对象实例在应用中是唯的存在,那么我们就称它为单例模式。
package com.itjc.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 ServletDemo03 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("对象创建并初始化成功···");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("接收到客户端的请求···");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("接收到客户端的请求···");
    }

    @Override
    public void destroy() {
        System.out.println("对象已销毁···");
    }
}

在这里插入图片描述

3.7 Servlet线程安全问题

  • 由于 Servlet采用的是单例模式,也就是整个应用中只有一个实例对象。所以我们需要分析这个唯一的实例对象中的类成员是否线程安全。
  • 模拟用户登录功能来查看 Servlet线程是否安全
  • 结论:一个浏览器代表个线程,多个浏览器代表多个线程。按理说我们期望的应该是每个浏览器查看的都应该是自己的用户名。而现在的结果是浏览器中数据混乱。因此,我们可以认为Servlet是线程不安全的!
  • 解决:定义类成员要谨慎。如果是共用的,并且只会在初始化时赋值,其他时间都是获取的话,那么是没问题的。如果不是共用的,或者每次使用都有可能对其赋值,那就要考虑线程安全问题了,可以将其定义到dogetdoPost方法内或者使用同步功能即可。
public class ServletDemo04 extends HttpServlet {
    //    1、定义一个用户名成员变量
    private String username;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //2、获取用户名响应给浏览器

        synchronized (this) {
            username = req.getParameter("username");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //3、用户名相应给浏览器 此处最好不要用中文 涉及到一个乱码问题
            PrintWriter pw = resp.getWriter();
            pw.println("Welcome" + username);
            pw.close();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //2、获取用户名响应给浏览器
        String username;
        username = req.getParameter("username");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //3、用户名相应给浏览器 此处最好不要用中文 涉及到一个乱码问题
        PrintWriter pw = resp.getWriter();
        pw.println("Welcome" + username);
        pw.close();

    }

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

3.8 Servlet映射方式

1. 第一种

  • 具体名称的方式。访问的资源路径必须和映射配置完全相同。
    <servlet>
        <servlet-name>ServletDemo05</servlet-name>
        <servlet-class>com.itjc.servlet.ServletDemo05</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletDemo05</servlet-name>
        <url-pattern>/ServletDemo05</url-pattern>
    </servlet-mapping>

2. 第二种

  • /开头 + 通配符的方式。只要符合目录结构即可,不用考虑结尾是什么。
    <servlet>
        <servlet-name>ServletDemo05</servlet-name>
        <servlet-class>com.itjc.servlet.ServletDemo05</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletDemo05</servlet-name>
        <url-pattern>/servlet/*</url-pattern>
    </servlet-mapping>

3. 第三种

  • 通配符 + 固定格式结尾的方式。只要符合固定结尾格式即可,不用考虑前面的路径。
    <servlet>
        <servlet-name>ServletDemo05</servlet-name>
        <servlet-class>com.itjc.servlet.ServletDemo05</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletDemo05</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

注意∶优先级问题。越是具体的优先级越高,越是模糊通用的优先級越伓。第一种->第二种->第三种。

3.9 Servlet多路径映射

  • 我们可以给一个 Servlet配置多个访问映射,从而根据不同的请求路径来实现不同的功能。
  • 场景分析:
    如果访问的资源路径是/vip商品价格打9折。
    如果访问的资源路径是/vvip商品价格打5折。
    如果访问的资源路径是其他商品价格不打折。
package com.itjc.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 ServletDemo06 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、定义一个商品金额
        int money = 1000;
        // 2、获取商品的资源路径
        String path = req.getRequestURI();
        path = path.substring(path.lastIndexOf("/"));

        //  3、条件判断
        if ("/vip".equals(path)) {
            System.out.println("商品原价为:" + money + "元,优惠后:" + money * 0.9 + "元");
        } else if ("/vvip".equals(path)) {
            System.out.println("商品原价为:" + money + "元,优惠后:" + money * 0.8 + "元");
        } else {
            System.out.println("商品原价为:" + money + "元");
        }
    }

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

在这里插入图片描述

3.10 Servlet创建时机

1.第一次访问时创建

  • 优势:减少对服务器内存的浪费。提高了服务器启动的效率。
  • 弊端:如果有一些要在应用加载时就做的初始化操作,无法完成。

2.服务器加载时创建

  • 优势:提前创建好对象,提高了首次执行的效羍。可以完成一些应用加载时要做的初始化操作。

  • 弊端:对服务器内存占用较多,影响了服务器后动的效率。

  • 修改 Servlet创建时机。在<servlet>标签中,添加<load-on-startup>标签。
    在这里插入图片描述

  • 正整数代表服务器加载时创建,值越小、优先级越高。负整数惑不写代表第一次访问时创建

    <servlet>
        <servlet-name>ServletDemo03</servlet-name>
        <servlet-class>com.itjc.servlet.ServletDemo03</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletDemo03</servlet-name>
        <url-pattern>/ServletDemo03</url-pattern>
    </servlet-mapping>

在这里插入图片描述

3.11 默认Servlet

  • 默认Servlet是由服务器提供的一个Servlet。它配置在Tomcatconf目录中的web.xml中。
  • 它的映射路径是<url- pattern>/<ur- patter>,我们在发送请求时,首先会在我们项目中的 web.xml中查找映射配置,找到则执行。但是当找不到对应的Servlet路径时,就去找默认的 Servlet,由默认Servlet处理。所以,一切都是Servlet
    在这里插入图片描述

该错误是Tomcat中的Servlet提供的。

四、ServletConfig

4.1 ServletConfig介绍

  • ServletConfigServlet的配置参数对象,在Servlet的规范中,允许为每一个 Servlet都提供一些初始化的配置。所以,每个Servlet都有一个自己的Servletconfig
  • 作用:在Servlet的初始化时,把一些配置信息传递给Servlet
  • 生命周期:和Servlet相同。
    在这里插入图片描述

4.2 ServletConfig配置方式

  • <servlet>标签中,通过标签来配置。有两个子标签。
  • <param-name>:代表初始化参数的key
  • <param-va|ue>:代表初始化参数的value
    在这里插入图片描述
    <!--配置Servlet-->
    <servlet>
        <servlet-name>servletConfigDemo01</servlet-name>
        <servlet-class>com.itjc.servlet.ServletConfigDemo01</servlet-class>
        <!--   配置ServletConfig-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>desc</param-name>
            <param-value>This is a ServletConfig</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>servletConfigDemo01</servlet-name>
        <url-pattern>/servletConfigDemo01</url-pattern>
    </servlet-mapping>

4.3 ServletConfig常用方法

在这里插入图片描述

package com.itjc.servlet;

import javax.servlet.ServletConfig;
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;
import java.util.Enumeration;

public class ServletConfigDemo01 extends HttpServlet {

    //    获取ServletConfig Servletconfig的配置信息需要在初始化时候进行传递 Servlet初始化要执行init方法

    //1、声明ServletConfig
    private ServletConfig config;

    //2、通过init方法 对servletconfig对象进行赋值 服务器进行提供
    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //3、演示ServletConfig的常用方法
        String encodingValue = config.getInitParameter("encoding");
        System.out.println(encodingValue);

        //4、获取所有的key
        Enumeration<String> keys = config.getInitParameterNames();
        while (keys.hasMoreElements()) {
            //            获取每个key
            String key = keys.nextElement();
            //            根据key获取value
            String value = config.getInitParameter(key);
            System.out.println(key + ":" + value);
        }


        // 5、 获取servlet名称
        String servletName = config.getServletName();
        System.out.println(servletName);

        // 6、获取ServletContext对象
        ServletContext servletContext = config.getServletContext();
        System.out.println(servletContext);

    }

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

在这里插入图片描述

五、ServletContext

5.1 ServletContext介绍

  • Servletcontext是应用上下文对象应用域对象。每一个应用中只有一个Servletcontext对象。
  • 作用:可以配置和获得应用的全局初始化参数,可以实现Servlet之间的数据共享。
  • 生命周期:应用一加载则创建,应用被停止则销毁。

在这里插入图片描述

5.2 域对象

  • 域对象指的是对象有作用域。也就是有作用范围。域对象可以实现数据的共享。不同作用范围的域对象,共享数据的能力也不一样。
  • Servlet规范中,一共有4个域对象。 Servletcontext就是其中的-个。它也是web应用中最大的作用域,也叫application域。它可以实现整个应用之间的数据共享!

5.3 ServletContext配置方式

  • <web-app>标签中,通过<context-param>标签来配置。有两个子标签。
  • <param-name>:代表全局初始化参数的key
  • <param-vdue>:代表全局初始化参数的value
    在这里插入图片描述
    <!--    配置基本Servlet-->
    <servlet>
        <servlet-name>servletContextDemo</servlet-name>
        <servlet-class>com.itjc.servlet.ServletContextDemo</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>servletContextDemo</servlet-name>
        <url-pattern>/servletContextDemo</url-pattern>
    </servlet-mapping>

    <!--    配置ServletContext-->
    <context-param>
        <param-name>globalEncoding</param-name>
        <param-value>UTF-8</param-value>
    </context-param>
    <context-param>
        <param-name>globalDesc</param-name>
        <param-value>This is a ServletContext</param-value>
    </context-param>

5.4 Servletcontext常用方法

在这里插入图片描述

package com.itjc.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 ServletContextDemo extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //        1、获取ServletContext对象
        ServletContext context = getServletContext();

        //        2、常用方法展示
        //        获取全局参数 getinitParameter(String key) 根据key获取value]
        String value = context.getInitParameter("globalDesc");
        System.out.println(value);
        //        获取应用的虚拟目录 getContextPath()
        String contextPath = context.getContextPath();
        System.out.println(contextPath);

        //根据虚拟目录获取绝对路径 getRealPath(String path)
        String realPath = context.getRealPath("/");
        System.out.println(realPath);
        String a = context.getRealPath("/WEB-INF/classes/a.txt");
        System.out.println(a);

        String b = context.getRealPath("/b.txt");
        System.out.println(b);

        String c = context.getRealPath("/WEB-INF/c.txt");
        System.out.println(c);
    }

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

在这里插入图片描述

5.5 Servletcontext常用方法

在这里插入图片描述

Object username = servletContext.getAttribute("username");
context.setAttribute("username", "zhagnsan");
context.removeAttribute("username");

六、注解开发Servlet3

6.1 Servlet3.0规范

  • 我们使用的是Tomcat9版本。 Javaee规范要求是8.对应的Servlet版本应该是4x版本。但是,在企业开发中,稳定要远比追求新版本要重要。所以我们会降版本使用,用的是 Servlet3.1版本
  • 其实我们之前的操作全都是基于Servlet2.5版本规范的,也就是借助于配置文件的方式。后来随着软件开发逐步的演变,基于注解的配置开始流行。而Servlet3.0版本也就开始攴持注解开发了!
  • Servlet3.0版本既保留了2.5版本的配置方式,同时又支持了全新的注解配置方式。它可以完全不需要web. xml配置文件,就能实现Servlet的配置,同时还有一些其他的新特性。

6.2 自动注解开发

实现步骤:

  1. 创建一个web项目(创建JavaEE8项目)。
  2. 定义一个类,继承Httpservlet
  3. 重写doGetdoPost方法。
  4. 在类上使用@Web servlet注解配置Servlet
  5. 部署并启动项目。
  6. 通过浏览器测试。
package com.itjc.servlet;

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

@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ServletDemo01执行了···");
    }

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

在这里插入图片描述

/**
 * WebServlet注解
 * @since Servlet 3.0 (Section 8.1.1)
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {

    /**
     * 指定Servlet的名称。
     * 相当于xml配置中<servlet>标签下的<servlet-name>
     */
    String name() default "";

    /**
     * 用于映射Servlet访问的url映射
     * 相当于xml配置时的<url-pattern>
     */
    String[] value() default {};

    /**
     * 相当于xml配置时的<url-pattern>
     */
    String[] urlPatterns() default {};

    /**
     * 用于配置Servlet的启动时机
     * 相当于xml配置的<load-on-startup>
     */
    int loadOnStartup() default -1;

    /**
     * 用于配置Servlet的初始化参数
     * 相当于xml配置的<init-param>
     */
    WebInitParam[] initParams() default {};

    /**
     * 用于配置Servlet是否支持异步
     * 相当于xml配置的<async-supported>
     */
    boolean asyncSupported() default false;

    /**
     * 用于指定Servlet的小图标
     */
    String smallIcon() default "";

    /**
     * 用于指定Servlet的大图标
     */
    String largeIcon() default "";

    /**
     * 用于指定Servlet的描述信息
     */
    String description() default "";

    /**
     * 用于指定Servlet的显示名称
     */
    String displayName() default "";
}

在这里插入图片描述

注解的本质就是一个接口。

6.3 手动创建容器(不常用)

  • Servlet3.0规范除了使用自动注解的配置方式外,还攴持手动创建Servlet容器的方式。如果使用必须遵循其编写规范。在3.0版本加入了一个新的接口

七、 案例学生管理系统

7.1 案例效果

在这里插入图片描述

7.2 案例实现

  1. 创建一个web项目。
  2. 创建一个用于保存学生信息的html文件。
  3. 创建一个类,继承Httpservlet
  4. 重写doGetdoPost方法。
  5. web.xml文件中修改默认主页和配置Servlet
  6. doGet方法中接收表单数据保存到文件中,并响应给浏览器结果。
  7. 部署并启动项目
  8. 通过浏览器测试

1. 创建一个web项目。
在这里插入图片描述

2. 创建一个用于保存学生信息的html文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>保存学生信息</title>
</head>
<body>
<form action="#" method="get" autocomplete="off">
    学生姓名: <input type="text" name="username"> <br>
    学生年龄: <input type="number" name="username"> <br>
    学生成绩: <input type="number" name="username"> <br>
    <button type="submit">保存</button>
</form>
</body>
</html>

3. 创建一个类,继承Httpservlet
4. 重写doGetdoPost方法。
5. 在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">
    <!--    修改默认主页-->
    <welcome-file-list>
        <welcome-file>/addStudent.html</welcome-file>
    </welcome-file-list>


    <servlet>
        <servlet-name>studentServlet</servlet-name>
        <servlet-class>com.itjc.servlet.StudentServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>studentServlet</servlet-name>
        <url-pattern>/studentServlet</url-pattern>
    </servlet-mapping>
</web-app>

6. 在doGet方法中接收表单数据保存到文件中,并响应给浏览器结果。

package com.itjc.servlet;

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

public class StudentServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取表单数据 并保存到文件中
        String username = req.getParameter("username");
        String age = req.getParameter("age");
        String score = req.getParameter("score");

        // 采用字符输出流
        BufferedWriter bw = new BufferedWriter(new FileWriter("F:\\stu.txt", true));
        bw.write(username + " " + age + " " + score);
        bw.newLine();
        bw.close();
        //响应客户端
        PrintWriter pw = resp.getWriter();
        pw.println("Save Sucess!");
        pw.close();
    }

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

7. 部署并启动项目
8. 通过浏览器测试
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值