Java Web之Servlet技術


 1、Servlet基礎

  針對Servlet技術開發,Sun公司提供了一些列接口和類,其中最重要的是javax.servlet.Servlet接口,兩個重要的包是javax.servlet和javax.servlet.http,Servlet就是一種實現了Servlet接口的類,它由Web容器(Tomcat/Jetty等)負責調用並創建,用於接收和響應用戶請求。Servlet接口中定義了5個抽象方法:

方法 功能
void init(ServletConfig config)

負責Servlet初始化工作,容器在創建好Servlet對象后就調用此方法。該方法接受一個

ServletConfig 類參數,Servlet容器通過這個參數向Servlet傳遞配置信息

ServletConfig getServletConfig() 返回容器調用init(ServletConfig config)時傳遞的ServletConfig 對象
void service(ServletRequest req, ServletResponse res)

負責響應用戶的請求,當接收到客戶端訪問Servlet對象的請求時就會調用此方法。

容器會構造一個ServletRequest和ServletResponse對象作為參數傳遞到該方法中,

在該方法中通過ServletRequest對象獲取請求信息,對請求處理完成后,通過

ServletResponse對象設置響應消息

String getServletInfo()

返回一個字符串,包含Servlet信息。注意,該方法自己需要重定義,在GenericServlet

類中該方法返回空字符串

void destroy() 負責釋放Servlet對象占用的資源,當Servlet對象被銷毀時,容器會調用該函數

Servlet頂層類結構如下所示:

2、第一個Servlet程序

  新建一個Java Web工程,然后新建Hello類,Hello.java源碼如下:

package zzz;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Hello extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 設置響應消息編碼
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("Hello World");
    }
    
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        this.doGet(request, response);
    }
}

  配置文件web.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    <display-name>zzz</display-name>

  <servlet> <!-- 注冊Servlet -->
      <servlet-name>Hello</servlet-name> <!-- 指定Servlet名稱 -->
      <servlet-class>zzz.Hello</servlet-class> <!-- 指定Servlet完整類名 -->
  </servlet>
  <servlet-mapping> <!-- 映射Servlet對外訪問路徑 -->
      <servlet-name>Hello</servlet-name> <!-- 指定Servlet名稱 -->
      <url-pattern>/hello</url-pattern> <!-- 指定訪問Servlet的虛擬路徑 -->
  </servlet-mapping>
</web-app>

  啟動運行瀏覽器顯示如下:

3、Servlet生命周期

   Servlet生命周期大致分為3個階段,初始化階段、運行階段和銷毀階段。以下是各個階段詳細說明:

  • 初始化階段:客戶端向Servlet容器發出請求訪問Servlet時,容器首先解析請求,查看內存中是否有該Servlet對象,如果有直接使用;否則創建該Servlet對象,然后調用init()方法,注意,Servlet整個聲明周期中,init()只會調用一次
  • 運行階段:這個是Servlet最重要的階段,此階段容器會構造一個ServletRequest和ServletResponse對象作為參數傳遞到Servlet的service()方法中。對於Servlet的每一次訪問,Servlet容器都會調用一次service()方法,service()方法在Servlet整個生命周期中會被調用多次
  • 銷毀階段:當服務器關閉或者Web應用被移除出容器時,會進入到此階段,此時會調用destroy()方法,整個生命周期中destroy()方法只會被調用一次

  在客戶端首次訪問Servlet時,容器會創建該Servlet對象,但是有時希望Servlet對象在Tomcat啟動時跟隨啟動,這怎么處理呢?此時,只需要在web.xml中使用<load-on-startup>元素即可,示例配置如下:

<servlet>
      <servlet-name>Hello</servlet-name>
      <servlet-class>zzz.Hello</servlet-class>
    <!-- 自動加載servlet程序 -->
    <load-on-startup>1</load-on-startup> 
  </servlet>
  <servlet-mapping>
      <servlet-name>Hello</servlet-name>
      <url-pattern>/hello</url-pattern>
  </servlet-mapping>

 4、ServletConfig和ServletContext

ServletConfig接口

  Servlet運行期間,如果需要一些輔助信息,例如文件編碼、使用Servlet的公司等,這些信息可以在web.xml中使用<init-param>元素進行配置,當Tomcat初始化一個Servlet時,會將該Servlet配置信息封裝成一個ServletConfig對象通過init(ServletConfig config)傳遞到Servlet。ServletConfig定義了一系列獲取配置信息的方法:

方法 功能
String getServletName() 返回Servlet名字,即web.xml中<servlet-name>中的值
ServletContext getServletContext() 返回代表當前Web應用的ServletContext對象
String getInitParameter(String name) 根據參數名返回對應的參數值,如果未找到返回null
Enumeration<String> getInitParameterNames() 返回一個Enumeration對象,其中包含所有的初始化參數

  接下來以getInitParameter()為例,講解該方法使用示例:

web.xml配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    <display-name>zzz</display-name>

  <servlet>
      <servlet-name>Hello</servlet-name>
      <servlet-class>zzz.Hello</servlet-class>
      <init-param>
          <param-name>company</param-name>
          <param-value>dahua</param-value>
      </init-param>
  </servlet>
  <servlet-mapping>
      <servlet-name>Hello</servlet-name>
      <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

Hello.java文件如下:

package zzz;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Hello extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 設置響應消息編碼
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        
        ServletConfig config = this.getServletConfig();
        String param = config.getInitParameter("company");
        out.println("company: " + param);
    }
    
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        this.doGet(request, response);
    }
}

 ServletContext接口

  當Servlet容器啟動時,會為每一個Web應用創建一個唯一的ServletContext對象代表當前Web應用,該對象不僅封裝了該Web應用的所有信息,而且實現了多個Servlet對象間的數據共享。在web.xml中不僅可以配置Servlet的初始化信息,還可以配置整個Web應用的初始化信息,配置方式如下所示:

<context-param>
    <param-name>name</param-name>
    <param-value>luoxn28</param-value>
</context-param>
<context-param>
    <param-name>company</param-name>
    <param-value>dahua</param-value>
</context-param>

  注意:一個<context-param>元素里只能有一個<param-name>和<param-value>,上面的配置在web.xml中<web-app>下配置。Hello.java文件如下:

package zzz;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Hello extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 設置響應消息編碼
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        
        ServletContext context = this.getServletContext();
        Enumeration<String> paramNames = context.getInitParameterNames();
        while (paramNames.hasMoreElements()) {
            String name = paramNames.nextElement();
            String value = context.getInitParameter(name);
            out.println(name + ": " + value + "<br/>");
        }
    }
    
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        this.doGet(request, response);
    }
}

 

  由於一個Web應用中所有Servlet共享一個ServletContext對象,所以ServletContext對象的域屬性可以被Web應用中所有的Servlet訪問。在ServletContext接口中定義了分別增加、刪除、設置ServletContext域屬性的4個方法:

方法 功能
Object getAttribute(String name) 根據指定參數獲取一個匹配的域屬性值
Enumeration<String> getAttributeNames() 返回一個Enumeration對象,包含所有存放在ServletContext中所有域屬性名
void setAttribute(String name, Object object) 設置ServletContext域屬性值,name-域屬性名,object-域屬性值
void removeAttribute(String name) 根據指定的域屬性名從ServletContext中移除域屬性

  通過以上方法就可以實現多個Servlet間共享數據,這個具體實例就不貼代碼了,網上可參考的資料很多,比如可以點擊javaweb學習總結(六)——Servlet開發(二)

5、參考資料

  1、《Java Web程序開發入門》Servlet技術章節

  2、javaweb學習總結(六)——Servlet開發(二)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM