2022年Servlect课时十六——Filter 与Servlect 的用法相似

简介: 2022年Servlect课时十六——Filter 与Servlect 的用法相似

第一部分观察下图Servlet与Filter的创建过程与生命周期

仔细观察下面图片过程

总结:从上面图片过程可以看出:当Servlect与Filter同时创建时,运行服务器首先调用的是Filter中。MyFilter():构造方法<<FilterConfig()方法:加载数据。当我改下内容在刷新时你会发现服务器运行以下方法

1 销毁数据

2 Filter所有方法运行完毕后销毁过滤器

3 构造方法

4 加载数据

5 我创建了第一个MyFilter过滤器

6 FilterConfig用来加载初始化数据

当我去运行ServlectA时服务器运行以下方法

1 ServlectA的构造方法

2 ServletAinit方法

3 ServlectA的servlect的方法

上面总结代码如下

创建如下图的项目

package co;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Servlet implementation class Servlect1
 */
@WebServlet("/Servlect1")
public class Servlect1 extends HttpServlet {
  private static final long serialVersionUID = 1L;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Servlect1() {
        super();
        // TODO Auto-generated constructor stub
    }
  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    //response.getWriter().append("Served at: ").append(request.getContextPath());
  PrintWriter pw =response.getWriter();
  pw.print("<h1>我是第一个servlect</h1>");
  }
  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }
}
package co;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Servlet implementation class Servlect2
 */
@WebServlet("/Servlect2")
public class Servlect2 extends HttpServlet {
  private static final long serialVersionUID = 1L;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Servlect2() {
        super();
        // TODO Auto-generated constructor stub
    }
  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
  //response.getWriter().append("Served at: ").append(request.getContextPath());
    response.setContentType("text/html");
    response.setCharacterEncoding("UTF-8");
    PrintWriter pw =response.getWriter();
    pw.print("<h1>我是第一个servlect2</h1>");
  }
  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }
}
package co;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Servlet implementation class Servlect3
 */
@WebServlet("/Servlect3")
public class Servlect3 extends HttpServlet {
  private static final long serialVersionUID = 1L;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Servlect3() {
        super();
        // TODO Auto-generated constructor stub
    }
  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    //response.getWriter().append("Served at: ").append(request.getContextPath());
    response.setContentType("text/html");
    response.setCharacterEncoding("UTF-8");
    PrintWriter pw =response.getWriter();
    pw.print("<h1>我是第一个servlect3</h1>");
  }
  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }
}
package co;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Servlet implementation class Servlect3
 */
@WebServlet("/Servlect3")
public class Servlect3 extends HttpServlet {
  private static final long serialVersionUID = 1L;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Servlect3() {
        super();
        // TODO Auto-generated constructor stub
    }
  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    //response.getWriter().append("Served at: ").append(request.getContextPath());
    response.setContentType("text/html");
    response.setCharacterEncoding("UTF-8");
    PrintWriter pw =response.getWriter();
    pw.print("<h1>我是第一个servlect3</h1>");
  }
  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }
}
package co;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ServlectA  implements Servlet{
  public ServlectA() {
    // TODO Auto-generated constructor stub
    System.out.println("ServlectA的构造方法");
  }
  @Override
  public void destroy() {
    // TODO Auto-generated method stub
    System.out.println("运行完毕后销毁ServlectA");
  }
  @Override
  public ServletConfig getServletConfig() {
    // TODO Auto-generated method stub
    System.out.println("ServlectA ServletConfig方法");
    return null;
  }
  @Override
  public String getServletInfo() {
    // TODO Auto-generated method stub
    System.out.println(" ServletAgetServletInfo方法");
    return null;
  }
  @Override
  public void init(ServletConfig config) throws ServletException {
    // TODO Auto-generated method stub
    System.out.println("ServletAinit方法");
  }
  @Override
  public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    // TODO Auto-generated method stub
    System.out.println("ServlectA的servlect的方法");
  }
}
package com;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
 * Servlet Filter implementation class MyFilter1
 */
@WebFilter("/Servlect2")
public class MyFilter1 implements Filter {
    /**
     * Default constructor. 
     */
    public MyFilter1() {
        // TODO Auto-generated constructor stub
      System.out.println("构造方法");
    }
  /**
   * @see Filter#destroy()
   */
  public void destroy() {
    // TODO Auto-generated method stub
    System.out.println("销毁数据");
  }
  /**
   * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
   */
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    response.setContentType("text/html");
    response.setCharacterEncoding("UTF-8");
    System.out.println("我是myfilter1开始拦截请求地址哦哦");
    //实施访问
    chain.doFilter(request, response);
  }
  /**
   * @see Filter#init(FilterConfig)
   */
  public void init(FilterConfig fConfig) throws ServletException {
    // TODO Auto-generated method stub
    System.out.println("加载数据");
  }
}
package com;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
 * Servlet Filter implementation class MyFilter2
 */
@WebFilter("/Servlect2")
public class MyFilter2 implements Filter {
    /**
     * Default constructor. 
     */
    public MyFilter2() {
        // TODO Auto-generated constructor stub
    }
  /**
   * @see Filter#destroy()
   */
  public void destroy() {
    // TODO Auto-generated method stub
  }
  /**
   * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
   */
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    // TODO Auto-generated method stub
    // place your code here
    response.setContentType("text/html");
    response.setCharacterEncoding("UTF-8");
    System.out.println("我是myfilter2开始拦截请求地址哦哦");
    //实施访问
    chain.doFilter(request, response);
  }
  /**
   * @see Filter#init(FilterConfig)
   */
  public void init(FilterConfig fConfig) throws ServletException {
    // TODO Auto-generated method stub
  }
}
package com;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
 * Servlet Filter implementation class MyFilter3
 */
@WebFilter("/Servlect2")
public class MyFilter3 implements Filter {
    /**
     * Default constructor. 
     */
    public MyFilter3() {
        // TODO Auto-generated constructor stub
    }
  /**
   * @see Filter#destroy()
   */
  public void destroy() {
    // TODO Auto-generated method stub
  }
  /**
   * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
   */
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    // TODO Auto-generated method stub
    // place your code here
    response.setContentType("text/html");
    response.setCharacterEncoding("UTF-8");
    System.out.println("我是myfilter3开始拦截请求地址哦哦");
    //实施访问
    chain.doFilter(request, response);
  }
  /**
   * @see Filter#init(FilterConfig)
   */
  public void init(FilterConfig fConfig) throws ServletException {
    // TODO Auto-generated method stub
  }
}

第二部分观察Servlect与Filter在web.xml注册的相似

请看以下图片仔细观察

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>Day010.jsp</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <!-- <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file> -->
  </welcome-file-list>
  <!-- 第一部分·注册过滤器 -->
 <filter>
 <filter-name>MyFilter</filter-name>
 <filter-class>com.MyFilter</filter-class>
 <init-param>
 <param-name>username</param-name>
 <param-value>student</param-value>
 </init-param>
 <init-param>
 <param-name>password</param-name>
 <param-value>666666</param-value>
 </init-param>
 </filter>
 <filter-mapping>
    <filter-name>MyFilter</filter-name>
    <!-- 这表示可以拦截任何请求 -->
    <url-pattern>/Servlect1</url-pattern>
  </filter-mapping>
 <servlet>
 <servlet-name>ServlectA</servlet-name>
 <servlet-class>co.ServlectA</servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet-name>ServlectA</servlet-name>
 <url-pattern>/ServlectA</url-pattern>
 </servlet-mapping>
</web-app>

第三部分了解三个类名DisplayHeader Refresh showError

看以下结果

代码

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>ADay03</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>  
    <!-- 类名 -->  
    <servlet-name>DisplayHeader</servlet-name>  
    <!-- 所在的包 -->  
    <servlet-class>com.runoob.test.DisplayHeader</servlet-class>  
  </servlet>  
  <servlet-mapping>  
    <servlet-name>DisplayHeader</servlet-name>  
    <!-- 访问的网址 -->  
    <url-pattern>/TomcatTest/DisplayHeader</url-pattern>  
  </servlet-mapping> 
  <!-- ************************************************************* -->
  <servlet>  
     <!-- 类名 -->  
    <servlet-name>Refresh</servlet-name>  
    <!-- 所在的包 -->  
    <servlet-class>com.runoob.test.Refresh</servlet-class>  
  </servlet>  
  <servlet-mapping>  
    <servlet-name>Refresh</servlet-name>  
    <!-- 访问的网址 -->  
    <url-pattern>/TomcatTest/Refresh</url-pattern>  
    </servlet-mapping>   
    <!-- ================================================================= -->
     <filter>
    <filter-name>helloFilter</filter-name>
    <filter-class>com.ys.filter.HelloFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>helloFilter</filter-name>
    <url-pattern>/*</url-pattern><!-- 这表示可以拦截任何请求 -->
  </filter-mapping>
</web-app>
package com.runoob.test;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
 * 下面的实例使用 HttpServletRequest 的 getHeaderNames() 方法读取 HTTP
 *  头信息。该方法返回一个枚举,
 * 包含与当前的 HTTP 请求相关的头信息。
一旦我们有一个枚举,我们可以以标准方式循环枚举,
使用 hasMoreElements() 方法来确定何时停止,使用 nextElement() 方法来获取每个参数的名称。
 */
/**
 * Servlet implementation class DisplayHeader
 */
@WebServlet("/DisplayHeader")
public class DisplayHeader extends HttpServlet {
  private static final long serialVersionUID = 1L;
    /**
     * Default constructor. 
     */
    public DisplayHeader() {
        // TODO Auto-generated constructor stub
      System.out.println("1111111111111111111");
    }
  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    /*
     * response.getWriter().append("Served at: ").append(request.getContextPath());
     */
     // 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String title = "HTTP Header 一起来学服务器 go go go  com on";
        String docType =
            "<!DOCTYPE html> \n";
            out.println(docType +
            "<html>\n" +
            "<head><meta charset=\"utf-8\"><title>" + title + "</title></head>\n"+
            "<body bgcolor=\"pink\">\n" +
            "<h2 align=\"center\">" + title + "</h2>\n" +
            "<table width=\"80%\" border=\"5\" align=\"center\">\n" +
            "<tr bgcolor=\"yellow\">\n" +
            "<th>Header 名称</th><th>Header 值</th>\n"+
            "</tr>\n");
        Enumeration headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String paramName = (String)headerNames.nextElement();
            out.print("<tr><td>" + paramName + "</td>\n");
            String paramValue = request.getHeader(paramName);
            out.println("<td> " + paramValue + "</td></tr>\n");
        }
        out.println("</table>\n</body></html>");
    }
  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }
}
package com.runoob.test;
//导入必需的 java 库
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/Refresh")
//扩展 HttpServlet 类
public class Refresh extends HttpServlet {
    // 处理 GET 方法请求的方法
      public void doGet(HttpServletRequest request,
                        HttpServletResponse response)
                throws ServletException, IOException
      {
          // 设置刷新自动加载时间为 5 秒
          response.setIntHeader("Refresh", 5);
          // 设置响应内容类型
          response.setContentType("text/html;charset=UTF-8");
          //使用默认时区和语言环境获得一个日历  
          Calendar cale = Calendar.getInstance();  
          //将Calendar类型转换成Date类型  
          Date tasktime=cale.getTime();  
          //设置日期输出的格式  
          SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
          //格式化输出  
          String nowTime = df.format(tasktime);
          PrintWriter out = response.getWriter();
          String title = "自动刷新 Header hellow world like you";
          String docType =
          "<!DOCTYPE html>\n";
          out.println(docType +
            "<html>\n" +
            "<head><title>" + title + "</title></head>\n"+
            "<body bgcolor=\"pink\">\n" +
            "<h2 align=\"center\">" + title + "</h1>\n" +
            "<p>当前时间是:" + nowTime + "</p>\n");
      }
      // 处理 POST 方法请求的方法
      public void doPost(HttpServletRequest request,
                         HttpServletResponse response)
          throws ServletException, IOException {
         doGet(request, response);
      }
}
package com.runoob.test;
/*
 * 初始状态行 + 回车换行符(回车+换行)
零个或多个标题行+回车换行符
一个空白行,即回车换行符
一个可选的消息主体,比如文件、查询数据或查询输出
 */
// 导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import javax.servlet.annotation.WebServlet;
@WebServlet("/showError")
// 扩展 HttpServlet 类
public class showError extends HttpServlet {
  // 处理 GET 方法请求的方法
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException
  {
      // 设置错误代码和原因
      response.sendError(407, "Need authentication!!!" );
  }
  // 处理 POST 方法请求的方法
  public void doPost(HttpServletRequest request,
                     HttpServletResponse response)
      throws ServletException, IOException {
     doGet(request, response);
  }
}
package com.ys.filter;
 /**
  * 总结:生命周期和 Servlet 的类似。只不过其构造方法和初始
  化方法是在容器启动时就调用了,
  * 而其 doFilter() 方法则是在每次请求的时候调用。故过滤器可以对请求进行拦截过滤。
  * 可以用来进行权限设置,对传输数据进行加密等等操作。
  */
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloFilter implements Filter{
    public HelloFilter() {
        System.out.println("构造器 HelloFilter()...");
        System.out.println("构造器 HelloFilter()...asd");
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init()...");
        System.out.println("hellow world 11");
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("doFilter()...");
        System.out.println("hellow world 12");
    }
    @Override
    public void destroy() {
        System.out.println("destroy()...");
        System.out.println("hellow world 13");
    }
}

今天学的内容

什么是过滤器?

Filter也称之为过滤器

     

过滤器本质上就是一个特殊的类

通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。

Servlet过滤器负责过滤的web组件有servlet、JSP或者是HTML文件

一个过滤器想要拦截多个不同的访问地址的时候,过滤器的拦截地址只要设置为/*

多个过滤器想要拦截一个访问地址,这里需要将多个过滤器的拦截地址设置为同一个

那么当多个过滤器拦截访问地址的时候,先被谁拦截?

1.如果多个过滤器都是使用web.xml文件的方式注册的,哪个过滤器先被注册就会先被哪个过滤器拦截

2.如果多个过滤器都是使用java注解的方式注册的,这些过滤器会按照类的名称进行排序访问


相关文章
|
10月前
|
存储 Java 对象存储
2022年Servlect课时十七——什么是监听器@@回顾过滤器@@Servlect(一)
2022年Servlect课时十七——什么是监听器@@回顾过滤器@@Servlect(一)
36 0
|
10月前
2022年Servlect课时十七——什么是监听器@@回顾过滤器@@Servlect(二)
2022年Servlect课时十七——什么是监听器@@回顾过滤器@@Servlect(二)
25 0
2022年Servlect课时十五——Servlect 56天的学习总结。(一)
2022年Servlect课时十五——Servlect 56天的学习总结。
72 0
|
存储
2022年Servlect课时十五——Servlect 56天的学习总结。(二)
2022年Servlect课时十五——Servlect 56天的学习总结。
91 0
|
Java 应用服务中间件 容器
2022年Servlect课时六——:案例 servlet的常用对象
2022年Servlect课时六——:案例 servlet的常用对象
80 0
2022年Servlect课时六——:案例 servlet的常用对象
|
Java
2022年Jsp课时十二——回顾 Servlect的一些内容(二)
2022年Jsp课时十二——回顾 Servlect的一些内容
53 0
2022年Jsp课时十二——回顾 Servlect的一些内容(二)
|
Java 容器
2022年Jsp课时十二——回顾 Servlect的一些内容(一)
2022年Jsp课时十二——回顾 Servlect的一些内容
48 0
2022年Jsp课时十二——回顾 Servlect的一些内容(一)
|
Java
2022年Jsp课程课时八——案例(Servlect常用对象)
2022年Jsp课程课时八——案例(Servlect常用对象)
58 0
2022年Jsp课程课时八——案例(Servlect常用对象)
2022年课时十——两个小项目实战(Servlect常用对象)
2022年课时十——两个小项目实战(Servlect常用对象)
61 0
2022年课时十——两个小项目实战(Servlect常用对象)
|
网络协议 Java
2022年课时一:Servlect
2022年课时一:Servlect
58 0
2022年课时一:Servlect