1. 程式人生 > >Java Web 學習與總結(二)Servlet核心介面+Servlet3.0配置

Java Web 學習與總結(二)Servlet核心介面+Servlet3.0配置

  Servlet3.0版本對Servlet配置進行了重大變革,Servlet類不需要再麻煩的去編輯web.xml檔案了,只需要在類上面進行註釋就可以了,獲得了 Java 社群的一片讚譽之聲,以下是新增的註解支援

@WebServlet

@WebServlet 用於將一個類宣告為 Servlet,該註解將會在部署時被容器處理,容器將根據具體的屬性配置將相應的類部署為 Servlet。該註解具有下表給出的一些常用屬性(以下所有屬性均為可選屬性,但是 vlaue 或者 urlPatterns 通常是必需的,且二者不能共存,如果同時指定,通常是忽略 value 的取值):

表 1. @WebServlet 主要屬性列表

下面是一個簡單的示例:

1 2 3 4 5 @WebServlet(urlPatterns = {"/simple"}, asyncSupported = true, loadOnStartup = -1, name = "SimpleServlet", displayName = "ss", initParams = {@WebInitParam(name = "username", value = "tom")} ) public class SimpleServlet extends HttpServlet{ … }

如此配置之後,就可以不必在 web.xml 中配置相應的 <servlet> 和 <servlet-mapping> 元素了,容器會在部署時根據指定的屬性將該類釋出為 Servlet。它的等價的 web.xml 配置形式如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <servlet>     <display-name>ss</display-name>     <servlet-name>SimpleServlet</servlet-name>     <servlet-class>footmark.servlet.SimpleServlet</servlet-class>     <load-on-startup>-1</load-on-startup>     <async-supported>true</async-supported>     <init-param>         <param-name>username</param-name>         <param-value>tom</param-value>     </init-param> </servlet> <servlet-mapping>     <servlet-name>SimpleServlet</servlet-name>     <url-pattern>/simple</url-pattern> </servlet-mapping>

@WebInitParam

該註解通常不單獨使用,而是配合 @WebServlet 或者 @WebFilter 使用。它的作用是為 Servlet 或者過濾器指定初始化引數,這等價於 web.xml 中 <servlet> 和 <filter> 的 <init-param> 子標籤。@WebInitParam 具有下表給出的一些常用屬性:

表 2. @WebInitParam 的常用屬性

@WebFilter

@WebFilter 用於將一個類宣告為過濾器,該註解將會在部署時被容器處理,容器將根據具體的屬性配置將相應的類部署為過濾器。該註解具有下表給出的一些常用屬性 ( 以下所有屬性均為可選屬性,但是 value、urlPatterns、servletNames 三者必需至少包含一個,且 value 和 urlPatterns 不能共存,如果同時指定,通常忽略 value 的取值 ):

表 3. @WebFilter 的常用屬性

下面是一個簡單的示例:

1 2 @WebFilter(servletNames = {"SimpleServlet"},filterName="SimpleFilter") public class LessThanSixFilter implements Filter{...}

如此配置之後,就可以不必在 web.xml 中配置相應的 <filter> 和 <filter-mapping> 元素了,容器會在部署時根據指定的屬性將該類釋出為過濾器。它等價的 web.xml 中的配置形式為:

1 2 3 4 5 6 7 8 <filter>     <filter-name>SimpleFilter</filter-name>     <filter-class>xxx</filter-class> </filter> <filter-mapping>     <filter-name>SimpleFilter</filter-name>     <servlet-name>SimpleServlet</servlet-name> </filter-mapping>

@WebListener

該註解用於將類宣告為監聽器,被 @WebListener 標註的類必須實現以下至少一個介面:

  • ServletContextListener
  • ServletContextAttributeListener
  • ServletRequestListener
  • ServletRequestAttributeListener
  • HttpSessionListener
  • HttpSessionAttributeListener

該註解使用非常簡單,其屬性如下:

表 4. @WebListener 的常用屬性

一個簡單示例如下:

1 2 @WebListener("This is only a demo listener") public class SimpleListener implements ServletContextListener{...}

如此,則不需要在 web.xml 中配置 <listener> 標籤了。它等價的 web.xml 中的配置形式如下:

1 2 3 <listener>     <listener-class>footmark.servlet.SimpleListener</listener-class> </listener>

@MultipartConfig

該註解主要是為了輔助 Servlet 3.0 中 HttpServletRequest 提供的對上傳檔案的支援。該註解標註在 Servlet 上面,以表示該 Servlet 希望處理的請求的 MIME 型別是 multipart/form-data。另外,它還提供了若干屬性用於簡化對上傳檔案的處理。具體如下:

表 5. @MultipartConfig 的常用屬性
以上引用於 https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/index.html   Servlet核心介面:   在Servlet體系結構中,除了用於實現Servlet的Servlet介面,GenericServlet類和HttpServlet類外,還有一些輔助Servlet獲取相關資源資訊的重要介面,瞭解這些介面的作用並熟練掌握這些介面的常用方法是使用Servlet進行Web應用開發的基礎,下面我將介紹以下幾種介面:   1.ServletConfig介面:用於獲取Servlet初始化引數和ServletContext物件;
 1 //
 2 // Source code recreated from a .class file by IntelliJ IDEA
 3 // (powered by Fernflower decompiler)
 4 //
 5 
 6 package javax.servlet;
 7 
 8 import java.util.Enumeration;
 9 
10 public interface ServletConfig {
11     String getServletName();
12 
13     ServletContext getServletContext();
14 
15     String getInitParameter(String var1);
16 
17     Enumeration<String> getInitParameterNames();
18 }
ServletConfig介面的主要方法: getInitParameter(String param); 根據給定的初始化引數名稱,返回引數值,若引數不存在,返回null getInitParameterNames():返回一個列舉集合物件,裡面包含了所有的初始化引數名稱 getServletContext():返回當前ServletContext()物件 getServletName():返回當前Servlet的名字,即@WebServlet的name屬性值。如果沒有配置這個屬性,則返回Servlet類的全限定名(絕對路徑)   2.ServletContext介面:
  1 //
  2 // Source code recreated from a .class file by IntelliJ IDEA
  3 // (powered by Fernflower decompiler)
  4 //
  5 
  6 package javax.servlet;
  7 
  8 import java.io.InputStream;
  9 import java.net.MalformedURLException;
 10 import java.net.URL;
 11 import java.util.Enumeration;
 12 import java.util.EventListener;
 13 import java.util.Map;
 14 import java.util.Set;
 15 import javax.servlet.ServletRegistration.Dynamic;
 16 import javax.servlet.descriptor.JspConfigDescriptor;
 17 
 18 public interface ServletContext {
 19     String TEMPDIR = "javax.servlet.context.tempdir";
 20     String ORDERED_LIBS = "javax.servlet.context.orderedLibs";
 21 
 22     String getContextPath();
 23 
 24     ServletContext getContext(String var1);
 25 
 26     int getMajorVersion();
 27 
 28     int getMinorVersion();
 29 
 30     int getEffectiveMajorVersion();
 31 
 32     int getEffectiveMinorVersion();
 33 
 34     String getMimeType(String var1);
 35 
 36     Set<String> getResourcePaths(String var1);
 37 
 38     URL getResource(String var1) throws MalformedURLException;
 39 
 40     InputStream getResourceAsStream(String var1);
 41 
 42     RequestDispatcher getRequestDispatcher(String var1);
 43 
 44     RequestDispatcher getNamedDispatcher(String var1);
 45 
 46     /** @deprecated */
 47     @Deprecated
 48     Servlet getServlet(String var1) throws ServletException;
 49 
 50     /** @deprecated */
 51     @Deprecated
 52     Enumeration<Servlet> getServlets();
 53 
 54     /** @deprecated */
 55     @Deprecated
 56     Enumeration<String> getServletNames();
 57 
 58     void log(String var1);
 59 
 60     /** @deprecated */
 61     @Deprecated
 62     void log(Exception var1, String var2);
 63 
 64     void log(String var1, Throwable var2);
 65 
 66     String getRealPath(String var1);
 67 
 68     String getServerInfo();
 69 
 70     String getInitParameter(String var1);
 71 
 72     Enumeration<String> getInitParameterNames();
 73 
 74     boolean setInitParameter(String var1, String var2);
 75 
 76     Object getAttribute(String var1);
 77 
 78     Enumeration<String> getAttributeNames();
 79 
 80     void setAttribute(String var1, Object var2);
 81 
 82     void removeAttribute(String var1);
 83 
 84     String getServletContextName();
 85 
 86     Dynamic addServlet(String var1, String var2);
 87 
 88     Dynamic addServlet(String var1, Servlet var2);
 89 
 90     Dynamic addServlet(String var1, Class<? extends Servlet> var2);
 91 
 92     Dynamic addJspFile(String var1, String var2);
 93 
 94     <T extends Servlet> T createServlet(Class<T> var1) throws ServletException;
 95 
 96     ServletRegistration getServletRegistration(String var1);
 97 
 98     Map<String, ? extends ServletRegistration> getServletRegistrations();
 99 
100     javax.servlet.FilterRegistration.Dynamic addFilter(String var1, String var2);
101 
102     javax.servlet.FilterRegistration.Dynamic addFilter(String var1, Filter var2);
103 
104     javax.servlet.FilterRegistration.Dynamic addFilter(String var1, Class<? extends Filter> var2);
105 
106     <T extends Filter> T createFilter(Class<T> var1) throws ServletException;
107 
108     FilterRegistration getFilterRegistration(String var1);
109 
110     Map<String, ? extends FilterRegistration> getFilterRegistrations();
111 
112     SessionCookieConfig getSessionCookieConfig();
113 
114     void setSessionTrackingModes(Set<SessionTrackingMode> var1);
115 
116     Set<SessionTrackingMode> getDefaultSessionTrackingModes();
117 
118     Set<SessionTrackingMode> getEffectiveSessionTrackingModes();
119 
120     void addListener(String var1);
121 
122     <T extends EventListener> void addListener(T var1);
123 
124     void addListener(Class<? extends EventListener> var1);
125 
126     <T extends EventListener> T createListener(Class<T> var1) throws ServletException;
127 
128     JspConfigDescriptor getJspConfigDescriptor();
129 
130     ClassLoader getClassLoader();
131 
132     void declareRoles(String... var1);
133 
134     String getVirtualServerName();
135 
136     int getSessionTimeout();
137 
138     void setSessionTimeout(int var1);
139 
140     String getRequestCharacterEncoding();
141 
142     void setRequestCharacterEncoding(String var1);
143 
144     String getResponseCharacterEncoding();
145 
146     void setResponseCharacterEncoding(String var1);
147 }
  ServletContext也成為Servlet上下文,代表當前Servlet執行環境,是Servlet與Servlet容器之間直接通訊的介面。Servlet容器在啟動一個Web應用時,會為該應用建立一個唯一的ServletContext物件供該應用中所有的Servlet物件共享,Servlet物件可以通過ServletContext物件來訪問容器的各種資源。   獲取ServletContext物件可以通過ServletConfig介面或者Generic抽象類中的getServletContext()方法   ServletContext介面中提供了以下幾種型別的方法:     獲取應用範圍的初始化引數的方法:       getInitParameter(String param); 根據給定的初始化引數名稱,返回引數值,若引數不存在,返回null       getInitParameterNames():返回一個列舉集合物件,裡面包含了所有的初始化引數名稱     存取應用範圍域屬性的方法:       setAttribute(String name,Object obj)把一個物件和一個屬性名以key+value的形式繫結並存放在ServletContext中       getAttribute(String name) 返回用上一方法中存的物件,根據其對應的屬性名       getAttributeNames():返回一個列舉集合物件,該物件包含了所有存放在ServletContext中的屬性名       removeAttribute(String name):同getAttribute()方法相反,刪除一個匹配的物件     獲取當前Web應用資訊的方法:       getContextPath():返回當前web應用的根路徑       getServletContextName():返回web應用的名字,即<web-app>中<display-name>元素的值       getRequestDispatcher(String path):返回一個用於其他web元件轉發請求的RequestDispatcher物件       getContext(Srting uripath):根據引數制定的URL返回當前Servlet容器中其他web應用的ServletContext物件,URL必須時以“/”開頭的絕對路徑     獲取當前容器資訊和輸出日誌的方法:       getServletInfo():返回Web容器的名字和版本       getMajorVersion():返回Web容器支援的Servlet API主版本號       getMinorVersion():返回Web容器支援的Servlet API次版本號       log(String msg):用於記錄一般的日誌       log(String msg throwable):用於記錄帶異常型別的日誌     獲取伺服器端檔案資源的方法:       getResourceAsStream(String path):返回一個讀取引數指定的檔案的輸入流,引數路徑必須以“/”開頭       getResouce(String path):返回由path指定的的資源路徑對應的一個URL物件,引數路徑必須以“/”開頭       getRealPath(String path):根據引數指定的虛擬路徑,返回檔案系統中的一個真實的路徑       getMimeType(String path):返回引數指定的檔案的MIME型別   3.HttpServletRequest介面
  1 //
  2 // Source code recreated from a .class file by IntelliJ IDEA
  3 // (powered by Fernflower decompiler)
  4 //
  5 
  6 package javax.servlet.http;
  7 
  8 import java.io.IOException;
  9 import java.security.Principal;
 10 import java.util.Collection;
 11 import java.util.Collections;
 12 import java.util.Enumeration;
 13 import java.util.Map;
 14 import javax.servlet.ServletException;
 15 import javax.servlet.ServletRequest;
 16 
 17 public interface HttpServletRequest extends ServletRequest {
 18     String BASIC_AUTH = "BASIC";
 19     String FORM_AUTH = "FORM";
 20     String CLIENT_CERT_AUTH = "CLIENT_CERT";
 21     String DIGEST_AUTH = "DIGEST";
 22 
 23     String getAuthType();
 24 
 25     Cookie[] getCookies();
 26 
 27     long getDateHeader(String var1);
 28 
 29     String getHeader(String var1);
 30 
 31     Enumeration<String> getHeaders(String var1);
 32 
 33     Enumeration<String> getHeaderNames();
 34 
 35     int getIntHeader(String var1);
 36 
 37     default HttpServletMapping getHttpServletMapping() {
 38         return new HttpServletMapping() {
 39             public String getMatchValue() {
 40                 return "";
 41             }
 42 
 43             public String getPattern() {
 44                 return "";
 45             }
 46 
 47             public String getServletName() {
 48                 return "";
 49             }
 50 
 51             public MappingMatch getMappingMatch() {
 52                 return null;
 53             }
 54         };
 55     }
 56 
 57     String getMethod();
 58 
 59     String getPathInfo();
 60 
 61     String getPathTranslated();
 62 
 63     default PushBuilder newPushBuilder() {
 64         return null;
 65     }
 66 
 67     String getContextPath();
 68 
 69     String getQueryString();
 70 
 71     String getRemoteUser();
 72 
 73     boolean isUserInRole(String var1);
 74 
 75     Principal getUserPrincipal();
 76 
 77     String getRequestedSessionId();
 78 
 79     String getRequestURI();
 80 
 81     StringBuffer getRequestURL();
 82 
 83     String getServletPath();
 84 
 85     HttpSession getSession(boolean var1);
 86 
 87     HttpSession getSession();
 88 
 89     String changeSessionId();
 90 
 91     boolean isRequestedSessionIdValid();
 92 
 93     boolean isRequestedSessionIdFromCookie();
 94 
 95     boolean isRequestedSessionIdFromURL();
 96 
 97     /** @deprecated */
 98     @Deprecated
 99     boolean isRequestedSessionIdFromUrl();
100 
101     boolean authenticate(HttpServletResponse var1) throws IOException, ServletException;
102 
103     void login(String var1, String var2) throws ServletException;
104 
105     void logout() throws ServletException;
106 
107     Collection<Part> getParts() throws IOException, ServletException;
108 
109     Part getPart(String var1) throws IOException, ServletException;
110 
111     <T extends HttpUpgradeHandler> T upgrade(Class<T> var1) throws IOException, ServletException;
112 
113     default Map<String, String> getTrailerFields() {
114         return Collections.emptyMap();
115     }
116 
117     default boolean isTrailerFieldsReady() {
118         return false;
119     }
120 }

  在Servlet API中,ServletRequest介面被定義為用於封裝請求的資訊,ServletRequest物件由Servlet容器在使用者每次請求Servlet時建立並傳入Servlet的service方法中。

  HttpServletRequest介面繼承自ServletRequest介面,該介面提供了具有如下HTTP請求資訊的處理

    獲取請求報文資訊(包括請求行,請求頭和請求正文)的方法:      獲取請求行資訊:       getMethod():獲取請求使用的HTTP方法,例如GET,POST和PUT       getRequestURL():獲取請求行中的資源名部分       getProtocol():獲取協議和版本號       getQueryString():獲取請求URL後面的查詢字串,只對GET有效       getServletPath():獲取Servlet所對映的路徑       getContextPath():獲取請求資源所屬於的Web應用的路徑     獲取請求頭資訊:       getIntHeader(String name):獲取整數型別的請求頭       getDateHeader(String name):獲取單值毫秒型別的請求頭       getContextLength():獲取請求內容的長度,以位元組為單位       getContentType():獲取請求的文件型別和編碼       getLocale():獲取使用者瀏覽器設定的locale資訊       getCookies():獲取一個包含在這個請求中所有cookie的陣列     獲取請求正文:       getParameter(String name):返回由name指定的使用者請求引數的值       getParameterNames():返回所有使用者請求的引數名       getParameterValues(String name):返回由name制定的使用者請求引數對應的一組值       getParameterMaps():返回一個請求引數的MAP物件       ServletInputStream getInputStream():獲取上傳檔案二進位制輸出流       BufferedReader getReader():獲取上傳檔案字元緩衝輸入流     獲取網路連線資訊的方法:       getRequestURL:返回客戶端發出請求時的完整URL。
      getRequestURI:返回請求行中的資源名部分。
      getRemoteAddr:返回發出請求的客戶機的IP地址。
      getRemoteHost:返回發出請求的客戶機的完整主機名。
      getRemotePort:返回客戶機所使用的網路埠號。
      getLocalAddr:返回WEB伺服器的IP地址。
      getLocalName:返回WEB伺服器的主機名。     存取請求域屬性的方法:       setAttribute(String name,Object obj)把一個物件和一個屬性名以key+value的形式繫結並存放在ServletContext中       getAttribute(String name) 返回用上一方法中存的物件,根據其對應的屬性名       getAttributeNames():返回一個列舉集合物件,該物件包含了所有存放在ServletContext中的屬性名       removeAttribute(String name):同getAttribute()方法相反,刪除一個匹配的物件   HttpServletResponse介面:   
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package javax.servlet.http;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.function.Supplier;
import javax.servlet.ServletResponse;

public interface HttpServletResponse extends ServletResponse {
    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;

    void addCookie(Cookie var1);

    boolean containsHeader(String var1);

    String encodeURL(String var1);

    String encodeRedirectURL(String var1);

    /** @deprecated */
    @Deprecated
    String encodeUrl(String var1);

    /** @deprecated */
    @Deprecated
    String encodeRedirectUrl(String var1);

    void sendError(int var1, String var2) throws IOException;

    void sendError(int var1) throws IOException;

    void sendRedirect(String var1) throws IOException;

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

    void setStatus(int var1);

    /** @deprecated */
    @Deprecated
    void setStatus(int var1, String var2);

    int getStatus();

    String getHeader(String var1);

    Collection<String> getHeaders(String var1);

    Collection<String> getHeaderNames();

    default void setTrailerFields(Supplier<Map<String, String>> supplier) {
    }

    default Supplier<Map<String, String>> getTrailerFields() {
        return null;
    }
}

HttpServletResponse同HttpServletRequest一樣都是繼承與javax.servlet包內的介面,它被用來進行HTTP相應資訊的處理

HttpServletResponse介面提供了具有如下功能型別的方法:

  設定響應狀態的方法:

    setStatus(int sc):以指定的狀態碼相應返回給客戶端

    setError(int sc):使用制定的狀態碼向客戶端返回一個錯誤響應 

    sendError(int sc,String msg):使用指定的狀態碼和狀態描述向客戶端返回一個錯誤響應

    sendRedirect(String):請求的重定向

  構建響應頭的方法:

    setContentType(String mimeType):設定Content-type報頭。

              setContentLength(int length):設定Content-length報頭,用於瀏覽器持續性HTTP連線。   

              addCookie(Cookie c):向set-cookie報頭插入一個cookie。 

    addHeader(String name, String value):新增String型別值到名為name的http頭部

    addIntHeader(String name, int value):新增Int型別值到名為name的http頭部

    addDateHeader(String name, long value):新增long型別值到名為name的http頭部

  建立相應正文的方法:

     getOutputStream():返回位元組輸出流物件ServletOutputStream

     getWriter():返回字元輸出流物件PrintWrite