天天看點

JavaWeb學習筆記(三)------ServletJavaWeb學習筆記(三)------Servlet

JavaWeb學習筆記(三)------Servlet

Servlet簡介

  • Servlet就是sun公司開發動态web的一門技術,sun公司在這些API中提供了一個接口,叫做Servlet。
  • 如果想要開發一個Servlet程式,隻需要完成兩個步驟:
    • 編寫一個類,實作Servlet接口
    • 把開發好的java類部署到web伺服器中
    • 把實作了Servlet接口的Java程式,叫做Servlet

HelloServlet

實作類

  • Servlet接口Sun公司有兩個預設的實作類:HttpServlet,GenericServlet
JavaWeb學習筆記(三)------ServletJavaWeb學習筆記(三)------Servlet
  • 建構一個普通的Maven項目,删掉裡面的src目錄,以後的學習在這個項目中建立Module。這個空的工程就是Maven的主工程

關于Maven父子工程的了解

  • 在父項目中會有
<modules>
    <module>servlet-01</module>
</modules>
           
  • 子項目中會有
<parent>
    <artifactId>javaweb-02-servlet</artifactId>
    <groupId>com.zmt</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
           
  • 父項目中的jar包,子項目可以直接使用,反過來不信

Maven環境優化

  • 修改web.xml為最新的
  • 将maven的環境搭建完整

編寫一個Servlet接口

  • 編寫一個普通類
  • 實作Servlet接口,直接繼承HttpServlet
public class HelloServlet extends HttpServlet {
    //由于get或者post隻是請求實作的不同的方式,可以互相調用,因為業務邏輯都一樣
    //重寫的post方法調用了get方法,是以直接重寫get方法即可
    //用get調post同理
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletInputStream inputStream = req.getInputStream();
        //ServletOutputStream outputStream = resp.getOutputStream();
        System.out.println("進入doGet方法");
        PrintWriter writer = resp.getWriter();  //響應流

        writer.print("Hello,Servlet");
    }

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

編寫Servlet的映射

  • 為什麼需要映射?
  • 因為我們寫的是Java程式,但是要通過浏覽器通路,而浏覽器需要連接配接web伺服器,是以我們需要在web服務中注冊我們寫的Servlet,還需要給他一個浏覽器能夠通路的路徑
  • 在web.xml中進行配置
<!--注冊Servlet servlet檔案對應的名字-->
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.zmt.servlet.HelloServlet</servlet-class>
  </servlet>
  <!--Servlet的請求路徑,url-pattern:在位址欄請求的網絡接口  servlet-name:請求的servlet -->
  <!--配置url-pattern,一定要在前面加/,不然會出錯 -->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
           

配置tomcat

  • 注意:配置項目釋出的路徑就可以了

啟動測試

  • 成功
  • 注意:Tomcat下配置的Artifacts檔案,要和項目檔案名一樣,否則産生的war包有問題

Servlet運作原理

  • Servlet是由Web伺服器調用,web伺服器在收到浏覽器請求之後,會:
JavaWeb學習筆記(三)------ServletJavaWeb學習筆記(三)------Servlet

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>/hello</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello1</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>*.abc</url-pattern>
  </servlet-mapping>
           
  • 預設請求路徑(盡量不用)
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
           

優先級問題

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

ServletContext

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

共享資料

  • 我在這個Servlet中儲存的資料,可以在另外一個Servlet中拿到
JavaWeb學習筆記(三)------ServletJavaWeb學習筆記(三)------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 = "zmt";  //資料

        //将一個資料儲存在 ServletContext中,鍵值對形式,
        //名字為:username 值zmt
        context.setAttribute("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 {
        doGet(req, resp);
    }
}
           
  • XML檔案
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.zmt.servlet.HelloServlet</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>get</servlet-name>
    <servlet-class>com.zmt.servlet.GetServlet</servlet-class>
  </servlet>

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

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

</web-app>
           
  • 測試通路結果

擷取初始化參數

  • 在web.xml中進行初始化配置
<web-app>
  <display-name>Archetype Created Web Application</display-name>

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

  <servlet>
    <servlet-name>gp</servlet-name>
    <servlet-class>com.zmt.servlet.ServletDemo03</servlet-class>
  </servlet>

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

</web-app>
           
  • 擷取初始配置
public class ServletDemo03 extends HelloServlet{
    @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);
    }
}
           

請求轉發

  • 請求轉發,路徑不會發生變化
public class ServletDemo04 extends HelloServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        System.out.println("進入Demo04");

        //請求轉發 /gp為轉發的請求路徑
        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");
        //調用forward實作請求轉發,轉發時,路徑不會變
        requestDispatcher.forward(req,resp);
        //  合并也可以實作 context.getRequestDispatcher("/gp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
           
  • XML檔案
<web-app>
  <display-name>Archetype Created Web Application</display-name>

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

  <servlet>
    <servlet-name>gp</servlet-name>
    <servlet-class>com.zmt.servlet.ServletDemo03</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>sd4</servlet-name>
    <servlet-class>com.zmt.servlet.ServletDemo04</servlet-class>
  </servlet>

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

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

</web-app>
           
  • 本質上A和B産生練習,由B去C處擷取資訊,是以路徑沒有發生變化
JavaWeb學習筆記(三)------ServletJavaWeb學習筆記(三)------Servlet

讀取資源檔案

  • 在java目錄下,建立proterties
  • 在resources目錄下,建立proterties
  • 都被打包在同一路徑下:target——servlet-02——WEB-INF——classes
  • 俗稱該路徑為:classpath,類路徑
  • 思路:需要一個檔案流
  • 在build中配置resources,來防止我們資源導出失敗的問題
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
           
  • 具體實作
public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //  ”/“代表目前web項目,即跳轉到tomcat檔案中webapps中的本項目目錄下
        //  本項目名為tomcat中Application Context設定值
        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);
    }
}
           
  • Properties
username = root
password = 123456
           
  • 測試通路結果