1. 程式人生 > 其它 >web基礎2-servlet入門(request、response)

web基礎2-servlet入門(request、response)

web基礎2-servlet入門

一、Servlet

1.1 servlet簡介

  • Servlet就是sun公司開發動態web的一門技術

  • Sun在這些API中提供一個介面叫做:Servlet,如果你想開發一個Servlet程式,只需要完成3個步驟:

    • 編寫一個類,實現servlet介面
    • 把開發好的Servlet註冊在web.xml中
    • 把開發好的JAVA類部署到web伺服器中

把實現了Servlet介面的java程式叫做servlet

1.2 第一個servlet-HelloServlet

servlet在sun公司有兩個預設繼承類,Httpservlet,GenericServlet

1.2.1 構建父子工程。(也可以不用父子工程)

構建一個普通的maven專案,刪掉裡面的src目錄,以後我們的學習就在這個專案裡面建立module了。這個空的工程就是maven主工程。詳細見1.3

1.2.2 Maven環境優化

  • 修改web.xml為最新的,換頭
  • 將maven的結構搭建完畢

1.2.3 編寫一個servlet程式

  • 編寫一個普通類
  • 實現一個servlet介面,我們這裡直接繼承Httpservlet
idea中檢視繼承關係樹

方法一:

ctrl+H

方法二:

ctrl+alt+U

1.2.4 編寫servlet對映

為什麼需要對映:我們寫的是java程式,但是要通過瀏覽器訪問,而瀏覽器需要連線的web伺服器,所以我們需要:

  • 在web伺服器中註冊我們寫的servlet

  • 還需要給他一個瀏覽器能夠訪問的路徑。

<!--web.xml是配置我們web的核心配置檔案-->
<!--註冊Servelet-->
<servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>com.happy.servlet.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!--請求地址-->
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

1.2.5 配置tomcat

注意:配置專案釋出的路徑即可

1.3 關於maven 父子工程的理解

注意:有時候用idea建立子專案的時候,parent標籤會丟失,注意檢查專案

父專案中會有

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

子專案中會有

<parent>
    <artifactId>PureMavenWeb</artifactId>
    <groupId>org.example</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

父專案中的java子專案可以直接使用,而子專案中的父專案不能使用。同多型一樣。

二、servlet原理

三、Mapping問題

3.1 一個Servlet請求可以指定一個對映路徑

<!--web.xml是配置我們web的核心配置檔案-->
<!--註冊Servelet-->
<servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>com.happy.servlet.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!--請求地址-->
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

3.2 一個Servlet可以指定多個對映路徑

<servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>com.happy.servlet.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!--請求地址-->
    <url-pattern>/hello</url-pattern>
</servlet-mapping>
<!--一個servlet對應多個對映url-->
<servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!--請求地址-->
    <url-pattern>/hello2</url-pattern>
</servlet-mapping>

3.3 一個Servlet可以指定通用對映路徑

<servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!--請求地址-->
    <url-pattern>/hello/*</url-pattern>
</servlet-mapping>

3.4 自定義字尾實現請求對映

注意:前面不能加對映的路徑,如/hello/*.do

<servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>com.happy.servlet.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!--可以自定義字尾匹配對映-->
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

3.5 預設請求路徑(兜底)

<servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>com.happy.servlet.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!--可以自定義字尾匹配對映-->
    <url-pattern>/*</url-pattern>
</servlet-mapping>

3.6 優先順序匹配

指定了固有的對映路徑=》優先順序最高。

如果找不到就會走預設的處理請求/*

四、servlet重要物件和API

4.1 init-parm vs context-param

<servlet>
    <servlet-name>loginServlet</servlet-name>
    <servlet-class>com.qcc.study.servlet02.LoginServlet</servlet-class>
    <!-- 配置Servlet初始化引數 -->
    <init-param>
        <param-name>initParam</param-name>
        <param-value>qcc</param-value>
    </init-param>
    <!-- Web容器啟動時就載入並例項化該Servlet -->
    <load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>loginServlet</servlet-name>
    <url-pattern>/login</url-pattern>	
</servlet-mapping>
<!-- 配置ContextParam全域性引數 -->
<context-param>
    <param-name>contextParam</param-name>
    <param-value>admin</param-value>
</context-param>

配置在標籤中,用來初始化當前的Servlet的,屬於當前Servlet的配置,因此存放在 servletConfig物件中;

通過getServletConfig().getInitParameter("initParam")的方式獲取;

直接配置在web.xml的標籤中,屬於上下文引數,在整個web應用中都可以使用,它是全域性的,因此存放在servletContext物件中(即application物件);

通過getServletContext().getInitParameter("contextParam")的方式獲取;

4.2 ServletContext

web容器在啟動的時候,他會為每個web程式都建立一個對應的ServletContext物件,它代表了當前的web應用。(在容器啟動時候就有)

作用:

4.2.1 共享資料

我在這servlet中儲存的資料,可以在另外一個servlet獲取。

注意:實際工作中,一般不用servletContext存取資料,一般用session和cookie和request存取資料

一個servlet用於通過ServletContext來set資料

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

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

//    <!-- 配置ContextParam全域性引數 -->
//    <context-param>
//        <param-name>happyContextParam</param-name>
//        <param-value>admin</param-value>
//    </context-param>
        String happy = servletContext.getInitParameter("happyContextParam");
        System.out.println(happy);
        int i=0;
        Object object= servletContext.getAttribute("happy");
        if (object==null){
            i=0;
        } else {
            i=(int)object+1;
        }
        servletContext.setAttribute("happy",i);

        ServletConfig servletConfig = this.getServletConfig();
        String happyServletParam = servletConfig.getInitParameter("happyServletParam");
        System.out.println(happyServletParam);
        PrintWriter writer = resp.getWriter();
        writer.println("<h1>訪問次數+1</h1>");
        writer.println("<a href='http://localhost:8080/s2/get' target='_blank'>http://localhost:8080/s2/get</a>");
        System.out.println(i);
    }

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

一個servlet用於通過ServletContext來get資料

package com.happy.servlet;

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

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        Object happy = servletContext.getAttribute("happy");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.println("訪問次數共計:"+happy);

    }

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

web.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"
         metadata-complete="true">

    <!-- 配置ContextParam全域性引數 -->
    <context-param>
        <param-name>happyContextParam</param-name>
        <param-value>admin</param-value>
    </context-param>

    <servlet>
        <servlet-name>SetServlet</servlet-name>
        <servlet-class>com.happy.servlet.SetServlet</servlet-class>
        <init-param>
            <param-name>happyServletParam</param-name>
            <param-value>happyvalue</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>SetServlet</servlet-name>
        <url-pattern>/set/*</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>GetServlet</servlet-name>
        <servlet-class>com.happy.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GetServlet</servlet-name>
        <url-pattern>/get</url-pattern>
    </servlet-mapping>

</web-app>

4.2.2 獲取初始化引數

可以用來配置一些web應用初始化引數

注意:實際工作中一般不在web.xml中放參數,而用properties檔案等存全域性引數

 <!-- 配置ContextParam全域性引數
        可以用來配置一些web應用初始化引數-->
    <context-param>
        <param-name>happyContextParam</param-name>
        <param-value>admin</param-value>
    </context-param>

    <context-param>
        <param-name>setByConf</param-name>
        <param-value>setByConfValue</param-value>
    </context-param>
package com.happy.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;
import java.io.PrintWriter;

public class GetInitParamsServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        String setByConf = (String)servletContext.getInitParameter("setByConf");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.println("setByConf:"+setByConf);

    }

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

4.2.3 請求轉發

實際工作中一般不用ContextServlet物件的dispatcher,而用response物件的dispatcher方法

package com.happy.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;
import java.io.PrintWriter;

public class ContextDispatcherServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        servletContext.getRequestDispatcher("/get").forward(request,response);
    }

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

<servlet>
    <servlet-name>ContextDispatcherServlet</servlet-name>
    <servlet-class>com.happy.servlet.ContextDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ContextDispatcherServlet</servlet-name>
    <url-pattern>/cds</url-pattern>
</servlet-mapping>

4.2.4 讀取專案資原始檔

實際工作中一般不用這個api,而是用反射和類載入等載入資原始檔

前景補充知識
關於classpath
  • java目錄,作為source目錄
  • resources目錄,作為resources目錄

對回被打包到同一個路徑下:classes,我們俗稱這個路徑為classpath:

maven構建時候,部分source目錄下面資原始檔不能打包問題

解決方案:在build中配置resources.來防止我們資源匯出失敗的問題

<build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
獲取資原始檔

寫一個servlet呼叫context物件的獲取資原始檔的api方法getResourceAsStream

InputStream is = servletContext.getResourceAsStream("/WEB-INF/classes/db.properties");

    <servlet>
        <servlet-name>PropertiesServlet</servlet-name>
        <servlet-class>com.happy.servlet.PropertiesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>PropertiesServlet</servlet-name>
        <url-pattern>/ps</url-pattern>
    </servlet-mapping>
package com.happy.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;
import java.io.InputStream;
import java.util.Properties;

public class PropertiesServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        InputStream is = servletContext.getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties prop = new Properties();
        prop.load(is);
        String url = prop.getProperty("url");
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");
        response.getWriter().println(url+" "+username+" "+password);
    }

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

效果如下:

4.3 HttpServletResponse

web伺服器接收到客戶端的http請求,針對這個請求,分別建立一個代表請求的HttpServletRequest物件,代表響應的一個httpServeletResponse。

  • 如果要獲取客戶端請求過來的引數:找HttpServeletRequest
  • 如果要給客戶端響應一些資訊:找HttpServeletResponse

4.3.1 HttpServletResponse簡單分類

負責向瀏覽器傳送資料的方法
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 setBufferSize(int 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);

void setStatus(int var1);

響應的狀態碼:

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;

4.3.2 HttpServletResponse常見應用

1. 向瀏覽器輸出訊息
2.下載檔案resp.setHeader("Content-disposition","attachment;filename"+filename);

核心:

resp.setHeader("Content-disposition","attachment;filename="+filename);
URLEncoder.encode(filename,"utf-8")) //解決檔名亂碼
  1. 要獲取下載檔案的路徑
  2. 下載檔名是啥
  3. 設定想辦法讓瀏覽器能夠支援下載我們需要的東西
  4. 獲取下載檔案的輸入流
  5. 建立快取區
  6. 獲取OutputStream物件
  7. 將FIleOutputStream流寫入到buffer緩衝區
  8. 使用outputstream將緩衝區中的資料輸出到客戶端
package com.happy.servlet;


import org.apache.commons.lang3.StringUtils;

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 DownServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      /*  1. 要獲取下載檔案的路徑
        2. 下載檔名是啥
        3. 設定想辦法讓瀏覽器能夠支援下載我們需要的東西
        4. 獲取下載檔案的輸入流
        5. 建立快取區
        6. 獲取OutputStream物件
        7. 將FIleOutputStream流寫入到buffer緩衝區
        8. 使用outputstream將緩衝區中的資料輸出到客戶端*/
        String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/書.jpg");
        System.out.println(realPath);
        String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
        System.out.println(filename);

//        resp.setHeader("Content-disposition","attachment;filename"+filename);

        String userAgent = req.getHeader("USER-AGENT");
        if (StringUtils.contains(userAgent, "MSIE") || StringUtils.contains(userAgent, "Edge")) {
            // IE瀏覽器
            filename = URLEncoder.encode(filename, "UTF-8");
        } else if (StringUtils.contains(userAgent, "Firefox") || StringUtils.contains(userAgent, "Chrome") || StringUtils.contains(userAgent, "Safari")) {
            // google,火狐瀏覽器
//            filename = new String(filename.getBytes(), "ISO-8859-1");
            filename = URLEncoder.encode(filename, "UTF-8");
        } else {
            filename = URLEncoder.encode(filename, "UTF-8");
// 其他瀏覽器
        }
        System.out.println(filename);
        resp.setHeader("Content-disposition", "attachment;filename=" + filename);


        // 建立輸入流,把檔案變成流
        FileInputStream is = new FileInputStream(realPath);
        // 建立輸出流
        ServletOutputStream os = resp.getOutputStream();
        // 建立快取區,new 一個byte【】作為byte
        byte[] buff = new byte[1024];
        int len = 0;
        try {
            System.out.println("開始讀取資料");
            while ((len = is.read(buff)) > 0) {
                os.write(buff, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            is.close();
            os.close();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
3.生成驗證碼

原生生成驗證碼方法:

package com.happy.servlet;

import org.junit.jupiter.api.Test;

import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
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 request, HttpServletResponse response) throws ServletException, IOException {
//        前端重新整理為windows.location.refresh
//        通過後端響應給前端設定頭資訊,響應可以設定前端所有東西
        response.setHeader("refresh","8");

        BufferedImage bufferedImage=drawNum();

//        告訴瀏覽器,這個請求的響應用圖片方式開啟
        response.setContentType("image/png");
//        取消快取
        response.setDateHeader("expires",-1);
        response.setHeader("Cache-Control","no-cache");
        response.setHeader("Pragma","no-cache");
        boolean jpg = ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
    }

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

    @Test
    public BufferedImage drawNum(){
        //        在記憶體中建立一個空白的圖片
        BufferedImage bufferedImage = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();
//        設定圖片的背景顏色
        graphics.setColor(Color.white);
//        畫邊框
        graphics.fillRect(0,0,80,20);
//        給圖片寫資料
        graphics.setColor(Color.blue);
        graphics.setFont(new Font(null,Font.BOLD,20));
        graphics.drawString(makeNum(),0,20);

        return bufferedImage;
    }

    public String makeNum(){
        Random random = new Random();
        String num = String.valueOf(random.nextInt(999999+1));
        StringBuffer sb = new StringBuffer(num);
        for(int i=0;i<=5-num.length();i++){
            sb.append(0);
        }
        return sb.toString();
    }
}

4.實現重定向

本質上是302和location設定重定向地址

response.sendRedirect();

常見場景:

  • 使用者登陸
package com.happy.servlet;

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

public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        方式一
//        可以直接重定向到外部網站
//        response.sendRedirect("http://www.baidu.com");
//        也可以內部地址,要帶專案名
        response.sendRedirect("/response/image");
    }

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

所以本質上是302和location設定重定向地址

//        方式二,拆分兩步
response.setHeader("Location","/response/image");
//        response.setStatus(302);
response.setStatus(HttpServletResponse.SC_FOUND);
重定向和轉發的區別
重定向 轉發
相同點 頁面實現跳轉 頁面實現跳轉
不同點 url位址列會發生變化 url不會產生變化
${pageContext.request.contextPath}
登陸跳轉(重定向實戰)

index.jsp作為登陸頁面如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陸介面</title>
</head>
<body>

<%--這裡提交的路徑,需要尋找專案的路徑--%>
<%--<form action="/response/login" method="get">--%>
<form action="${pageContext.request.contextPath}/login" method="get">
使用者:<input type="text" name="username">
密碼:<input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>

web.xml配置對映

<servlet>
    <servlet-name>FormServlet</servlet-name>
    <servlet-class>com.happy.servlet.FormServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>FormServlet</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

處理servlet

package com.happy.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 FormServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("進入這個請求了");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username+":"+password);
        response.sendRedirect("/response/success.jsp");

    }

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

4.4 HttpServletRequest

4.4.1 響應重定向和請求轉發

重定向和轉發的區別
重定向 轉發
相同點 頁面實現跳轉 頁面實現跳轉
不同點 url位址列會發生變化 url不會產生變化
狀態碼 302 307
重定向response.sendRedirect

注意:重定地址(外部地址)要帶專案名

獲取方式:

  1. 寫死response.sendRedirect("projectContextName/success.jsp");

  2. this.getServletContext().getContextPath()
    response.sendRedirect(this.getServletContext().getContextPath()+"/success.jsp");
    
  3. request.getContextPath()
    response.sendRedirect(request.getContextPath()+"/success.jsp");
    
轉發request.getRequestDispatcher

注意:轉發地址(內部地址)不用帶專案名

轉發this.getServletContext().getRequestDispatcher

4.4.2 獲取前端引數

package com.happy.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.Arrays;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username+":"+password);
        String[] hobbies = request.getParameterValues("hobbies");
        System.out.println(Arrays.toString(hobbies));
        System.out.println(this.getServletContext().getContextPath());
        System.out.println(request.getContextPath());
//        方式一:response redirect轉發
//        response.sendRedirect(this.getServletContext().getContextPath()+"/success.jsp");
//        方式二:servletContext 重定向
//        this.getServletContext().getRequestDispatcher("/success.jsp").forward(request,response);
        //方式三:request 重定向
        request.getRequestDispatcher("/success.jsp").forward(request,response);

    }

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