(web后端)02_Servlet

一、初识Servlet

1.Servlet简介

在这里插入图片描述
Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:

  1、编写一个Java类,实现servlet接口。
  2、把开发好的Java类部署到web服务器中

Java Servlet是和平台无关的服务器端组件,它运行在Servlet容器中。Servlet容器负责Servlet和客户的通信以及调用Servlet的方法 ,Servlet和客户的通信采用“请求/响应”的模式。Servlet可完成如下功能:

  1. 创建并返回基于客户请求的动态HTML页面。
  2. 创建可嵌入到现有HTML 页面中的部分HTML 页面(HTML 片段)。
  3. 与其它服务器资源(如数据库或基于Java的应用程序)进行通信。

Servlet容器响应客户请求的过程
在这里插入图片描述
Servlet,filter,listener统称为JavaWeb的三大组件,它属于动态资源。Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:

接收请求数据;
处理请求;
完成响应

实现Servlet有三种方式:

实现javax.servlet.Servlet接口;
继承javax.servlet.GenericServlet类;
继承javax.servlet.http.HttpServlet类;

通常我们会去继承HttpServlet类来完成我们的Servlet,但学习Servlet还要javax.servlet.Servlet接口开始学习。

二、Servlet初探

接下来我们开始准备完成Servlet,完成Servlet需要分为两步:

  1. 编写Servlet类;
  2. 在web.xml文件中配置Servlet;
    ①编写Servlet类:
//开发一个Serlvet  实现Serlvet接口
public class HelloServlet  implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init。。。。。。。");
    }

    @Override
    public ServletConfig getServletConfig() {
        System.out.println("get Servlet config。。。。");
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service。。。。。。");
    }

    @Override
    public String getServletInfo() {
        System.out.println("servlet info。。。。。");
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("destory。。。。。");
    }
}

②配置Serlvet

<?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-name>helloSerlvet</servlet-name>
<!--        指定要配置的servlet是哪一个具体的serlvet  此处需要使用全类名-->
        <servlet-class>org.lanqiao.web.HelloServlet</servlet-class>
    </servlet>
<!--    配置serlvet映射-->
    <servlet-mapping>
<!--        映射的servlet的名称 需要对应上边的serlvet-name-->
        <servlet-name>helloSerlvet</servlet-name>
<!--        serlvet请求规则-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

在web.xml中配置Servlet的目的其实只有一个,就是把访问路径与一个Servlet绑定到一起,上面配置是把访问路径:“/hello”与“org.lanqiao.javaweb.HelloServlet”绑定到一起。

  1. < servlet>:指定HelloServlet这个Servlet的名称为hello;
  2. < servlet-mapping>:指定/hello访问路径所以访问的Servlet名为hello。
    < servlet >和< servlet-mapping >通过< servlet-name >这个元素关联在一起了!

请求的过程: tomcat
localhost:8080/
tomcat中 /默认会请求servlet中的一个默认的defaultServlet
执行到welcome-file-list

1.url-pattern常用的配置方法:

/:表示项目的根路径
/
是通配符 无论后边是什么都无所谓 都可以匹配的到 * 0-N个字符
多级路径配置:

<!--    配置serlvet映射-->
    <servlet-mapping>
<!--        映射的servlet的名称 需要对应上边的serlvet-name-->
        <servlet-name>helloSerlvet</servlet-name>
<!--        serlvet请求规则-->
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>

使用扩展名配置:

<!--    配置serlvet映射-->
    <servlet-mapping>
<!--        映射的色弱略同的名称 需要对应上边的serlvet-name-->
        <servlet-name>helloSerlvet</servlet-name>
<!--        serlvet请求规则-->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

常用的 扩展名 .do .action

三、Sevlet的生命周期:

  1. init :表示servlet的初始化 执行一次
  2. service:servlet的服务方法 是处理请求的 每一次请求都会执行service方法
  3. destroy:销毁(死亡) 执行一次 serlvet从serlvet容器中卸载的时候 才会执行

init方法表示servlet的创建:
创建时机可控:

  1. 默认情况下 是当第一次请求servlet的时候 才会执行该init 方法 创建servlet

< load-on-startup>< /load-on-startup>

  1. 该参数>=0 则表示该serlvet随着容器的启动而完成初始化
    数字越小 初始化时机越早
  2. 当参数<0 则servelt的初始化时机为第一次请求时
    此时初始话的时机 与数字大小无关 与请求顺序有关

每个Serlvet在整个声明周期中 有几个实例对象:
A 只有一个(用构造器可明显看出)
B 每次都会产生一个新的

四、HttpServlet

Servlet ---接口
   GenericServlet---抽象类  ---service
      HttpServlet --- 抽象类  ---无抽象方法 该类提供了对Http协议的支持

在开发中 sevlet的实现 采用继承HttpSerlvet,并重写doGet和doPost

public class HttpServletDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //请求处理的核心代码
        System.out.println("请求处理。。。。。");
    }
}

五、Servlet API

1.ServletConfig

  1. ServletConfig:init()方法的参数,它表示Servlet配置对象,它对应Servlet的配置信息,对应web.xml文件中的< servlet>元素。
  2. String getServletName():获取Servlet在web.xml文件中的配置名称,即< servlet-name>指定的名称;
  3. Enumeration getInitParameterNames():用来获取在web.xml中配置的所有初始化参数名称;
  4. String getInitParameter(String name):用来获取在web.xml中配置的初始化参数,通过参数名来获取参数值;
  5. ServletContext getServletContext():用来获取ServletContext对象

xml配置文件:

<servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>org.lanqiao.web.HelloServlet</servlet-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>user</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>123456</param-value>
        </init-param>
        <load-on-startup>10</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

servlet类:

@Override
    public void init(ServletConfig servletConfig) throws ServletException {
//        获取web.xml中配置的该sevelt的        <servlet-name>helloSerlvet</servlet-name>的值
       String servletName =  servletConfig.getServletName();
        System.out.println("servletName:---"+servletName);
//        获取该sevlet中所有的 初始化参数的名称
        Enumeration<String> names =  servletConfig.getInitParameterNames();
        while(names.hasMoreElements()){
            System.out.println("parameterName ="+names.nextElement());
        }
        //获取初始化参数的对应的值
      String  username  =   servletConfig.getInitParameter("username");
        System.out.println(username);
        String password  = servletConfig.getInitParameter("password");
        System.out.println(password);
    }

2.ServletContext

2.1.ServletContext概述

服务器会为每个应用创建一个ServletContext对象:

  1. ServletContext对象的创建是在服务器启动时完成的;
  2. ServletContext对象的销毁是在服务器关闭时完成的。
  3. ServletContext对象的作用是在整个Web应用的动态资源之间共享数据!例如在AServlet中向
  4. ServletContext对象中保存一个值,然后在BServlet中就可以获取这个值,这就是共享数据了。
  5. Servlet引擎为每个WEB应用程序都创建一个对应的ServletContext对象,ServletContext对象被包含在ServletConfig对象中,调用ServletConfig.getServletContext方法可以返回ServletContext对象的引用。
  6. 由于一个WEB应用程序中的所有Servlet都共享同一个ServletContext对象,所以,ServletContext对象被称之为 application 对象(Web应用程序对象)。
  7. 功能:
    ①获取WEB应用程序的初始化参数
    ②记录日志
    ③application域范围的属性
    ④访问资源文件
    ⑤WEB应用程序之间的访问

2.2.获取ServletContext

ServletConfig#getServletContext();
GenericServlet#getServletContext();
HttpSession#getServletContext()
ServletContextEvent#getServletContext()
 ServletContext application = servletConfig.getServletContext();
 //获取初始化参数
String  name =  application.getInitParameter("name");
String age = application.getInitParameter("age");
 System.out.println(name+"---"+age);

web.xml配置文件

<!--    ServletContext的初始化参数  可以被所有的servelt 所共享   -->
    <context-param>
        <param-name>name</param-name>
        <param-value>jack</param-value>
    </context-param>
    <context-param>
        <param-name>age</param-name>
        <param-value>23</param-value>
    </context-param>
    
 

2.3.域对象的功能

ServletContext是JavaWeb四大域对象之一:

PageContext;
ServletRequest;
HttpSession;
ServletContext

所有域对象都有存取数据的功能,因为域对象内部有一个Map,用来存储数据,下面是ServletContext对象用来操作数据的方法:

  1. void setAttribute(String name, Object value): 用来存储一个对象,也可以称之为存储一个域属性,例如:servletContext.setAttribute(“xxx”, “XXX”),在ServletContext中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。请注意,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同;
  2. Object getAttribute(String name): 用来获取ServletContext中的数据,当前在获取之前需要先去存储才行,例如:String value = (String)servletContext.getAttribute(“xxx”);,获取名为xxx的域属性;
  3. void removeAttribute(String name): 用来移除ServletContext中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做;
  4. Enumeration getAttributeNames(): 获取所有域属性的名称;
servletContext.setAttribute("schoolname","中北大学");
String schoolname = (String) servletContext.getAttribute("schoolname");
System.out.println("schoolname="+schoolname);

小结:

  1. Servlet的生命周期
    init(ServletConfig config) 创建并初始化servlet
    load-on-startup
    参数 >= 0 随着servelt的装载而进行初始化 数字越小 初始化越早
    <0 则是在第一次请求时进行初始化
    service(ServletRequest req ,ServletResponse resp)
    serlvet的接受请求并处理请求 返回响应
    destroy(); 销毁 当servlet从容器中卸载时 执行 后续的清理工作

  2. Servlet的核心API
    ServletConfig 封装了当前servlet的配置信息
    ServletContext 代表整个web应用的全部信息 可以实现servelt之间的数据共享

  3. 四大域对象:
    pageContext
    ServletRequst
    HttpSession
    ServletContext

域对象的公有方法:

 setAttribute(String key ,Object value);
 getAttribute(String key);
 removeAttribute(String key);

练习:
servlet类:

public class servletDemo1 extends HttpServlet {
    //重写doGet和doPost
    //doGet只能接受get请求 doPost只能接受post请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //编写核心业务代码
        //获取servletconfig对象 通过servletconfig获取相关的配置信息
        ServletConfig config = this.getServletConfig();
        String name = config.getServletName();
        String username = config.getInitParameter("username");
        System.out.println(name +"------"+username);
        //获取servletcontext对象
        ServletContext context = req.getServletContext();
        String app = context.getInitParameter("app");
        System.out.println("app:"+app);

        context.setAttribute("schoolname","中北大学");
        String schoolname = (String) context.getAttribute("schoolname");
        System.out.println("schoolname :"+schoolname);
    }

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

}

xml配置:

<context-param>
        <param-name>app</param-name>
        <param-value>javeEE</param-value>
    </context-param>
    <servlet>
        <servlet-name>demo1</servlet-name>
        <servlet-class>org.lanqiao.web.servletDemo1</servlet-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>tom</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo1</servlet-name>
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>

练习:统计当前访问应用的用户数量

  //需求:统计当前访问应用的用户数量
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //编写核心业务代码
        //获取servletconfig对象 通过servletconfig获取相关的配置信息
       ServletContext application = req.getServletContext();
        Integer online_num = (Integer) application.getAttribute("online_num");
        if (online_num == null){
            online_num = 1;
        }else {
            online_num++;
        }
        application.setAttribute("online_num",online_num);
        System.out.println("你是访问该应用的第"+online_num+"的用户");


    }

3.Request

3.1.request概述

request是Servlet.service()方法的一个参数,类型为javax.servlet.http.HttpServletRequest。在客户端发出每个请求时,服务器都会创建一个request对象,并把请求数据封装到request中,然后在调用Servlet.service()方法时传递给service()方法,这说明在service()方法中可以通过request对象来获取请求数据。

3.2谁可以发送请求:

HttpServletRequest 接受请求的

  1. 通过浏览器的地址栏发送请求 可以发送get请求
  2. 超链接发送请求 请求的地址href 只能发送get请求
  3. form表单 可以通过action来发送请求 不仅可以发送get请求还可以发送post请求 根据method属性来指定请求的方式
    在这里插入图片描述
    get的参数传递是通过路径后?参数名=参数值&参数名=参数值
    post的参数通过请求体来传递参数的
    发送get请求

http://localhost:8080/demo1?username=admin

3.3.request相关的其它方法

  1. int getContentLength():获取请求体的字节数,GET请求没有请求体,没有请求体返回-1;
  2. String getContentType():获取请求类型,如果请求是GET,那么这个方法返回null;如果是POST请求,那么默认为application/x-www-form-urlencoded,表示请求体内容使用了URL编码;
  3. String getMethod():返回请求方法,例如:GET
  4. Locale getLocale():返回当前客户端浏览器的Locale。java.util.Locale表示国家和言语,这个东西在国际化中很有用;
  5. String getCharacterEncoding():获取请求编码,如果没有setCharacterEncoding(),那么返回null,表示使用ISO-8859-1编码;
  6. void setCharacterEncoding(String code):设置请求编码,只对请求体有效!注意,对于GET而言,没有请求体!!!所以此方法只能对POST请求中的参数有效!
  7. String getContextPath():返回上下文路径,例如:/hello
  8. String getQueryString():返回请求URL中的参数,例如:name=zhangSan
  9. String getRequestURI():返回请求URI路径,例如:/hello/oneServlet
  10. StringBuffer getRequestURL():返回请求URL路径,例如:http://localhost/hello/oneServlet,即返回除了参数以外的路径信息;
  11. String getServletPath():返回Servlet路径,例如:/oneServlet
  12. String getRemoteAddr():返回当前客户端的IP地址;
  13. String getRemoteHost():返回当前客户端的主机名,但这个方法的实现还是获取IP地址;
  14. String getScheme():返回请求协议,例如:http;
  15. String getServerName():返回主机名,例如:localhost
  16. int getServerPort():返回服务器端口号,例如:8080
    在这里插入图片描述
 System.out.println("request.getContentLength(): " + request.getContentLength());
  System.out.println("request.getContentType(): " + request.getContentType());
  System.out.println("request.getContextPath(): " + request.getContextPath());
  System.out.println("request.getMethod(): " + request.getMethod());
  System.out.println("request.getLocale(): " + request.getLocale());
     
  System.out.println("request.getQueryString(): " + request.getQueryString());
  System.out.println("request.getRequestURI(): " + request.getRequestURI());
  System.out.println("request.getRequestURL(): " + request.getRequestURL());
  System.out.println("request.getServletPath(): " + request.getServletPath());
  System.out.println("request.getRemoteAddr(): " + request.getRemoteAddr());
  System.out.println("request.getRemoteHost(): " + request.getRemoteHost());
  System.out.println("request.getRemotePort(): " + request.getRemotePort());
  System.out.println("request.getScheme(): " + request.getScheme());
  System.out.println("request.getServerName(): " + request.getServerName());
  System.out.println("request.getServerPort(): " + request.getServerPort());

在这里插入图片描述

3.4.request获取请求参数

最为常见的客户端传递参数方式有三种:

浏览器地址栏直接输入:一定是GET请求;
超链接:一定是GET请求;
表单:可以是GET,也可以是POST,这取决与<form>的method属性值;

GET请求和POST请求的区别:
GET请求和POST请求的区别:

  1. GET请求:
    ①请求参数会在浏览器的地址栏中显示,所以不安全;
    ②请求参数长度限制长度在1K之内;
    ③GET请求没有请求体,无法通过request.setCharacterEncoding()来设置参数的编码;
  2. POST请求:

①请求参数不会显示浏览器的地址栏,相对安全;
②请求参数长度没有限制;
在这里插入图片描述

3.5.中文乱码

解决post请求的中文乱码:
方式一:采用解码编码的方式来解决

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String username = req.getParameter("username");
    //对获取到的数据进行节码 得到字节数组
    byte[] usernameBytes = username.getBytes("iso-8859-1");
    // 使用新的字符集重新编码
    String name = new String(usernameBytes,"UTF-8");
    System.out.println(name);
    String key = req.getParameter("key");
    System.out.println(key);
}

方式二:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //设定接收请求所采用的字符集
    req.setCharacterEncoding("utf-8");
    String username = req.getParameter("username");
    System.out.println(username);
    String key = req.getParameter("key");
    System.out.println(key);
}

Get
通用解决方式:
配置tomcat的字符集 conf/serve.xml

  <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"  URIEncoding="UTF-8"/>

4.response

response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse。在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作。
response对象的功能分为以下四种:

设置响应头信息;
发送状态码;
设置响应正文;
重定向;

4.1.response响应正文

response是响应对象,向客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共提供了两个响应流对象:

PrintWriter out = response.getWriter():获取字符流;
ServletOutputStream out = response.getOutputStream():获取字节流;

当然,如果响应正文内容为字符,那么使用response.getWriter(),如果响应内容是字节,例如下载时,那么可以使用response.getOutputStream()。
注意,在一个请求中,不能同时使用这两个流!也就是说,要么你使用repsonse.getWriter(),要么使用response.getOutputStream(),但不能同时使用这两个流。不然会抛出IllegalStateException异常。
字符响应流
字符编码
在使用response.getWriter()时需要注意默认字符编码为ISO-8859-1,如果希望设置字符流的字符编码为utf-8,可以使用response.setCharaceterEncoding(“utf-8”)来设置。这样可以保证输出给客户端的字符都是使用UTF-8编码的!
但客户端浏览器并不知道响应数据是什么编码的!如果希望通知客户端使用UTF-8来解读响应数据,那么还是使用response.setContentType(“text/html;charset=utf-8”)方法比较好,因为这个方法不只会调用response.setCharaceterEncoding(“utf-8”),还会设置content-type响应头,客户端浏览器会使用content-type头来解读响应数据。
缓冲区
response.getWriter()是PrintWriter类型,所以它有缓冲区,缓冲区的默认大小为8KB。也就是说,在响应数据没有输出8KB之前,数据都是存放在缓冲区中,而不会立刻发送到客户端。当Servlet执行结束后,服务器才会去刷新流,使缓冲区中的数据发送到客户端。
如果希望响应数据马上发送给客户端:

向流中写入大于8KB的数据;
调用response.flushBuffer()方法来手动刷新缓冲区;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String username = req.getParameter("username");
        //使用response相应客户端 常用来:设置响应头 设置响应体
        //设置响应 内容类型
        //resp.setCharacterEncoding("UTF-8");
        //设置响应的字符集
        //resp.setContentType("text/html");
        System.out.println(username);
        //合法并写
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html lang=\"en\">");
        out.println("<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>欢迎页</title>\n" +
                "</head>");
        out.println("<body>");
        out.println("欢迎"+username);
        out.println("</body>");
        resp.flushBuffer();//刷新缓冲区
         }

4.2.设置响应头信息(了解)

可以使用response对象的setHeader()方法来设置响应头!使用该方法设置的响应头最终会发送给客户端浏览器!

  1. response.setHeader(“content-type”, “text/html;charset=utf-8”):设置content-type响应头,该头的作用是告诉浏览器响应内容为html类型,编码为utf-8。而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”);
  2. response.setHeader(“Refresh”,“5; URL=http://www.baidu.com”):5秒后自动跳转到百度主页

4.3.设置状态码及其他方法(了解)

  1. response.setContentType(“text/html;charset=utf-8”):等同与调用response.setHeader(“content-type”, “text/html;charset=utf-8”);
  2. response.setCharacterEncoding(“utf-8”):设置字符响应流的字符编码为utf-8;
  3. response.setStatus(200):设置状态码;
  4. response.sendError(404, “您要查找的资源不存在”):当发送错误状态码时,Tomcat会跳转到固定的错误页面去,但可以显示错误信息。

4.4.请求转发和重定向

4.4.1.请求转发:

1 浏览器向服务器端只发送了一次请求
2 浏览器的地址栏不会发生变化
3 不能转发到外部资源 只能转发内部资源
4 所以转发整个的过程都是一个请求 此时的request域的数据是可以在转发的servlet之间共享的 对于转发的serlvet来说是同一个请求
5 转发不仅可以转发到一个servlet 也可以转发到一个页面
路径前边 的第一个/表示根路径 就是我们项目结构中的web目录

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //请求转发
        //req.getRequestDispatcher("/demo2").forward(req,resp);
        //req.getRequestDispatcher("/WEB-INF/success.html").forward(req,resp);
        req.getRequestDispatcher("home.html").forward(req,resp);
         }

在这里插入图片描述

4.4.2.重定向

  1. 重定向向服务器端发送了两次请求 第一次请求可以是get也可以是post 但是第二次请求肯定是get
  2. 重定向时 地址栏会发生变化 显示重定向的地址
  3. 可以重定向到外部资源 可以重定向到内部资源
  4. 在整个请求 中发生了两次请求 产生了两个request对象 不能实现数据共享
  5. 也可以重定向到页面 和serlvet
 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //重定向
        //resp.sendRedirect("http://www.baidu.com");
        //resp.sendRedirect("/demo2");
        resp.sendRedirect("/home.html");
         }

在这里插入图片描述

4.4.3.转发和重定向的使用的选择:

不同servlet之间的调用  使用转发 
如果要跳转页面 则使用重定向	
发布了67 篇原创文章 · 获赞 6 · 访问量 1915

猜你喜欢

转载自blog.csdn.net/weixin_45801537/article/details/104782028
今日推荐