1. 程式人生 > 資訊 >聯想小新 Air 14/15 2021 酷睿版配置公佈:i5-1155G7+16GB 記憶體,配備全功能 USB-C 介面

聯想小新 Air 14/15 2021 酷睿版配置公佈:i5-1155G7+16GB 記憶體,配備全功能 USB-C 介面

Servlet

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

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

  1. 編寫一個類,實現Servlet介面

  2. 把開發好的java類部署到web伺服器中

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

HelloServlet

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

2、關於Maven父子工程的理解

父專案中會有

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

子專案中會有

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

父專案中的jar 子專案可以直接使用

3、Maven環境優化

1、修改web.xml為最新的 (內容是tomcat的webapps/root/WEB-INF/web.xml)

2、將maven的結構搭建完整

4、編寫一個servlet程式

1、編寫一個普通類

2、實現Servlet嗟闊,這裡我們直接繼承HttpServlet

public class HelloServlet extends HttpServlet {
    //由於get或者post只是請求實現的不同方式,可以相互呼叫,業務邏輯都一樣
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        PrintWriter writer 
= resp.getWriter();//響應流 writer.print("hello,servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }

5、編寫Servlet的對映

為什麼需要對映:我們寫的是java程式,但是要 通過瀏覽器訪問,而瀏覽器需要連線web伺服器,所以我們需要在web服務中註冊我們寫的servlet,還需給它一個瀏覽器能夠訪問的路徑

<!--註冊Servlet-->
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.cheng.servlet.HelloServlet</servlet-class>
  </servlet>
  <!--Servlet的請求路徑-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

6、配置Tomcat

7、啟動測試

Maven由於“約定大於配置”的特性,可能會遇到配置檔案無法匯出或者無法生效的問題。在核心配置檔案pom.xml新增如下程式碼。

<!--在build中配置resoureces,來防止我們資源匯出失效的問題-->
<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>

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>/hello1</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>

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/sdsds.miaomiao-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.miaomiao</url-pattern>
  </servlet-mapping>

6、優先順序問題

指定了固有的對映路徑優先順序最高,如果找不到就會走預設的處理請求

<!--404-->
  <servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.cheng.servlet.ErrorServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
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("<h1>404</h1>");
    }

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

ServletContext

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

共享資料

我在這個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

        System.out.println("Hello");
    }
}
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 {
        super.doPost(req, resp);
    }
}


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

獲取初始化引數

<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
  </context-param>
 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        resp.getWriter().print(url);
    }

請求轉發

 @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);
    }

讀取資原始檔

propertie

  • 在java目錄下新建properties

  • 在resources目錄下新建properties

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

思路:需要一個檔案流

username=root 
password=1235465
public class ServletDemo05 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 {
    }
}

訪問測試即可

HttpServletResponse

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

如果要獲取客戶端請求過來的引數,找HttpServletRequest

如果要給客戶端響應一些資訊,找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 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;

常見應用

1、向瀏覽器傳送訊息

2、下載檔案

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 {
        //獲取下載檔案的路徑
        String realPath = "F:\\JavaProjects\\javaweb-servlet\\response\\src\\main\\resources\\test1.jpg";
        System.out.println("下載檔案的路徑"+realPath);
        //下載的檔名
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
        //設定讓瀏覽器能夠支援下載我們需要的東西(web下載檔案的頭訊息)
        resp.setHeader("Content-Disposition","attachment;filename"+URLEncoder.encode(fileName,"UTF-8"));
        //獲取下載檔案的輸入流
        FileInputStream in = new FileInputStream(realPath);
        //建立緩衝區
        int len=0;
        byte[] buffer = new byte[1024];
        //獲取outputStream物件
        ServletOutputStream out = resp.getOutputStream();
        //將FileoutputStream流寫入到buffer緩衝區,使用outputstream將緩衝區中的資料輸出到客戶端
        while((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        //關閉流
        in.close();
        out.close();

    }

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

3、驗證碼功能

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 {
        //如何讓瀏覽器5秒自動重新整理以此
        resp.setHeader("refresh","3");
        //在記憶體中建立一個圖片
        BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_3BYTE_BGR);
        //得到圖片
        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(99999999)+"";
        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 {
        super.doGet(req, resp);
    }
}

4、實現重定向

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

void sendRedirect(String var1) throws IOException;

測試

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

重定向和轉發的區別?


  • 相同點: 頁面都會實現跳轉


不同點:


  • 請求轉發的時候,url不會產生變化

  • 重定向的時候,url位址列會發生變化


cookie、session

會話:使用者開啟一個瀏覽器,點選了很多超連結,訪問多個web資源,關閉瀏覽器,這個過程可以稱之為會話

有狀態會話

1、伺服器給客戶端一個信件,客戶端下次訪問伺服器帶上信件就可以了,cookie

2、伺服器登記你來過,下次你來的時候我來匹配你,session

儲存會話的兩種技術

cookie

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

1、從請求中拿到cookie資訊

2、伺服器響應給客戶端cookie

Cookie[] cookies = req.getCookies();//獲得cookie
cookie.getName();//獲得cookie中的key
cookie.getValue();//獲得cookie中的value
new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一個cookie
cookie.setMaxAge(24*60*60);//設定cookie的有效期
resp.addCookie(cookie);//響應給客戶端一個cookie
//儲存使用者上一次訪問的時間
public class CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        PrintWriter out = resp.getWriter();

        //cookie ,伺服器端從客戶端獲取
        Cookie[] cookies = req.getCookies();//返回陣列,說明cookie可能存在多個
        //判斷cookie是否存在
        if(cookies!=null){
            //如果存在
            out.write("您上一次訪問的時間是:");
            for(int i=0;i<cookies.length;i++){
               Cookie cookie= cookies[i];
               //獲取cookie的名字
                if(cookie.getName().equals("lastLoginTime")){
                    //獲取cookie中的值
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.write(date.toLocaleString());
                }
            }
        }else{
            out.write("這是您第一次訪問本站");
        }
        //伺服器給客戶端響應一個cookie
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
        //cookie有效期為1天
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);
    }

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

cookie一般會儲存在本地的使用者目錄下appdata

session

伺服器技術,利用這個技術,可以儲存使用者的會話資訊,我們可以把資訊或者資料放在session中

  • 伺服器會給每一個使用者(瀏覽器)建立一個session物件

  • 一個session獨佔一個瀏覽器,只要瀏覽器沒有關閉,這個session就存在

  • 使用者登入後,整個網站它都可以訪問

session和cookie的區別

  • cookie是把使用者的資料寫給使用者的瀏覽器,瀏覽器儲存(可以儲存多個)

  • session把使用者的資料寫到使用者獨佔session中,伺服器端儲存(儲存重要的資訊,減少伺服器資源的浪費)

  • session物件由伺服器建立

使用場景:

  • 儲存一個登入使用者的資訊

  • 購物車資訊

  • 在整個網站中經常使用的資料,我們將它儲存在session中

使用session

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","喵喵");
        //獲取session的id
        String sessionId = session.getId();
        //判斷session是不是新建立的
        if(session.isNew()){
            resp.getWriter().write("session建立成功,ID:"+sessionId);

        }else {
            resp.getWriter().write("session已經在伺服器中存在,ID:"+sessionId);
        }
    }

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

//得到session
        HttpSession session= req.getSession();
        Person person = session.getAttribute("name");
        System.out.println( person.toString());

//手動登出session
        HttpSession session= req.getSession();
        session.removeAttribute("name");
        session.invalidate();

會話自動過期 web.xml

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

JSP

瀏覽器向伺服器傳送請求,不管訪問什麼資源,其實都是在訪問servlet

jsp最終也會被轉換成一個java類

<%--JSP表示式
   作用:用來將程式的輸出,輸出到客戶端--%>
  <%= new java.util.Date()%>
  <hr>
  <%--jsp指令碼片段--%>
  <%
    int sum=0;
    for (int i = 0; i < 100; i++) {
      sum+=i;
    }
    out.print("<h1>Sum="+sum+"</h1>");
  %>
  <%--在程式碼中嵌入HTML元素--%>
  <%
    for (int i = 0; i < 5; i++) {
  %>
  <h1>hello</h1>
  <%
    }
  %>

  <hr>
  <%--jsp宣告--%>
  <%!
    static {
      System.out.println("loading servlet");
    }
    private int globalVar=0;
    public void miao(){
      System.out.println("進入了方法miao");
    }
  %>

jsp宣告會被編譯到JSP生成的java的類中,其他就會被生成到jspService方法中

在jsp中嵌入java程式碼即可

jsp的註釋,不會在客戶端顯示,html就會

9大內建物件

PageContext 存東西

Request 存東西

Response

Session 存東西

Application [ServletContext ] 存東西

config [ServletConfig]

out

page 不用

exception

  pageContext.setAttribute("name1","喵喵1號");//儲存的資料只在一個頁面中有效
    request.setAttribute("name2","喵喵2號");//儲存的資料只在一次請求中有效,請求轉發會攜帶這個資料
    session.setAttribute("name2","喵喵2號");//儲存的資料只在一次會話中有效,從開啟瀏覽器到關閉瀏覽器
    application.setAttribute("name2","喵喵2號");//儲存的資料只在伺服器中有效,從開啟伺服器到關閉伺服器

request:客戶端向伺服器傳送請求,產生的資料,使用者看完就沒用了。比如新聞

session:客戶端向伺服器傳送請求,產生的資料,使用者用完一會兒還有用,比如購物車

application:客戶端向伺服器傳送請求,產生的資料,一個使用者用完了,其他使用者還可以使用,比如聊天資料

JSP標籤、JSTL標籤、EL表示式

 <!--jstl表示式的依賴-->
    <dependency>
        <groupId>javax.servlet.jsp.jstl</groupId>
        <artifactId>jstl-api</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
    </dependency>

EL表示式: ${}

  • 獲取資料

  • 執行運算

  • 獲取web開發的常用物件

JSP標籤

 <jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name" value="miaomiao"></jsp:param>

JSTL標籤

<%--引入JSTL核心標籤庫,我們才能使用JSTL標籤--%>
<%@taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core" %>
<form action="jsptag2.jsp" method="get">
    <%--EL表示式獲取表單中的資料--%>
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="登入">
    
    <c:if test="${param.username='admin'}" var="isAdmin">
    <c out value="管理員歡迎您"/>
</c:if>
    <c: out value="${isAdmin}"/>

JavaBean

實體類

  • JavaBean有特定的寫法

  • 必須要有一個無參構造

  • 屬性必須私有化

  • 必須有對應的get/set方法

一般用來和資料庫的欄位作對映