• Servlet入门接口、类和配置学习


    Servlet

    Servlet 是 Java 编程语言的一种特殊类型的类,通常用于在服务器端处理Web请求和生成Web响应。Servlet 在Java企业环境中广泛用于开发Web应用程序。

    1. 服务器端处理:Servlet 主要在服务器端运行,用于处理客户端发送的HTTP请求并生成响应。这使得Servlet成为构建Web应用程序的重要组件。

    2. Java平台:Servlet 是基于Java平台的,因此它可以在几乎所有支持Java的服务器上运行,例如Apache Tomcat、Jetty、IBM WebSphere等。

    3. 生命周期:Servlet 有一个生命周期,它包括初始化、请求处理和销毁等阶段。在初始化阶段,Servlet可以执行一些初始化任务。在请求处理阶段,Servlet会响应来自客户端的HTTP请求。最后,在销毁阶段,Servlet可以执行一些清理工作。

    4. HTTP请求和响应:Servlet 主要用于处理HTTP请求和生成HTTP响应。它可以接收来自浏览器的请求,读取请求参数,执行业务逻辑,然后生成HTML、XML或其他格式的响应发送回客户端。

    5. 灵活性:Servlet是灵活的,可以用于构建各种Web应用程序,包括动态网页、Web服务、RESTful API等。

    6. Java EE(现在称为Jakarta EE):在Java企业版(Java EE)规范中,Servlet是一个重要的组成部分。Java EE定义了一整套标准API,用于构建企业级Web应用程序,Servlet就是其中之一。

    Servlet的使用通常需要Java编程知识,但它是构建强大和可扩展Web应用程序的重要工具。Servlet容器(例如Tomcat)负责管理Servlet的生命周期,并确保它们可以响应来自客户端的请求。这使得Java在服务器端开发Web应用程序变得非常流行。


    创建一个Servlet,实现向控制台输出字符,展示Servlet的生命周期

    创建Web项目及包,创建 FirstServlet.java 。

    #包名
    package com.hong.Servlet.HttpServlet;
    
    • 1
    • 2
    package com.hong.Servlet.HttpServlet;
    
    import jakarta.servlet.GenericServlet;
    import jakarta.servlet.ServletException;
    import jakarta.servlet.ServletRequest;
    import jakarta.servlet.ServletResponse;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /**
     * @author WangYH
     * @version 2021.1.3
     * @date 2023/10/4 16:55
     */
    
    public class FirstServlet extends GenericServlet {
    
        @Override
        public void init() throws ServletException {
            System.out.println("init 开始运行");
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("solution Request");
    
            //获得输出流PrintWriter对象
            PrintWriter printWriter = servletResponse.getWriter();
    
            //Servlet调用输出流对象向客户发送字符信息
            printWriter.println("

    FirstServlet,hello

    "
    ); } @Override public void destroy() { System.out.println("destroy start"); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    第二步还要配置虚拟路径才能在浏览器访问,可以使用XML文件或者注解。

    
    <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> FirstServlet servlet-name>
            <servlet-class>com.hong.Servlet.HttpServlet.FirstServletservlet-class>
    
    		
            <load-on-startup> 1 load-on-startup>
        servlet>
    
    	 
    	<servlet-mapping>
            <servlet-name>SecondServletservlet-name>
            <url-pattern>/SecondServleturl-pattern>
        servlet-mapping>
        
    web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    第三步就是发布到Tomcat,输入虚拟路径访问资源。


    这里主要想讲的就是,Servlet的生命周期,主要是三个方法。

    1. init( ),在第一次被加载的时候调用一次,可以重写方法来完成初始化。
    2. service( ),真正处理请求的方法,请求对象和响应对象作为其参数。
    3. destroy( ),清除释放**init( )**占用的资源。

    配置文件写法,很重要很重要,这里没搞好,就是 404 Not Found。

    第一种,xml文件配置

    通常是一个名为 “web.xml” 的XML文件。在这个XML文件中,您可以定义和配置Servlet,以便在Web应用程序中使用。

    
    <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>HelloServletservlet-name> 
            <servlet-class>com.example.HelloServletservlet-class> 
        servlet>
    
        
        <servlet-mapping>
            <servlet-name>HelloServletservlet-name> 
            <url-pattern>/hellourl-pattern> 
        servlet-mapping>
    
    web-app>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    多重映射

    在 web.xml 文件中为Servlet设置两个虚拟路径,示例代码

        
        <servlet-mapping>
            <servlet-name>HelloServletservlet-name> 
            <url-pattern>/HelloServleturl-pattern> 
        servlet-mapping>
    
    	<servlet-mapping>
            <servlet-name>HelloServletservlet-name> 
            <url-pattern>/hellourl-pattern> 
        servlet-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    访问 /HelloServlet/hello 是一样的效果。

    或者是更加简短

        
        <servlet-mapping>
            <servlet-name>HelloServletservlet-name> 
            <url-pattern>/HelloServleturl-pattern> 
            <url-pattern>/hellourl-pattern> 
        servlet-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    多重映射还有一个通配符知识

    Servlet可以通过多重映射来处理多个不同的URL路径,这样可以将不同的请求分派到同一个Servlet或不同的Servlet上,以实现不同的处理逻辑。多重映射可以在一个Servlet应用中更灵活地处理各种请求。

    以下是一些关于Servlet多重映射的示例:

    1. 精确匹配:您可以使用精确匹配来指定Servlet处理特定的URL路径。例如:

      <servlet-mapping>
          <servlet-name>MyServletservlet-name>
          <url-pattern>/specific-pathurl-pattern>
      servlet-mapping>
      
      • 1
      • 2
      • 3
      • 4

      在这种情况下,Servlet “MyServlet” 仅会处理 “/specific-path” 路径的请求。

    2. 通配符匹配:您可以使用通配符来匹配一组URL。例如:

      <servlet-mapping>
          <servlet-name>MyServletservlet-name>
          <url-pattern>/products/*url-pattern>
      servlet-mapping>
      
      • 1
      • 2
      • 3
      • 4

      在这种情况下,Servlet “MyServlet” 将处理以 “/products/” 开头的所有路径,例如 “/products/item1”、“/products/item2” 等。

    3. 扩展名匹配:您可以使用扩展名匹配来匹配特定文件扩展名的URL。例如:

      <servlet-mapping>
          <servlet-name>ImageServletservlet-name>
          <url-pattern>*.jpgurl-pattern>
      servlet-mapping>
      
      • 1
      • 2
      • 3
      • 4

      在这种情况下,Servlet “ImageServlet” 将处理以 “.jpg” 结尾的所有URL,例如 “/images/pic1.jpg”、“/photos/photo.jpg” 等。

    4. 默认Servlet:在一些Servlet容器中,还有一个称为默认Servlet的特殊Servlet,它可以处理所有未匹配到其他Servlet的请求。这通常用于提供静态资源,如HTML文件、图像和CSS。

    使用多重映射,您可以根据具体的需求将不同的URL请求映射到不同的Servlet上,以实现不同的处理逻辑。这允许您构建更复杂的Web应用程序,可以处理多种不同类型的请求。配置多重映射通常是在Web应用程序的"web.xml"文件中完成的。优先级原则是 精确高于模糊,路径名高于扩展名,相似度高优先


    注解配置,这个就很简短了

    一般使用 "@WebServlet(name = " ", urlPatterns = {" /url "})",
    例如上一个还可以简写成 " @WebServlet("/FirstServlet")"


    还有一个是要自己配置Tomcat才行,这里就不讲了,我也是看别人教程写的。


    这里特别注意一下,以下每一个示例,我都没有贴上相应的配置文件,即web.xml 是缺失的,需要自己写或者看我上面那个如何配置的那个小点,当然如果是用注解配置的话,会一并附在代码之中,就无需单独配置文件了



    HttpServlet

    HttpServlet类的主要方法可以查看具体源码,主要是满足不同请求方式,当然还有 service 方法。

    演示一下 doGet 和 doPost 方法

    package com.hong.Servlet.HttpServlet;
    
    import jakarta.servlet.ServletException;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    
    import java.io.IOException;
    
    /**
     * @author WangYH
     * @version 2021.1.3
     * @date 2023/10/4 17:36
     */
    
    public class SecondServlet extends HttpServlet {
    
        /**
         * 构造方法直接调用父类的方法
         */
        public SecondServlet() {
            super();
        }
    
        /**
         *
         * @param request 接收一个HttpServletRequest对象(用于获取请求信息)
         * @param response 一个HttpServletResponse对象(用于生成响应)
         * @throws ServletException
         * @throws IOException
         *
         */
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=GB18030");
            //这一行设置响应的内容类型为"text/html;charset=GB18030",表示响应的内容将以HTML格式和GB18030字符编码发送给客户端。
            response.getWriter().write("少年强则国强:A strong youth makes a strong country");
            //这一行将文本消息,写入响应的输出流,以便将其发送给客户端浏览器。
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=GB18030");
            response.getWriter().write("大众创业,万众创新:Mass entrepreneurship and innovation");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    数据共享

    web.xml 文件传递消息,ServletConfig 接口 (配置)

    	<servlet>
            <servlet-name> FourthServlet servlet-name>
            <servlet-class>com.hong.Servlet.HttpServlet.FourthServletservlet-class>
    
            <init-param>
                <param-name>encodingparam-name>
                <param-value>GB18030param-value>
            init-param>
        servlet>
    
    	 <servlet-mapping>
            <servlet-name>FourthServletservlet-name>
            <url-pattern>/testurl-pattern>
        servlet-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    重写 doGet() 方法

    @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //解决中文乱码 req指的是请求
            req.setCharacterEncoding("UTF-8");
            //resp指的是响应
            resp.setContentType("text/html");
            resp.setCharacterEncoding("UTF-8");
    
            PrintWriter writer = resp.getWriter();
            //获取ServletConfig对象
            ServletConfig servletConfig = this.getServletConfig();
            //读取初始化参数encoding的值
            String encoding = servletConfig.getInitParameter("encoding");
            writer.print("参数encoding:"+encoding);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ServletContext (上下文)

    web.xml文件

    <context-param>
            <param-name> username param-name>
            <param-value> admin param-value>
        context-param>
        <context-param>
            <param-name>passwdparam-name>
            <param-value>1234param-value>
        context-param>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    还是重写 doGet 方法

    @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html; charset=GB18030");
            PrintWriter writer = resp.getWriter();
            ServletContext context = this.getServletContext();
            Enumeration<String> paramNames = context.getInitParameterNames();
            while (paramNames.hasMoreElements()){
                String name = paramNames.nextElement();
                String value = context.getInitParameter(name);
                writer.println(name + " : "+value);
                writer.println("
    "
    ); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    多个对象共享信息资源

    创建三个Java文件,重写1的 doGet 方法如下

     @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html;  charset=GB18030");
            PrintWriter writer = resp.getWriter();
            ServletContext context = this.getServletContext();
            context.setAttribute("name", "陆亦凡");
            context.setAttribute("sex","男");
            String name = (String) context.getAttribute("name");
            String sex = (String) context.getAttribute("sex");
    
            writer.println("获取的上下文的name:"+name + ";\n获取的上下文的sex:"+sex);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    重写2的 doGet 方法如下

    @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html;  charset=GB18030");
            PrintWriter writer = resp.getWriter();
            ServletContext context = this.getServletContext();
            context.setAttribute("name", "李萌萌");
            context.setAttribute("sex","女");
            String name = (String) context.getAttribute("name");
            String sex = (String) context.getAttribute("sex");
    
            writer.println("获取的上下文的name:"+name + ";\n获取的上下文的sex:"+sex);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    重写3的 doGet 方法如下

    @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html; charset=GB18030");
            PrintWriter writer = resp.getWriter();
            ServletContext context = this.getServletContext();
            String name = (String) context.getAttribute("name");
            String sex = (String) context.getAttribute("sex");
            writer.println("获取的上下文的name:"+name + ";\n获取的上下文的sex:"+sex);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    访问对应的虚拟路径可看到,3会和1或者2保持一致(这里取决谁把数据存入了),这是因为name和sex属性被多个对象共享了。


    读取properties文件信息内容

    这里创建好properties,随便填入一些信息

    username = admin;
    password = 123456;
    
    • 1
    • 2

    重写 doGet 方法如下

    @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html; charset=GB18030");
            ServletContext context = this.getServletContext();
            PrintWriter writer = resp.getWriter();
            InputStream in = context.getResourceAsStream("/WEB-INF/classes/servuser.properties");
            Properties properties = new Properties();
            properties.load(in);
            writer.println("获取的上下文的username:"+properties.getProperty("username"));
            writer.println("
    "
    ); writer.println("获取的上下文的password:"+properties.getProperty("password")); }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    嵌入式开源库之libmodbus学习笔记
    WebPack-打包工具
    基于ZXing.NET实现的二维码生成和识别客户端
    负载均衡的原理及其算法详解
    JVM中的STW(Stop The World)
    [ue5]建模场景学习笔记(6)——必修内容可交互的地形,交互沙(4)
    c语言内存函数
    毕业设计-论文写作笔记【毕设题目类型、论文写作细节、毕设资料】
    日志:Redo Log 和 Undo Log
    循环for处理数据
  • 原文地址:https://blog.csdn.net/weixin_63233998/article/details/133701138