Java Web筆記(2)

来源:https://www.cnblogs.com/xjtu-lyh/archive/2020/02/18/12329395.html
-Advertisement-
Play Games

學習筆記,狂神說java,鏈接:https://www.bilibili.com/video/av68833391 5、Maven 我為什麼要學習這個技術? 1. 在Javaweb開發中,需要使用大量的jar包,我們手動去導入; 2. 如何能夠讓一個東西自動幫我導入和配置這個jar包。 由此,Mav ...


學習筆記,狂神說java,鏈接:https://www.bilibili.com/video/av68833391

5、Maven

我為什麼要學習這個技術?

  1. 在Javaweb開發中,需要使用大量的jar包,我們手動去導入;

  2. 如何能夠讓一個東西自動幫我導入和配置這個jar包。

    由此,Maven誕生了!

5.1 Maven項目架構管理工具

我們目前用來就是方便導入jar包的!

Maven的核心思想:約定大於配置

  • 有約束,不要去違反。

Maven會規定好你該如何去編寫我們的Java代碼,必須要按照這個規範來;

5.2 下載安裝Maven

官網;https://maven.apache.org/

下載完成後,解壓即可;

小狂神友情建議:電腦上的所有環境都放在一個文件夾下,方便管理;

5.3 配置環境變數

在我們的系統環境變數中

配置如下配置:

  • M2_HOME maven目錄下的bin目錄
  • MAVEN_HOME maven的目錄
  • 在系統的path中配置 %MAVEN_HOME%\bin

測試Maven是否安裝成功,保證必須配置完畢!

5.4 阿裡雲鏡像

  • 鏡像:mirrors
    • 作用:加速我們的下載
  • 國內建議使用阿裡雲的鏡像
<mirror>
    <id>nexus-aliyun</id>  
    <mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>  
    <name>Nexus aliyun</name>  
    <url>http://maven.aliyun.com/nexus/content/groups/public</url> 
</mirror>

5.5 本地倉庫

在本地的倉庫,遠程倉庫;

建立一個本地倉庫:localRepository

<localRepository>D:\Environment\apache-maven-3.6.2\maven-repo</localRepository>

5.6、在IDEA中使用Maven

  1. 啟動IDEA

  2. 創建一個MavenWeb項目

  1. 等待項目初始化完畢

  1. 觀察maven倉庫中多了什麼東西?

  2. IDEA中的Maven設置

    註意:IDEA項目創建成功後,看一眼Maven的配置

  1. 到這裡,Maven在IDEA中的配置和使用就OK了!

5.7、創建一個普通的Maven項目

這個只有在Web應用下才會有!

5.8 標記文件夾功能

5.9 在 IDEA中配置Tomcat

解決警告問題

必須要的配置:為什麼會有這個問題:我們訪問一個網站,需要指定一個文件夾名字;

5.10 pom文件

pom.xml 是Maven的核心配置文件

<?xml version="1.0" encoding="UTF-8"?>

<!--Maven版本和頭文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <!--這裡就是我們剛纔配置的GAV-->
  <groupId>com.kuang</groupId>
  <artifactId>javaweb-01-maven</artifactId>
  <version>1.0-SNAPSHOT</version>
  <!--Package:項目的打包方式
  jar:java應用
  war:JavaWeb應用
  -->
  <packaging>war</packaging>


  <!--配置-->
  <properties>
    <!--項目的預設構建編碼-->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!--編碼版本-->
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <!--項目依賴-->
  <dependencies>
    <!--具體依賴的jar包配置文件-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
    </dependency>
  </dependencies>

  <!--項目構建用的東西-->
  <build>
    <finalName>javaweb-01-maven</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

maven由於他的約定大於配置,我們之後可以能遇到我們寫的配置文件,無法被導出或者生效的問題,解決方案:

<!--在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>

5.12 IDEA操作

5.13 解決遇到的問題

  1. Maven 3.6.3

    解決方法:降級為3.6.1

  2. Tomcat閃退

  3. IDEA中每次都要重覆配置Maven
    在IDEA中的全局預設配置中去配置

  1. Maven項目中Tomcat無法配置

  2. maven預設web項目中的web.xml版本問題

  1. 替換為webapp4.0版本和tomcat一致

    <?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"
             metadata-complete="true">
    
    
    
    </web-app>
  2. Maven倉庫的使用

    地址:https://mvnrepository.com/

6、Servlet

6.1、Servlet簡介

  • Servlet就是sun公司開發動態web的一門技術
  • Sun在這些API中提供一個介面叫做:Servlet,如果你想開發一個Servlet程式,只需要完成兩個小步驟:
    • 編寫一個類,實現Servlet介面
    • 把開發好的Java類部署到web伺服器中。

把實現了Servlet介面的Java程式叫做,Servlet

6.2、HelloServlet

Serlvet介面Sun公司有兩個預設的實現類:HttpServlet,GenericServlet

  1. 構建一個普通的Maven項目,刪掉裡面的src目錄,以後我們的學習就在這個項目裡面建立Moudel;這個空的工程就是Maven主工程;

  2. 關於Maven父子工程的理解:

    父項目中會有

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

    子項目會有

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

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

    ```java
    son extends father

```

  1. Maven環境優化

    1. 修改web.xml為最新的
    2. 將maven的結構搭建完整
  2. 編寫一個Servlet程式

    1. 編寫一個普通類

    2. 實現Servlet介面,這裡我們直接繼承HttpServlet

      public class HelloServlet extends HttpServlet {
      
          //由於get或者post只是請求實現的不同的方式,可以相互調用,業務邏輯都一樣;
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //ServletOutputStream outputStream = resp.getOutputStream();
              PrintWriter writer = resp.getWriter(); //響應流
              writer.print("Hello,Serlvet");
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      
  3. 編寫Servlet的映射

    為什麼需要映射:我們寫的是JAVA程式,但是要通過瀏覽器訪問,而瀏覽器需要連接web伺服器,所以我們需要再web服務中註冊我們寫的Servlet,還需給他一個瀏覽器能夠訪問的路徑;

        <!--註冊Servlet-->
        <servlet>
            <servlet-name>hello</servlet-name>
            <servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
        </servlet>
        <!--Servlet的請求路徑-->
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
    
  4. 配置Tomcat

    註意:配置項目發佈的路徑就可以了

  5. 啟動測試,OK!

6.3、Servlet原理

Servlet是由Web伺服器調用,web伺服器在收到瀏覽器請求之後,會:

6.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>/hello</url-pattern>
        </servlet-mapping>
        <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>
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello5</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. 指定一些尾碼或者首碼等等….

    <!--可以自定義尾碼實現請求映射
        註意點,*前面不能加項目映射的路徑
        hello/sajdlkajda.qinjiang
        -->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.qinjiang</url-pattern>
    </servlet-mapping>
  6. 優先順序問題
    指定了固有的映射路徑優先順序最高,如果找不到就會走預設的處理請求;

    <!--404-->
    <servlet>
        <servlet-name>error</servlet-name>
        <servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>error</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    

6.5、ServletContext

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

1、共用數據

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

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 = "秦疆"; //數據
        context.setAttribute("username",username); //將一個數據保存在了ServletContext中,名字為:username 。值 username

    }

}
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);
    }
}
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.kuang.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.kuang.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
    </servlet-mapping>

測試訪問結果;

2、獲取初始化參數

    <!--配置一些web應用初始化參數-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    String url = context.getInitParameter("url");
    resp.getWriter().print(url);
}

3、請求轉發

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    System.out.println("進入了ServletDemo04");
    //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //轉發的請求路徑
    //requestDispatcher.forward(req,resp); //調用forward實現請求轉發;
    context.getRequestDispatcher("/gp").forward(req,resp);
}

4、讀取資源文件

Properties

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

發現:都被打包到了同一個路徑下:classes,我們俗稱這個路徑為classpath:

思路:需要一個文件流;

username=root12312
password=zxczxczxc
public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/kuang/servlet/aa.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);
    }
}

訪問測試即可ok;

6.6、HttpServletResponse

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

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

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;

2、下載文件

  1. 向瀏覽器輸出消息 (一直在講,就不說了)
  2. 下載文件
    1. 要獲取下載文件的路徑
    2. 下載的文件名是啥?
    3. 設置想辦法讓瀏覽器能夠支持下載我們需要的東西
    4. 獲取下載文件的輸入流
    5. 創建緩衝區
    6. 獲取OutputStream對象
    7. 將FileOutputStream流寫入到buffer緩衝區
    8. 使用OutputStream將緩衝區中的數據輸出到客戶端!
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. 要獲取下載文件的路徑
    String realPath = "F:\\班級管理\\西開【19525】\\2、代碼\\JavaWeb\\javaweb-02-servlet\\response\\target\\classes\\秦疆.png";
    System.out.println("下載文件的路徑:"+realPath);
    // 2. 下載的文件名是啥?
    String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
    // 3. 設置想辦法讓瀏覽器能夠支持(Content-Disposition)下載我們需要的東西,中文文件名URLEncoder.encode編碼,否則有可能亂碼
    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緩衝區,使用OutputStream將緩衝區中的數據輸出到客戶端!
    while ((len=in.read(buffer))>0){
        out.write(buffer,0,len);
    }

    in.close();
    out.close();
}

3、驗證碼功能

驗證怎麼來的?

  • 前端實現
  • 後端實現,需要用到 Java 的圖片類,生產一個圖片
package com.kuang.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(80,20,BufferedImage.TYPE_INT_RGB);
        //得到圖片
        Graphics2D g = (Graphics2D) image.getGraphics(); //筆
        //設置圖片的背景顏色
        g.setColor(Color.white);
        g.fillRect(0,0,80,20);
        //給圖片寫數據
        g.setColor(Color.BLUE);
        g.setFont(new Font(null,Font.BOLD,20));
        g.drawString(makeNum(),0,20);

        //告訴瀏覽器,這個請求用圖片的方式打開
        resp.setContentType("image/jpeg");
        //網站存在緩存,不讓瀏覽器緩存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");

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

    }

    //生成隨機數
    private String makeNum(){
        Random random = new Random();
        String num = random.nextInt(9999999) + "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 7-num.length() ; i++) {
            sb.append("0");
        }
        num = sb.toString() + num;
        return num;
    }


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

4、實現重定向

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

常見場景:

  • 用戶登錄
void sendRedirect(String var1) throws IOException;

測試:

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

    /*
        resp.setHeader("Location","/r/img");
        resp.setStatus(302);
         */
    resp.sendRedirect("/r/img");//重定向
}

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

相同點

  • 頁面都會實現跳轉

不同點

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

5、簡單實現登錄重定向

<%--這裡提交的路徑,需要尋找到項目的路徑--%>
<%--${pageContext.request.contextPath}代表當前的項目--%>

<form action="${pageContext.request.contextPath}/login" method="get">
    用戶名:<input type="text" name="username"> <br>
    密碼:<input type="password" name="password"> <br>
    <input type="submit">
</form>
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //處理請求
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        System.out.println(username+":"+password);

        //重定向時候一定要註意,路徑問題,否則404;
        resp.sendRedirect("/r/success.jsp");
    }
  <servlet>
    <servlet-name>requset</servlet-name>
    <servlet-class>com.kuang.servlet.RequestTest</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>requset</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>Success</h1>

</body>
</html>

6.7、HttpServletRequest

HttpServletRequest代表客戶端的請求,用戶通過Http協議訪問伺服器,HTTP請求中的所有信息會被封裝到HttpServletRequest,通過這個HttpServletRequest的方法,獲得客戶端的所有信息;

獲取參數,請求轉發

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

    req.setCharacterEncoding("utf-8");
    resp.setCharacterEncoding("utf-8");

    String username = req.getParameter("username");
    String password = req.getParameter("password");
    String[] hobbys = req.getParameterValues("hobbys");
    System.out.println("=============================");
    //後臺接收中文亂碼問題
    System.out.println(username);
    System.out.println(password);
    System.out.println(Arrays.toString(hobbys));
    System.out.println("=============================");


    System.out.println(req.getContextPath());
    //通過請求轉發
    //這裡的 / 代表當前的web應用
    req.getRequestDispatcher("/success.jsp").forward(req,resp);

}

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

相同點

  • 頁面都會實現跳轉

不同點

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

7、Cookie、Session

7.1、會話

會話:用戶打開一個瀏覽器,點擊了很多超鏈接,訪問多個web資源,關閉瀏覽器,這個過程可以稱之為會話;

有狀態會話:一個同學來過教室,下次再來教室,我們會知道這個同學,曾經來過,稱之為有狀態會話;

你能怎麼證明你是西開的學生?

你 西開

  1. 發票 西開給你發票
  2. 學校登記 西開標記你來過了

一個網站,怎麼證明你來過?

客戶端 服務端

  1. 服務端給客戶端一個 信件,客戶端下次訪問服務端帶上信件就可以了; cookie
  2. 伺服器登記你來過了,下次你來的時候我來匹配你; seesion

7.2、保存會話的兩種技術

cookie

  • 客戶端技術 (響應,請求)

session

  • 伺服器技術,利用這個技術,可以保存用戶的會話信息? 我們可以把信息或者數據放在Session中!

常見常見:網站登錄之後,你下次不用再登錄了,第二次訪問直接就上去了!

  1. 從請求中拿到cookie信息
  2. 伺服器響應給客戶端cookie
Cookie[] cookies = req.getCookies(); //獲得Cookie
cookie.getName(); //獲得cookie中的key
cookie.getValue(); //獲得cookie中的vlaue
new Cookie("lastLoginTime", System.currentTimeMillis()+""); //新建一個cookie
cookie.setMaxAge(24*60*60); //設置cookie的有效期
resp.addCookie(cookie); //響應給客戶端一個cookie

cookie:一般會保存在本地的 用戶目錄下 appdata;

一個網站cookie是否存在上限!聊聊細節問題

  • 一個Cookie只能保存一個信息;
  • 一個web站點可以給瀏覽器發送多個cookie,最多存放20個cookie;
  • Cookie大小有限制4kb;
  • 300個cookie瀏覽器上限

刪除Cookie;

  • 不設置有效期,關閉瀏覽器,自動失效;
  • 設置有效期時間為 0 ;

編碼解碼:

URLEncoder.encode("秦疆","utf-8")
URLDecoder.decode(cookie.getValue(),"UTF-8")

7.4、Session(重點)

什麼是Session:

  • 伺服器會給每一個用戶(瀏覽器)創建一個Seesion對象;
  • 一個Seesion獨占一個瀏覽器,只要瀏覽器沒有關閉,這個Session就存在;
  • 用戶登錄之後,整個網站它都可以訪問!--> 保存用戶的信息;保存購物車的信息…..

Session和cookie的區別:

  • Cookie是把用戶的數據寫給用戶的瀏覽器,瀏覽器保存 (可以保存多個)
  • Session把用戶的數據寫到用戶獨占Session中,伺服器端保存 (保存重要的信息,減少伺服器資源的浪費)
  • Session對象由服務創建;

使用場景:

  • 保存一個登錄用戶的信息;
  • 購物車信息;
  • 在整個網站中經常會使用的數據,我們將它保存在Session中;

使用Session:

package com.kuang.servlet;

import com.kuang.pojo.Person;

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

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        //解決亂碼問題
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");
        
        //得到Session
        HttpSession session = req.getSession();
        //給Session中存東西
        session.setAttribute("name",new Person("秦疆",1));
        //獲取Session的ID
        String sessionId = session.getId();

        //判斷Session是不是新創建
        if (session.isNew()){
            resp.getWriter().write("session創建成功,ID:"+sessionId);
        }else {
            resp.getWriter().write("session以及在伺服器中存在了,ID:"+sessionId);
        }

        //Session創建的時候做了什麼事情;
//        Cookie cookie = new Cookie("JSESSIONID",sessionId);
//        resp.addCookie(cookie);

    }

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

//得到Session
HttpSession session = req.getSession();

Person person = (Person) session.getAttribute("name");

System.out.println(person.toString());

HttpSession session = req.getSession();
session.removeAttribute("name");
//手動註銷Session
session.invalidate();

會話自動過期:web.xml配置

<!--設置Session預設的失效時間-->
<session-config>
    <!--15分鐘後Session自動失效,以分鐘為單位-->
    <session-timeout>15</session-timeout>
</session-config>


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="htt ...
  • 使用原生JS實現輪播圖,僅需短短幾行代碼,代碼如下 當然,不可能這麼簡單,這裡我引入了自定義的 Carousel 類,是使用原生 JS 寫的,全部的代碼就不放出來了,只給出實現輪播的核心代碼 javascript // nextIndex 下一個 index change(nextIndex) { ...
  • 隨著前端項目複雜度的增加,其所依賴的資源也越來越多,從最初的HTML文件,CSS文件,JS文件發展到現在的各種預處理文件,模板文件等等。文件多了,項目大了,項目的維護就變得更加困難了,在這樣的背景下,webpack 這樣的打包工具就成了前段工程師必知必會的工具了。 ...
  • events.js:72 throw er; // Unhandled 'error' event ^Error: listen EADDRINUSE at errnoException (net.js:901:11) at Server._listen2 (net.js:1039:14) at l ...
  • 餓漢模式 懶漢模式(線程不安全) 懶漢模式(線程安全) 雙重檢查模式(DCL) 靜態內部類單例模式 枚舉類單例模式 使用容器實現單例模式 CAS實現單例模式 ...
  • 一、包含與刪除兩種方法解析 1.boolean contains(Object o);判斷集合中是否包含某個元素。 package com.bjpowernode.java_learning; import java.util.*; ​ public class D85_1_ContainsMeth ...
  • SpringBoot 簡介 springBoot 是 spring 團隊伴隨著 spring4.0 一同發佈的框架,已然成為該團隊的一個非常重要的項目。其作用是幫助我們簡單迅速地創建一個獨立的產品級別的基於 spring 的應用 為什麼要使用SpringBoot? J2EE笨重的開發、繁多的配置、低 ...
  • 策略模式 1.需求分析: 一個考試系統,當考生的成績通過後(成績大於60分)會通過各種方式通知用戶。 通知方式有:APP消息推送、簡訊、郵件、站內消息四種方式; 但是每種方式是否進行通知是要進行在表中配置的; 假設我們從表中查詢後的對象如下: 2.常規操作 最簡單的就是使用if else進行判斷了。 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:本文代碼示例演示瞭如何在WPF中使用LiveCharts庫創建動態條形圖。通過創建數據模型、ViewModel和在XAML中使用`CartesianChart`控制項,你可以輕鬆實現圖表的數據綁定和動態更新。我將通過清晰的步驟指南包括詳細的中文註釋,幫助你快速理解並應用這一功能。 先上效果: 在 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • 概述:本示例演示了在WPF應用程式中實現多語言支持的詳細步驟。通過資源字典和數據綁定,以及使用語言管理器類,應用程式能夠在運行時動態切換語言。這種方法使得多語言支持更加靈活,便於維護,同時提供清晰的代碼結構。 在WPF中實現多語言的一種常見方法是使用資源字典和數據綁定。以下是一個詳細的步驟和示例源代 ...
  • 描述(做一個簡單的記錄): 事件(event)的本質是一個委托;(聲明一個事件: public event TestDelegate eventTest;) 委托(delegate)可以理解為一個符合某種簽名的方法類型;比如:TestDelegate委托的返回數據類型為string,參數為 int和 ...
  • 1、AOT適合場景 Aot適合工具類型的項目使用,優點禁止反編 ,第一次啟動快,業務型項目或者反射多的項目不適合用AOT AOT更新記錄: 實實在在經過實踐的AOT ORM 5.1.4.117 +支持AOT 5.1.4.123 +支持CodeFirst和非同步方法 5.1.4.129-preview1 ...
  • 總說周知,UWP 是運行在沙盒裡面的,所有許可權都有嚴格限制,和沙盒外交互也需要特殊的通道,所以從根本杜絕了 UWP 毒瘤的存在。但是實際上 UWP 只是一個應用模型,本身是沒有什麼許可權管理的,許可權管理全靠 App Container 沙盒控制,如果我們脫離了這個沙盒,UWP 就會放飛自我了。那麼有沒... ...
  • 目錄條款17:讓介面容易被正確使用,不易被誤用(Make interfaces easy to use correctly and hard to use incorrectly)限制類型和值規定能做和不能做的事提供行為一致的介面條款19:設計class猶如設計type(Treat class de ...
  • title: 從零開始:Django項目的創建與配置指南 date: 2024/5/2 18:29:33 updated: 2024/5/2 18:29:33 categories: 後端開發 tags: Django WebDev Python ORM Security Deployment Op ...
  • 1、BOM對象 BOM:Broswer object model,即瀏覽器提供我們開發者在javascript用於操作瀏覽器的對象。 1.1、window對象 視窗方法 // BOM Browser object model 瀏覽器對象模型 // js中最大的一個對象.整個瀏覽器視窗出現的所有東西都 ...