Servlet:HelloServlet入門程序;Mapping配置;ServletContext;Response

Servlet

1、Servlet簡介

  • Servlet (Service Applet) 是在服務器上運行的小程序。
  • 廣義的Servlet是指任何實現了這個Servlet接口的類Servlet運行於支持Java的應用服務器中。從原理上講,Servlet可以響應任何類型的請求,但絕大多數情況下Servlet只用來擴展基於HTTP協議的Web服務器

2、HelloServlet

  • Java提供了兩個默認的Servlet接口實現類:
    • HttpServlet
    • GenericServlet
  1. 構建一個普通的Maven項目,刪掉裏面的src目錄,以後我們的學習就在這個項目裏面建立Moudel,這個空的工程就是Maven主工程

    • Maven父子工程

      父項目中會有

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

      子項目會有

          <parent>
              <artifactId>javaweb</artifactId>
              <groupId>com.study</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
      
  2. 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_4_0.xsd"
               version="4.0"
               metadata-complete="true">
      </web-app>
      
    2. 將maven的結構搭建完整

      創建 javaresources 文件夾

  3. 編寫一個Servlet程序
    在這裏插入圖片描述

  • 定義一個類,實現Servlet接口,這裏我們直接繼承HttpServlet

    public class HelloServlet extends HttpServlet {
    //由於get和post只是請求的不同的方式,所以doGet和doPost業務邏輯都一樣,可以相互調用
        @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 {
            doGet(req, resp);
        }
    }
    
  1. 編寫Servlet的映射

    <!--註冊Servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.study.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--Servlet的請求路徑-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
  2. 配置Tomcat服務器

  3. 啓動發佈

3、Servlet原理

在這裏插入圖片描述

4、Mapping配置

  • 一個Servlet可以指定一個映射路徑
	<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
  • 一個Servlet可以指定多個映射路徑
	<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>
  • 一個Servlet可以指定通配的映射路徑
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <!-- * 通配任意字符串-->
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>
  • 默認請求路徑
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
  • 指定後綴或前綴等
<!--
   注意點,*前面不能加項目映射的路徑
-->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.study</url-pattern>
</servlet-mapping>
  • 優先級問題:指定了固有的映射路徑優先級最高,如果找不到就會走默認的處理請求

5、ServletContext

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

5.1、共享數據

  • 即在一個Servlet中保存的數據,可以在另外一個servlet中拿到
public class HelloServlet extends HttpServlet {
	@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = "張三"; //數據
        //將一個數據保存在了ServletContext中,字段名:username 值 “張三”
        context.setAttribute("username",username); 
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 獲取保存在ServletContext中的數據
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);
    }
}
  • web.xml配置
<servlet>
	<servlet-name>hello</servlet-name>
	<servlet-class>com.study.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.study.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>getc</servlet-name>
    <url-pattern>/getc</url-pattern>
</servlet-mapping>
  • 測試訪問

    • 若直接訪問 http://localhost:8080/s2/getc ,由於username還未賦值,所以username=null;
      在這裏插入圖片描述

    • 先訪問 http://localhost:8080/s2/hello ,將數據存進ServletContext

    • 再訪問 http://localhost:8080/s2/getc
      在這裏插入圖片描述

5.2、獲取初始化參數

    <!--配置一些web應用初始化參數-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mydb</param-value>
    </context-param>
public class TestServlet 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);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 測試訪問:
    在這裏插入圖片描述

5.3、請求轉發

public class ForwardServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        // "/url" 5.2中的Servlet
        context.getRequestDispatcher("/url").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 測試訪問:
    在這裏插入圖片描述
  • 轉發過程:
    在這裏插入圖片描述

5.4、讀取資源文件

  • 在java目錄下新建properties文件

  • 在resources目錄下新建properties文件

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

  • 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>
  • prop.properties
username=root
password=123456
  • PropServlet.java
public class PropServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = getServletContext();
        InputStream resourceAsStream = context.getResourceAsStream("WEB-INF/classes/prop.properties");
        Properties properties = new Properties();
        properties.load(resourceAsStream);
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        resp.getWriter().print("<h1>"+username+"==="+password+"</h1>");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 測試訪問:
    在這裏插入圖片描述

6、Response

6.1、瀏覽器下載文件

public class FileDownloadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //需要下載的文件在服務器的路徑
        String filePath="D:\\IdeaProjects\\maven-javaweb-01\\Servlet-03\\src\\main\\resources\\背景.png";
        //文件名
        String fileName=filePath.substring(filePath.lastIndexOf('\\')+1);
        //設置使瀏覽器能夠支持下載(Content-Disposition)我們需要的東西,中文文件名需要設置編碼(URLEncoder.encode),否則有可能亂碼
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
        //創建讀取文件的輸入流
        FileInputStream in = new FileInputStream(filePath);
        //獲取輸出流
        ServletOutputStream out =resp.getOutputStream();
        //創建buffer緩衝區
        byte[] buffer = new byte[1024 * 8];
        int len=0;
        //將FileOutputStream流寫入到buffer緩衝區,使用OutputStream將緩衝區中的數據輸出到瀏覽器!
        while ((len=in.read(buffer))!=-1){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 測試訪問:
    在這裏插入圖片描述

6.2、創建一張圖片,在其中生成8位隨機數,並響應給瀏覽器

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(200, 40, BufferedImage.TYPE_INT_RGB);
        //獲取圖片
        Graphics2D g = (Graphics2D) image.getGraphics();
        //設置圖片背景顏色
        g.setColor(Color.cyan);
        g.fillRect(0,0,200,40);
        //在圖片中寫入數據
        g.setColor(Color.RED);
        g.setFont(new Font("華文彩雲",Font.BOLD,30));
        g.drawString(getNum(),20,30);
        //把圖片寫到瀏覽器
        ImageIO.write(image,"png",resp.getOutputStream());
    }

    private String getNum() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder(random.nextInt(99999999));
        int sbLen=sb.length();
        for (int i = 0; i < 8-sbLen; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 測試訪問:
    在這裏插入圖片描述

6.3、重定向

  • RedirectServlet.java
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //重定向
        resp.sendRedirect("/s3/success.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
<h1>redirect success!</h1>
</body>
</html>
  • 測試訪問:
    在這裏插入圖片描述

  • 重定向示意圖:
    在這裏插入圖片描述

  • 重定向和轉發的區別:

    • 重定向是兩次請求,轉發是一次請求,因此轉發的速度要快於重定向;

    • 重定向之後地址欄上的地址會發生變化,變化成第二次請求的地址,轉發之後地址欄上的地址不變,還是第一次請求的地址;

    • 轉發是服務器行爲,重定向是客戶端行爲;

    • 重定向時的網址可以是任何網址,轉發的網址必須是本站點的網址。

發佈了55 篇原創文章 · 獲贊 31 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章