JavaWeb Servlet超詳細講解(附帶原理)Day04

JavaWeb Servlet

1 Servlet簡介

  • Servlet就是Sun公司開發動態web的一門技術
  • Sun在這些API中提供一個藉口叫做:Servlet,如果你想開發一個Servlet程序,只需要完成以下兩個步驟:
    • 編寫一個類,實現Servlet接口
    • 把開發好的java類部署到web服務器中

把實現了Servlet接口的Java程序叫做:Servlet

2 HelloServlet

Servlet接口Sun公司有兩個默認的實現類:HttpServlet、 GenericServlet

  1. 構建一個搭載了webapp的Maven項目,以後我們的學習就在這個項目裏面建立Moudel;這個空的工程就是Maven主工程。構建過程可以查看我的另一篇博客:點擊跳轉

    構建完成後,在pom.xml文件中的<dependencies></dependencies>中添加以下代碼,導入servlet的依賴。

    <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>4.0.1</version>
          <scope>provided</scope>
        </dependency>
    
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>javax.servlet.jsp-api</artifactId>
          <version>2.3.3</version>
          <scope>provided</scope>
        </dependency>
    
  2. 關於Maven父子工程的理解:

    父項目中會有

    <modules>
      <module>servlet-01</module>
    </modules>
    

    子項目中會有

    <parent>
      <artifactId>javaweb-02-servlet</artifactId>
      <groupId>com.demut</groupId>
      <version>1.0-SNAPSHOT</version>
    </parent>
    

    父項目中的java子項目可以直接使用

    son extends father
    
  3. Maven環境優化

    1. 修改web.xml爲最新的,用以下代碼替換原有代碼:

      <?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"
               metadata-complete="true">
        
      </web-app>
      
    2. 將maven的結構搭建完整,即補充java、resources、test目錄完整。

  4. 編寫一個Servlet程序

    1. 編寫一個普通類,並實現Servlet接口,這裏我們直接繼承HttpServlet,代碼如下:

      package com.demut.servlet;
      
      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.io.PrintWriter;
      
      public class HelloServlet extends HttpServlet {
         
          //由於get或者post只是請求實現的不同的方式,相互調用,業務邏輯都是一樣的
          
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              PrintWriter writer = resp.getWriter(); //響應流
              writer.print("Htllo, Servlet");
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              super.doGet(req, resp);
          }
      }
      
    2. 編寫Servlet的映射。

      爲什麼需要映射:我們寫的是Java程序,但是要通過瀏覽器訪問,而瀏覽器需要連接web服務器,所以我們需要在web服務中註冊我們寫的Servlet,還需要給瀏覽器一個能夠訪問的路徑。

      在web.xml中的<web-app></web-app>內添加以下代碼:

      		<!--註冊Servlet-->
          <servlet>
              <servlet-name>hello</servlet-name>
              <servlet-class>com.demut.servlet.HelloServlet</servlet-class>
          </servlet>
          
          <!--配置Servlet的請求路徑-->
          <servlet-mapping>
              <servlet-name>hello</servlet-name>
              <url-pattern>/hello</url-pattern>
          </servlet-mapping>
      
    3. 配置Tomcat,我的另一篇博客裏面有詳細的配置過程:點擊跳轉

      注意:配置項目發佈的路徑就可以了,我這邊配置的路徑名爲S1!

    4. 點擊右上角,啓動Tomcat,隨後我們會在瀏覽器中看到Hello World!

    5. 在地址欄中後加hello,回車即可!如圖:

      在這裏插入圖片描述

    6. 如圖顯示Hello, Servlet 測試成功!

      在這裏插入圖片描述

3 Servlet原理

在這裏插入圖片描述

4 Mapping原理

  1. 一個Servlet可以指定一個映射路徑

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

    在這裏插入圖片描述

  2. 一個Servlet可以指定多個映射路徑

    <servlet-mapping>
    		<servlet-name>hello</servlet-name>
    		<url-pattern>/hello2</url-pattern>
    </servlet-mapping>
    
    <servlet-mapping>
    		<servlet-name>hello</servlet-name>
    		<url-pattern>/hello3</url-pattern>
    </servlet-mapping>
    
    <servlet-mapping>
    		<servlet-name>hello</servlet-name>
    		<url-pattern>/hello4</url-pattern>
    </servlet-mapping>
    

    在這裏插入圖片描述

  3. 一個Servlet可以指定通配映射路徑

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

    在這裏插入圖片描述

  4. 默認請求路徑

    <!--默認請求路徑-->
    <servlet-mapping>
    		<servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
  5. 指定一些後綴或者前綴的路徑

    <!--可以可以自定義後綴實現請求映射,注意*前不可以加項目映射的路徑-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.demut</url-pattern>
    </servlet-mapping>
    

    在這裏插入圖片描述

優先級問題:

​ 指定了固有的的映射路徑優先級最高,如果找不到就會走默認的處理請求。

以下展示404的頁面實現:

package com.demut.servlet;

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.io.PrintWriter;

public class ErrorServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");

        PrintWriter writer = resp.getWriter();
        writer.print("404");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<!--404 web.xml配置-->
<servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.demut.servlet.ErrorServlet</servlet-class>
</servlet>

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

5 ServletContext

web容器在啓動的時候,它會爲每個web程序創建一個對應的ServletContext對象,它代表了當前的web應用;

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-KdhfgDZd-1588607534171)(JavaWeb%20Day04.assets/image-20200502223031447.png)]

5.1 共享數據

相互獨立的Servlet之間可以共用信息!

我在這個Servlet中保存的數據,可以在另外一個Servlet中拿到;

代碼測試:

  1. 添加數據的類

    package com.demut.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 HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        this.getInitParameter(); //初始化參數
    //        this.getServletConfig(); //Servlet配置
    //        this.getServletContext(); //Servlet上下文
            ServletContext context = this.getServletContext();
    
            String username = "demut"; //數據
            context.setAttribute("username",username); //講一個數據保存在了ServletContext中
        }
    }
    
  2. 讀取數據的類

    package com.demut.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 GetServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            String username = (String)context.getAttribute("username");
            
            resp.setContentType("text/html");
            resp.setCharacterEncoding("utf-8");
         
            resp.getWriter().print("名字:" + username);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  3. web.xml

    <?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"
             metadata-complete="true">
    
        <servlet>
            <servlet-name>hello</servlet-name>
            <servlet-class>com.demut.servlet.HelloServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
    
        <servlet>
            <servlet-name>getc</servlet-name>
            <servlet-class>com.demut.servlet.GetServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>getc</servlet-name>
            <url-pattern>/getc</url-pattern>
        </servlet-mapping>
        
    </web-app>
    

測試結果:

首先輸入映射/hello寫入數據:

在這裏插入圖片描述

隨後輸入映射/getc讀取數據:

在這裏插入圖片描述

5.2 獲取初始化參數

我們在啓動一個web項目的時候通常會設置一些初始化參數,例如我們會在web中配置了數據庫的參數,此處我們想獲取該參數,使用context.getInitParameter可獲取,以下爲完整代碼:

測試代碼:

  1. web.xml我們初始化的參數,也是此次我們想獲取的參數:

    <!--配置一些web應用初始化參數-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>
    
  2. 獲取參數類:

    package com.demut.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 ServletDemo extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            String url = context.getInitParameter("url");
            resp.getWriter().print(url);
        }
    }
    
  3. web.xml配置路徑:

    <servlet>
        <servlet-name>gp</servlet-name>
        <servlet-class>com.demut.servlet.ServletDemo</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>gp</servlet-name>
        <url-pattern>/gp</url-pattern>
    </servlet-mapping>
    

測試結果:

輸入/gp測試:

在這裏插入圖片描述

5.3 請求轉發

首先筆者用流程圖說明一下轉發重定向的區別。

轉發過程:

在這裏插入圖片描述

重定向過程:

在這裏插入圖片描述

請求轉發使用context.getRequestDispatcher("").forward(req, resp)實現,以下爲完整代碼:

測試代碼:

  1. 測試類:

    package com.demut.servlet;
    
    import javax.servlet.RequestDispatcher;
    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 ServletDemo02 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            System.out.println("進入了ServletDemo02");
    //        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //轉發的請求路徑
    //        requestDispatcher.forward(req,resp);//調用forward實現請求轉發
            context.getRequestDispatcher("/gp").forward(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  2. web.xml中配置

    <servlet>
        <servlet-name>sd4</servlet-name>
        <servlet-class>com.demut.servlet.ServletDemo02</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>sd4</servlet-name>
        <url-pattern>/sd4</url-pattern>
    </servlet-mapping>
    

測試結果:

地址欄輸入/sd4,會映射到/gp,返回/gp對應的結果:

在這裏插入圖片描述

5.4 讀取資源文件

Properties文件:

  • 在java目錄下新建properties
  • 在resources目錄下新建properties

此時需要注意,需要在pom.xml文件下的<build></build>路徑中配置<resources>...</resources>,否則上述兩個文件不能同時導出。配置代碼如下:

<build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>

      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>

啓動後,我們會發現文件都被打包到了同一路徑下:classes,我們俗稱這個路徑爲classpath。

思路:需要一個文件流。

測試代碼:

  1. 資源文件配置:(db.properties, 放到resources文件下)

    username = demut
    password = 123456
    
  2. 讀取資源文件類:

    package com.demut.servlet;
    
    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.io.InputStream;
    import java.util.Properties;
    
    public class ServletDemo03 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
            Properties prop = new Properties();
            prop.load(is);
    
            String user = prop.getProperty("username");
            String pwd = prop.getProperty("password");
    
            resp.getWriter().print(user + ":" + pwd);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  3. web.xml配置

    <servlet>
        <servlet-name>sd5</servlet-name>
        <servlet-class>com.demut.servlet.ServletDemo03</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>sd5</servlet-name>
        <url-pattern>/sd5</url-pattern>
    </servlet-mapping>
    

測試結果:(地址欄內追加/sd5)

在這裏插入圖片描述

6 Response&Request應用

web服務器接收到客戶端的http請求,針對這個請求,分別創建一個代表請求的HttpServletRequest對象,和代表響應的一個HttpServletResponse;

  • 如果要獲取客戶端請求過來的參數:找HttpServletRequest
  • 如果要給客戶端響應一些信息:找HttpServletResponse

6.1 簡單分類

負責向瀏覽器發送數據的方法

ServletOutputStream getOutputStream() throws IOException;

PrintWriter getWriter() throws IOException;

負責向瀏覽器發送響應頭的方法

void setCharacterEncoding(String var1);

void setContentLength(int var1);

void setContentLengthLong(long var1);

void setContentType(String var1);

void setDateHeader(String var1, long var2);

void addDateHeader(String var1, long var2);

void setHeader(String var1, String var2);

void addHeader(String var1, String var2);

void setIntHeader(String var1, int var2);

void addIntHeader(String var1, int var2);

響應狀態碼

int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

6.2 下載文件應用

此處演示如何從服務器中下載文件(我在resources目錄下準備了一張圖片(張三.png))

實現思路:

  1. 獲取要下載的文件的絕對路徑

  2. 獲取要下載的文件名

  3. 設置content-disposition響應頭控制瀏覽器以下載的形式打開文件

  4. 獲取要下載的文件輸入流

  5. 創建數據緩衝區

  6. 通過response對象獲取OutputStream流

  7. 將FileInputStream流寫入到buffer緩衝區

  8. 使用OutputStream將緩衝區的數據輸出到客戶端瀏覽器

測試代碼:(前提已創建好相應的web項目並配置好了Tomcat)

下載文件類:

package com.demut.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.獲取路徑
        String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/download/張三.png");
        //2.獲取下載的文件名
        String fileName = realPath.substring(realPath.lastIndexOf("/")+1);
        //3.設置content-disposition響應頭控制瀏覽器以下載的形式打開文件
        resp.setHeader("Content-Disposition","attachment; filename="+ URLEncoder.encode(fileName,"UTF-8"));

        //4.獲取下載文件的輸入流
        FileInputStream in = new FileInputStream(realPath);

        //5.創建緩衝區
        int len = 0;
        byte[] buffer = new byte[1024];

        //6.獲取Outputstream對象
        ServletOutputStream out = resp.getOutputStream();

        //7.將FileOutputStream流寫入到buffer緩衝區
        while ((len = in.read(buffer)) > 0) {
            out.write(buffer, 0, len);
        }
        //8.關閉流
        out.close();
        in.close();
    }

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

web.xml中配置:

<servlet>
    <servlet-name>filedown</servlet-name>
    <servlet-class>com.demut.servlet.FileServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>filedown</servlet-name>
    <url-pattern>/down</url-pattern>
</servlet-mapping>

測試結果:

在這裏插入圖片描述

6.3 驗證碼應用

測試代碼:

生成驗證碼類:

package com.demut.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //讓瀏覽器每隔3秒刷新一次
        resp.setHeader("refresh","3");

        //在內存中創建一張圖片
        BufferedImage image = new BufferedImage(100, 50, BufferedImage.TYPE_INT_RGB);
        //設置一隻筆,對圖片進行操作
        Graphics2D g = (Graphics2D) image.getGraphics();
        //設置圖片的背景顏色
        g.setColor(Color.MAGENTA);
        g.fillRect(0,0,100,50);
        //給圖片寫數據
        g.setColor(Color.white);
        g.setFont(new Font(null,Font.BOLD,26));
        g.drawString(makeRandom(),0,30);

        //告知瀏覽器,以圖片的方式打開
        resp.setContentType("image/jpeg");
        //網站存在緩存,此處關閉緩存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");

        //把圖片寫給瀏覽器
        ImageIO.write(image, "jpeg",resp.getOutputStream());

    }

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

    private String makeRandom(){
        Random random = new Random();
        String num = random.nextInt(999999)+"";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 6-num.length(); i++){
            sb.append("0");
        }
        num = sb.toString() + num;
        return num;
    }
}

web.xml中配置:

<servlet>
    <servlet-name>ImageServlet</servlet-name>
    <servlet-class>com.demut.servlet.ImageServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>ImageServlet</servlet-name>
    <url-pattern>/img</url-pattern>
</servlet-mapping>

測試結果:

在這裏插入圖片描述

6.4 實現重定向(重要)

在這裏插入圖片描述

B的一個web資源收到客戶端A請求後,B會通知A客戶端去訪問另外一個web資源C,這個過程叫做重定向。

常用場景:

  • 用戶登錄

測試:

//類
public class RedirectServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        resp.setHeader("Location","/response/img");
//        resp.setStatus(302);
        resp.sendRedirect("/response/img"); //重定向
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
<!--配置web路徑-->
<servlet>
    <servlet-name>RedirectServlet</servlet-name>
    <servlet-class>com.demut.servlet.RedirectServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>RedirectServlet</servlet-name>
    <url-pattern>/redirect</url-pattern>
</servlet-mapping>

測試結果:

地址欄輸入路徑:

在這裏插入圖片描述

自動跳轉到以下位置:

在這裏插入圖片描述

查看請求:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-OwrvqNu6-1589812720563)(JavaWeb%20Servlet%E8%AF%A6%E8%A7%A3%20Day04.assets/image-20200518110313743.png)]

面試題:請你聊聊重定向和轉發的區別?==

相同點:

  • 頁面都會實現跳轉

不同點:

  • 請求轉發的時候,url不會產生變化
  • 重定向的時候,url地址欄會發生變化

6.5 實現重定向的一個Demo(註冊)

index.jsp中代碼:

<html>
<body>
<h2>Hello World!</h2>

<%--這裏提交的路徑需要尋找到項目的路徑--%>
<%--${pageContext.request.getContextPath}表示當前的項目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    用戶名:<input type="text" name = "username"> <br>
    密碼:<input type="password" name = "password"> <br>
    <input type="submit">

</form>
</body>
</html>

RequestTest類:

package com.demut.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 RequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("進入這個請求了!");

        //處理請求
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username + ":" + password);

        //重定向的時候一定要注意路徑問題,避免404
        resp.sendRedirect("/response/success.jsp");
    }

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

創建success.jsp並輸入以下代碼:

<%--
  Created by IntelliJ IDEA.
  User: demut
  Date: 2020/5/18
  Time: 11:44 上午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<p>
    註冊成功!
</p>

</body>
</html>

配置web中路徑

<servlet>
    <servlet-name>request</servlet-name>
    <servlet-class>com.demut.servlet.RequestTest</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>request</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

之後測試自行測試,此處不再展示!

寫在最後

悲劇贏得雋永,喜劇安慰人心!

To Demut and Dottie!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章