Spring框架之spring-web web源碼完全解析
spring-web是Spring webMVC的基礎,由http、remoting、web三部分組成,核心為web模塊。http模塊封裝了http協議中的client/server端的request請求/response響應,編解碼,一些格式的轉換(如cbor、Rss、json、xml)。remoting模塊負責遠程調用,包括caucho、httpinvoker、jaxws。
spring-web的web模塊封裝了快速開發spring-web需要的基礎組件。包括:Initializer、accept、bind、client、context、cors、filter、jsf、method、multipart、server、util。
Initializer部分:主要通過web/目錄下面的SpringServletContainerInitializer和WebApplicationInitializer做初始化的工作(例如注冊servlet或者filtes等)。
accept部分:主要用來負責協商http內容的MIME TYPE是否滿足要求的。同一資源可以有多種表現形式,比如xml、json等。具體使用哪種表現形式,是可以協商的。這是RESTfull的一個重要特性,Spring Web MVC也支持這個功能。
bind部分:數據綁定部分,將不同類型的http請求上的數據設置到特定的對象上,如javabean等,支持multipart的綁定。綁定支持兩種方式:編程式和注解式。
client部分:客戶端部分,核心類RestTemplate,與許多其他Spring 模板類(例如JdbcTemplate、JmsTemplate)設計原則相同,為執行復雜任務提供了一種具有默認行為的簡化方法。
context部分:上下文部分,包含了一系列web應用的WebApplicationContext,不同功能的監聽器等。
cors部分:對cors跨域資源操作提供了支持。
filter部分:封裝了各種不同的過濾器。
jsf部分:增加了對一種以組件為中心的用戶界面構建方法的頁面表示技術JSF的支持。
method部分:提供給spring mvc使用的方法處理類。
multipart部分:對rfc1867為http協議新增的文件上傳功能multipart/form-data提供支持。
server部分:服務器部分。包括ServerWebExchange、WebSession、WebFilter、WebHandler等類。
util部分:提供了公共的工具類。
本文基於version為5.2.4.BUILD-SNAPSHOT的Spring源碼版本進行分析,對spring-web web十二個子模塊中包含的接口和類進行分析。
一、web/
1.1 SpringServletContainerInitializer
servlet規范規定,在容器啟動時,會通過ServletContainerInitializer的實現類來做初始化的工作(例如注冊servlet或者filtes等)。
具體使用方法為:
1、實現ServletContainerInitializer接口。(SpringServletContainerInitializer類)
2、在對應的jar包的META-INF/services 目錄創建一個名為javax.servlet.ServletContainerInitializer的文件。(..\spring-web\src\main\resources\META-INF\services\,tomcat默認就會去讀取META-INF)
3、ServletContainerInitializer文件內容為實現類的全類名,即包名+類名。(內容為:org.springframework.web.SpringServletContainerInitializer)
SpringServletContainerInitializer類實現了ServletContainerInitializer接口。這意味着servlet(3.0以上版本)容器啟動時,該類被容器自動加載並執行其onStartup(webAppInitializerClasses, servletContext)方法。
SpringServletContainerInitializer 類使用了@HandlesTypes(WebApplicationInitializer.class)注解。表明給onStartup方法傳遞了類路徑下所有實現了WebApplicationInitializer類。spring將初始化所有這些具體實現類,並調用它們的WebApplicationInitializer#onStartup(servletContext)方法。這些類可以在其onStartup方法中,通過可編程方式注冊和初始化servlet組件。
簡單介紹下Servlet:
Servlet就是一個Java接口,只有5個方法的接口,Servlet接口中的5大方法:
1、void init(ServletConfig):初始化servlet,它是servlet的生命周期方法,由web容器調用一次。
2、void service(ServletRequest, ServletResponse):為傳入的請求提供響應,它由容器的每個請求調用。
3、void destroy():僅被調用一次,表明servlet正在被銷毀。
4、ServletConfig getServletConfig():返回ServletConfig對象。
5、String getServletInfo():返回有關servlet的信息,如作者、版權、版本等。
Servlet接口定義的是一套處理網絡請求的規范,所有實現servlet的類,都要實現它的5個方法。其中最主要的是兩個生命周期方法init()和destroy(),還有一個處理請求service()。也就是說所有實現servlet接口的類,或者說,所有想要處理網絡請求的類,都要回答三個問題:初始化要做什么,銷毀時要做什么,接受到請求時要做什么。
實現了servlet的類能處理請求嗎,不能。那請求怎么來到servlet呢,通過servlet容器,比如我們最常用的tomcat。所以需要將servlet部署到一個容器中,否則servlet根本不會起作用。
容器(如tomcat)才是與客戶端直接打交道的,它監聽了端口,請求過來后,根據url等信息,確定要將請求交給哪個servlet去處理,然后調用那個servlet的service方法,service方法返回一個response對象,tomcat再把這個response返回給客戶端。
1.2 WebApplicationInitializer
現在JavaConfig配置方式在逐步取代xml配置方式。而WebApplicationInitializer可以看做是Web.xml的替代,它是一個接口。通過實現WebApplicationInitializer,在其中可以添加servlet,listener等,在加載Web項目的時候會加載這個接口實現類,從而起到web.xml相同的作用。
WebApplicationInitializer的調用執行要通過SpringServletContainerInitializer類實現。SpringServletContainerInitializer 類使用了@HandlesTypes(WebApplicationInitializer.class)注解。表明給其onStartup方法傳遞了類路徑下所有實現了WebApplicationInitializer類。spring將初始化所有這些具體實現類,並調用他們的WebApplicationInitializer#onStartup(servletContext)方法。
進入SpringServletContainerInitializer 類的onStartup方法:
1、先判斷webAppInitializerClasses這個Set是否為空。
2、如果不為空的話,找到這個Set中不是接口,不是抽象類,並且是WebApplicationInitializer接口實現類的類,將它們保存到List中。
3、判斷這個list是否為空,為空則記錄日志,返回。
4、不為空的話就按照一定的順序排序,並將它們按照一定的順序實例化。調用每一個WebApplicationInitializer的onStartup(servletContext)方法執行。
1.3 HttpRequestHandler
Http請求處理器,一個專門用來處理Http請求,並生成對應的響應的處理器。只有一個handlerRequest方法,其處理邏輯隨子類的實現不同而不同。該接口類似於javaEE中的Servlet,目的都是處理請求,產生響應結果。
1.4 HttpMediaTypeException
和媒體類型(Media Types)相關的異常的抽象基類。
1.5 HttpMediaTypeNotAcceptableException
客戶端請求期望響應的媒體類型與服務器響應的媒體類型不一致造成的。例如客戶端希望返回的媒體類型是json對象(application/json),服務器返回的媒體類型是一個普通的json字符串(text/plain);又或者是客戶端希望返回的是html頁面,服務器返回的卻是json對象。
1.6 HttpMediaTypeNotSupportedException
每條HTTP 請求報文都包含一個方法。這個方法會告訴服務器要執行什么動作,不同於GET、HEAD、DELETE方法,PUT、POST、PATCH方法需要發送客戶端數據,HttpRequestHandler處理這三種請求報文時,客戶端數據的類型不被支持拋出的異常。
1.7 HttpRequestMethodNotSupportedException
當一個請求報文處理器不支持該請求報文的方法時拋出的異常。一些常見的HTTP方法:
GET:從服務器向客戶端發送命名資源;
HEAD:僅發送命名資源響應中的HTTP 首部;
DELETE:從服務器中刪除命名資源;
PUT:將來自客戶端的數據存儲到一個命名的服務器資源中去;
POST:將客戶端數據發送到一個服務器網關應用程序;
PATCH:方法是新引入的,是對PUT方法的補充,用來對已知資源進行局部更新。
1.8 HttpSessionRequiredException
一個HttpRequestHandler需要session,但從當前請求獲得不到session時拋出的異常。
二、web/accept
accept部分就是負責協商http內容的Mime Type是否滿足要求的。幾個HTTP請求報文示例:
GET /tools.html HTTP/1.0
User-agent: Mozilla/4.75 [en] (Win98; U)
Host: www.joes-hardware.com
Accept: text/html, image/gif, image/jpeg
Accept-language: en
GET /seasonal/index-fall.html HTTP/1.1
Host: www.joes-hardware.com
Accept: *
HEAD /seasonal/index-fall.html HTTP/1.1
Host: www.joes-hardware.com
Accept: *
rfc-2616中HTTP/1.1中標准頭域Accept的語法和語義:
對於實體頭域來說,發送者和接收者都既可以指客戶端也可以指服務器,取決於誰發送和誰接收此實體。
Accept請求頭域被用於指定哪些媒體類型的響應對請求端是可接受的。Accept頭域被用於指明請求只對某些期望的媒體類型有效,例如請求一個內嵌的圖像。
Accept = "Accept" ":"
#( media-range [ accept-params ] )
media-range = ( "*/*"
| ( type "/" "*" )
| ( type "/" subtype )
) *( ";" parameter )
accept-params = ";" "q" "=" qvalue *( accept-extension )
accept-extension = ";" token [ "=" ( token | quoted-string ) ]
星號”*”字符用於把媒體類型組合成一個范圍,“*/*”指明了所有的媒體類型而“type/*”指明type類型的所有子類型。Media-range可能包含一個媒體類型參數。
每一個media-range可能會跟隨一個或多個accept-params,以“q”參數指明一個相對的喜愛程度的質量因子。通過第一個“q”參數(如果有的話)把accept-params和media-range參數分離。喜愛程度質量因子允許用戶或用戶代理去指明對那個media-range 的相對喜愛程度,qvalue的范圍是從0到1。缺省是q=1。
注意:利用“q”參數名字將媒體類型參數(譯注:media-range里的parameter)和acceptextension分離開來是基於歷史的實踐。盡管這能防止任何以“q”命名的媒體類型參數應用於media-range 里,但在一個media-range 里使用“q”被認為是不可能發生的,這是因為在IANA的媒體類型注冊表里是沒有“q”參數的並且在Accept頭域里利用媒體類型參數也是很少見。將來的媒體類型不被鼓勵任何以“q”命名的參數注冊。
例子:
Accept: audio/*; q=0.2, audio/basic
該例應該被解釋成“我喜歡audio/basic,但是可以給我發送任何audio類型如果它最容易得到,但在喜愛程度質量要下降80%”。
如果沒有Accept頭域出現,那么會假設客戶端能接受所有媒體類型。如果Accept頭域在請求消息里出現,並且如果服務器根據聯合Accept頭域值發現它不能發送客戶端可接受的響應,那么服務器應發送406(不可接受的)響應。
一個更加詳盡的例子如下:
Accept: text/plain; q=0.5, text/html,
text/x-dvi; q=0.8, text/x-c
這可能被口頭地解釋成“text/html 和 text/x-c是更喜愛的媒體類型,但是如果他們不存在,那么發送text/x-dvi實體,但如果text/x-dvi也不存在,那么發送text/plain實體。
Media-range能被更具有特殊性的media-range或媒體類型覆蓋。如果多個media-range應用了一個特指的類型,那么最具有特殊性的應該優先。例如:
Accept: text/*, text/html, text/html;level=1, */*
擁有下面的優先順序:
1) text/html;level=1
2) text/html
3) text/*
4) */*
一個媒體類型的喜愛程度質量因子是和一個給定的媒體類型聯系在一起的,它是由查找能最高優先匹配那個媒體類型的media-range決定的。例如:
Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
text/html;level=2;q=0.4, */*;q=0.5
可能會引起下面值被聯系:
text/html;level=1 = 1
text/html = 0.7
text/plain = 0.3
image/jpeg = 0.5
text/html;level=2 = 0.4
text/html;level=3 = 0.7
注意:一個用戶代理可能會為一個特定的media-range提供一個缺省的質量值的集合。然而,除非用戶代理是一個不能和其他的呈現代理交互的封閉的系統,否則這個缺省的集合應該可以被用戶可設置的。
什么是內容協商:簡單點說,就是同一資源,可以有多種表現形式,比如xml、json等,具體使用哪種表現形式,是可以協商的。這是RESTfull的一個重要特性,Spring Web MVC也支持這個功能。
Spring MVC REST展示內容(視圖)采用的幾種方式:
1、根據Http請求的header中的Accept屬性的值來判讀,比如:
Accept: application/xml 將返回xml格式數據
Accept: application/json 將返回json格式數據
優點:是這種方式是理想的標准方式
缺點:是由於瀏覽器的差異,導致發送的Accept Header頭可能會不一樣,從而導致服務器不知要返回什么格式的數據
2、根據擴展名來判斷,比如:
/mvc/test.xml 將返回xml格式數據
/mvc/test.json 將返回json格式數據
/mvc/test.html 將返回html格式數據
缺點:喪失了同一URL的多種展現方式。在實際環境中使用還是較多的,因為這種方式更符合程序員的習慣
3、根據參數來判斷
/mvc/test?format=xml 將返回xml數據
/mvc/test?format=json 將返回json數據
缺點:需要額外的傳遞format參數,URL變得冗余繁瑣,缺少了REST的簡潔風范
2.1 ContentNegotiationStrategy
策略接口,用於從請求對象中的信息中判斷該請求的MediaType,即客戶端需要什么類型(MediaType)的數據。
該接口主要定義了一個方法List<MediaType> resolveMediaTypes(NativeWebRequest webRequest)。該方法接受一個參數NativeWebRequest(請求對象),分析該請求對象,從而獲得它的MediaType列表。
2.2 FixedContentNegotiationStrategy
該策略對象創建時固定了一組MediaType,不管請求對象是什么,都返回這組MediaType。
2.3 HeaderContentNegotiationStrategy
該策略對象分析請求頭部Accept 得出該請求的一組MediaType,如果請求頭部Accept未設置,返回的MediaType只包含*/*。
2.4 AbstractMappingContentNegotiationStrategy
抽象基類,通過request獲取MediaType所需的Key,再根據Key找出對應的MediaType列表並返回。ParameterContentNegotiationStrategy,PathExtensionContentNegotiationStrategy,ServletPathExtensionContentNegotiationStrategy都是從該類派生出來的。
2.5 ParameterContentNegotiationStrategy
根據一個查詢參數(query parameter)判斷請求的MediaType,該查詢參數缺省使用format`。
2.6 PathExtensionContentNegotiationStrategy
根據請求URL 路徑中所請求的文件資源的擴展名部分判斷請求的MediaType。
2.7 ServletPathExtensionContentNegotiationStrategy
擴展自PathExtensionContentNegotiationStrategy,將使用ServletContext#getMimeType(String)方法判斷請求MediaType。
2.8 MediaTypeFileExtensionResolver
MediaType和路徑擴展名解析策略的接口,例如將 json 解析成 application/json 或者反向解析。
主要定義了兩個方法:List<String> resolveFileExtensions(MediaType mediaType)方法,根據指定的mediaType返回一組文件擴展名;List<String> getAllFileExtensions()方法,返回該策略接口中注冊的所有文件擴展名。
2.9 MappingMediaTypeFileExtensionResolver
此類維護一些Map以及提供操作的方法,它維護了一個文件擴展名和MediaType的雙向查找表。擴展名和MediaType的對應關系:一個MediaType對應N個擴展名;一個擴展名最多只會屬於一個MediaType。
2.10 ContentNegotiationManager
內容協商管理器ContentNegotiationManager是Spring Web一個重要的工具類,用於判斷一個請求的媒體類型MediaType列表。具體的做法是委托給它所維護的一組ContentNegotiationStrategy實例。實際上它自身也實現了接口ContentNegotiationStrategy,使用者可以直接將它作為一個ContentNegotiationStrategy使用。
另外,ContentNegotiationManager也實現了接口MediaTypeFileExtensionResolver,從而可以根據MediaType查找到相應的文件擴展名。這一點也是通過將任務委托給他所維護的一組MediaTypeFileExtensionResolver實例完成的。
ContentNegotiationManager其實就是一個組合容器:組合了一組用於判斷請求媒體類型的ContentNegotiationStrategy實例;組合了一組用於根據媒體類型獲取文件擴展名的MediaTypeFileExtensionResolver實例,而ContentNegotiationManager又實現了這兩個接口ContentNegotiationStrategy/MediaTypeFileExtensionResolver。它對這兩個接口的功能實現最終委托給了它所維護的這些實例來完成。通過這種組合-委托模式,使用者自己不用維護這些單個的ContentNegotiationStrategy/MediaTypeFileExtensionResolver的實例以及對它們的組合使用了,而是只需要通過使用ContentNegotiationManager即可。
2.11 ContentNegotiationManagerFactoryBean
用來生成ContentNegotiationManager,並使用ContentNegotiationStrategy配置它。
三、web/bind
數據綁定部分,綁定的意思是將不同類型的http請求上的數據設置到特定的對象object上如javabean等,支持multipart的綁定。綁定支持兩種方式:編程式和注解式。其中,注解的實現由HandlerMethodInvoker觸發HandlerMethodResolver來完成。
3.1 WebDataBinder
它的作用就是從web request 里(注意:這里指的web請求,並不一定就是ServletRequest請求)把web請求的parameters綁定到JavaBean上。
Controller方法的參數類型可以是基本類型,也可以是封裝后的普通Java類型。若這個普通Java類型沒有聲明任何注解,則意味着它的每一個屬性都需要到Request中去查找對應的請求參數。無論客戶端傳入的是什么類型的請求參數,最終都要以字節的形式傳給服務端。而服務端通過Request的getParameter方法取到的參數也都是字符串形式的結果。所以,需要有一個把字符串形式的參數轉換成服務端真正需要的類型的轉換工具,在spring中這個轉換工具為WebDataBinder。
3.2 ServletRequestDataBinder
從Servlet Request里把參數綁定到JavaBean里,支持multipart。
3.3 ServletRequestParameterPropertyValues
PropertyValue類:保存單個bean屬性的信息和值的對象。
PropertyValues接口:包含一個或多個PropertyValue對象的容器。
MutablePropertyValues類: PropertyValues接口的默認實現。
ServletRequestParameterPropertyValues繼承自MutablePropertyValues,能夠查找以特定前綴(比如""spring"")加前綴分割器(默認為""_"")開頭的所有property values。
3.4 ServletRequestUtils
操作request的工具類。主要用來從ServletRequest中析取被綁定的參數。
3.5 EscapedErrors
各種錯誤類型包裝器,增加了automatic HTML escaping錯誤類型,在HTML視圖中方便使用。通過RequestContext的getErrors方法獲得該wrapped的實例。
3.6 MethodArgumentNotValidException
檢驗使用@Valid注解的參數失敗拋出的異常。
3.7 ServletRequestBindingException
綁定時致命異常錯誤,這些綁定異常時不可恢復的。拓展自ServletException,為了在Servlet資源(如Filter)中方便拋出。
3.8 MissingMatrixVariableException
ServletRequestBindingException子類,當一個使用了@RequestMapping標注的方法在其參數中期望的一個matrix variable不在從URL提取出來的matrix variables時拋出的異常。
3.9 MissingPathVariableException
ServletRequestBindingException的子類,當一個使用@RequestMapping注解標注的方法在其參數中期望的一個path variable不在從URL中提取出來的URI variables中拋出的異常。
3.10 MissingRequestCookieException
ServletRequestBindingException的子類,當一個使用@RequestMapping注解標注的方法在其參數中期望的request cookie不存在時拋出的異常。
3.11 MissingRequestHeaderException
ServletRequestBindingException的子類,當一個使用@RequestMapping注解標注的方法在其參數中期望的request header不存在時拋出的異常。
3.12 MissingServletRequestParameterException
ServletRequestBindingException的子類,表示缺失了一個參數。
3.13 UnsatisfiedServletRequestParameterException
ServletRequestBindingException的子類,表示一個不滿足的參數的狀況。
web/bind/support
3.14 WebExchangeDataBinder
Spring5.0后提供的,對Reactive編程的Mono數據綁定提供支持。
3.15 WebRequestDataBinder
它是用於處理Spring自己定義的org.springframework.web.context.request.WebRequest的,旨在處理和容器無關的web請求數據綁定。
3.16 WebDataBinderFactory
為一個目標對象創建一個WebDataBinder實例。
3.17 DefaultDataBinderFactory
創建一個WebRequestDataBinder實例,並使用WebBindingInitializer對其進行初始化。
3.18 SpringWebConstraintValidatorFactory
該類實現了JSR-303 ConstraintValidatorFactory接口,委托給當前的Spring WebApplicationContext,用以創建自動裝配的ConstraintValidator實例。
WebApplicationContext是專門為web應用准備的,允許從相對於web根目錄的路勁中裝載配置文件完成初始化工作。
ConstraintValidator接口實現類可以完成自定義注解校驗。我們往往使用注解的方式對傳入的參數進行一個格式的校驗,但已有的注解不是萬能的,我們在實現當前業務邏輯判斷時會遇到已有注解不能校驗的邏輯,我們則需要自己自定義校驗注解進行對參數的校驗。
3.19 WebBindingInitializer
實現此接口重寫initBinder方法注冊的屬性編輯器是全局的屬性編輯器,對所有的Controller都有效。
3.20 ConfigurableWebBindingInitializer
實現了接口WebBindingInitializer,用來初始化WebDataBinder,將請求的參數轉化為對應的JavaBean,並且會結合類型、格式轉換等API一起使用。
3.21 SessionAttributeStore
往后台session存儲model attributes的策略接口。
3.22 DefaultSessionAttributeStore
SessionAttributeStore接口的默認實現類,用來往Web Request session(比如HttpSession)存取數據的工具類。
3.23 SessionStatus
一個簡單的接口,可以在處理方法中使用,使他們可以判斷會話的處理是否結束,如果結束可以緊接着進行一些清理工作。定義了兩個函數:setComplete()、isComplete()。
3.24 SimpleSessionStatus
SessionStatus接口的簡單實現,定義了一個標示變量complete。
3.25 WebArgumentResolver
參數解析器。
3.26 WebExchangeBindException
繼承自ServerWebInputException,當數據綁定和驗證失敗時拋出的異常。該異常類也實現了接口BindingResult(包括它的父接口Errors),允許直接分析綁定和驗證的錯誤。
web/bind/annotation
3.27 ControllerAdvice
此注解用於class上。使用@ControllerAdvice聲明一個類來統一對所有@RequestMapping方法來做@ExceptionHandler、``@InitBinder以及@ModelAttribute`處理。
3.28 CookieValue
此注解用在@RequestMapping聲明的方法的參數上,可以把HTTP cookie中相應名稱的cookie綁定上去。
3.29 CrossOrigin
此注解用在class和method上用來支持跨域請求,是Spring 4.2后引入的。
3.30 DeleteMapping
使用DELETE方式進行交互。
3.31 ExceptionHandler
此注解使用在方法級別,聲明對Exception的處理邏輯。可以指定目標Exception。
3.32 GetMapping
將 HTTP GET 請求映射到特定的處理程序方法。
3.33 InitBinder
此注解使用在方法上,聲明對WebDataBinder的初始化(綁定請求參數到JavaBean上的DataBinder)。在controller上使用此注解可以自定義請求參數的綁定。
3.34 Mapping
元注解,用來注解一個web mapping注解。
元注解的作用就是負責注解其他注解。Java 5 定義了四個標准的元注解類型,用以提供對其它注解的功能說明。
@Target用於描述注解的范圍,即注解在哪用。
@Retention用於描述注解的生命周期,表示需要在什么級別保存該注解,即保留的時間長短。
@Documented用於描述其它類型的annotation應該被作為被標注的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化。
@Inherited用於表示某個被標注的類型是被繼承的。
3.35 MatrixVariable
此注解使用在請求handler方法的參數上,Spring可以注入matrix url中相關的值。這里的矩陣變量可以出現在url中的任何地方,變量之間用分號分隔。
3.36 ModelAttribute
被該注解定義的方法,會在該方法所在的controller的任何目標方法執行之前執行。
3.37 PatchMapping
PatchMapping注解將 HTTP Patch請求映射到特定的處理程序方法。PATCH方法是新引入的,是對PUT方法的補充,用來對已知資源進行局部更新。
3.38 PathVariable
可以使用@PathVariable將路徑中的參數綁定到請求方法參數上。
3.39 PostMapping
PostMapping注解將 HTTP Post請求映射到特定的處理程序方法。
3.40 PutMapping
將 HTTP Put 請求映射到特定的處理程序方法。
3.41 RequestAttribute
此注解用在請求handler方法的參數上,用於將web請求中的屬性(request attributes,服務器放入的屬性值)綁定到方法參數上。
3.42 RequestBody
將請求信息的body內容綁定在程序的實體類中。
3.43 RequestHeader
此注解用在請求handler方法的參數上,用於將http請求頭部的值綁定到參數上。
3.44 RequestMapping
這個注解會將 HTTP 請求映射到 MVC 和 REST 控制器的處理方法上。
3.45 RequestParam
此注解用在請求handler方法的參數上,用於將http請求參數的值綁定到參數上。
3.46 RequestPart
此注解用在請求handler方法的參數上,用於將文件之類的multipart綁定到參數上。
3.47 ResponseBody
此注解將controller的方法返回的對象通過適當的轉換器轉換為指定的格式之后,寫入到response對象的body區,通常用來返回JSON數據或者是XML。
3.48 ResponseStatus
此注解用於方法和exception類上,聲明此方法或者異常類返回的http狀態碼。可以在Controller上使用此注解,這樣所有的@RequestMapping都會繼承。
3.49 RestController
此注解用於class上,聲明此controller返回的不是一個視圖而是一個領域對象。其同時引入了@Controller和@ResponseBody兩個注解。
3.50 RestControllerAdvice
此注解用於class上,同時引入了@ControllerAdvice和@ResponseBody兩個注解。
3.51 SessionAttribute
注解用於方法的參數上,用於將session中的屬性綁定到參數。
3.52 SessionAttributes
此注解用於type級別,用於將JavaBean對象存儲到session中。一般和@ModelAttribute注解一起使用。
3.53 RequestMethod
枚舉類型,枚舉了HTTP請求方法:GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS、TRACE。
@RequestMapping注解會將 HTTP 請求映射到 MVC 和 REST 控制器的處理方法上。該枚舉類在RequestMapping注解類method()方法中使用。
3.54 ValueConstants
用在bind注解中的常量值。該接口只定義一個字符串常量DEFAULT_NONE。String DEFAULT_NONE = "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";因為不能在注解的屬性中使用null來表示空值,所以用這段16位Unicode的字符串(ValueConstants.DEFAULT_NONE)來表示空值,並且是不會發生這段字符串與用戶定義的值是一樣的情況。避免了用戶給出的值卻被當作是空值的情況。
四、web/client
4.1 RestTemplate
spring框架提供的RestTemplate類可用於在應用中調用rest服務,它簡化了與http服務的通信方式,統一了RESTful的標准,封裝了http鏈接, 我們只需要傳入url及返回值類型即可。相較於之前常用的HttpClient,RestTemplate是一種更優雅的調用RESTful服務的方式。簡而言之就是簡化了發起HTTP請求以及處理響應的過程,並且支持REST。
在Spring應用程序中訪問第三方REST服務與使用Spring RestTemplate類有關。RestTemplate類的設計原則與許多其他Spring 模板類(例如JdbcTemplate、JmsTemplate)相同,為執行復雜任務提供了一種具有默認行為的簡化方法。
RestTemplate默認依賴JDK提供http連接的能力(HttpURLConnection),如果有需要的話也可以通過setRequestFactory方法替換為例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。
考慮到RestTemplate類是為調用REST服務而設計的,因此它的主要方法與REST的基礎緊密相連,后者是HTTP協議的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS。例如,RestTemplate類具有headForHeaders()、getForObject()、postForObject()、put()和delete()等方法。
4.2 RestOperations
指定了一套RESTful操作的接口,定義rest的各種操作,使用了大量的重載方法。該接口被RestTemplate類所實現。
REST: Representational State Transfer 直接翻譯:表現層狀態轉移。全稱是 Resource Representational State Transfer,通俗來講就是:資源在網絡中以某種表現形式進行狀態轉移。REST實際上只是一種設計風格,不是標准。基於REST構建的API就是Restful風格。
REST就是選擇通過使用http協議和uri,利用client/server model對資源進行CRUD(Create/Read/Update/Delete)增刪改查操作。
REST是面向資源的,而資源是通過URI進行暴露。URI的設計只要負責把資源通過合理的方式暴露出來就可以了,對資源的操作與它無關,操作是通過HTTP動詞來體現的,所以REST通過URI暴露資源時,會強調不要再URI中出現動詞。如GET /rest/api/getDogs 這種設計就不符合REST風格,URI里面包含了對資源的操作。 GET /rest/api/dogs滿足了,它的操作是用標准的HTTP動詞來體現的。
REST很好的利用HTTP本身就有的一些特征,如HTTP動詞、HTTP狀態碼、HTTP報頭等等。REST API是基於HTTP的,所以你的API應該去使用HTTP的一些標准。這樣所有的HTTP客戶端(如瀏覽器)才能夠直接理解你的API(也有其他好處,如利於緩存)。REST實際上也非常強調應該利用好HTTP本來就有的特征,而不是只把HTTP當成一個傳輸層這么簡單。
REST基礎概念:
1、在REST中的一切都被認為是一種資源。
2、每個資源由URI標識。
3、同一資源有多種表現形式。例如XML,JSON。
4、使用統一的接口。處理資源使用POST、GET、PUT、DELETE操作類似創建,讀取,更新和刪除(CRUD)操作。
5、所以的操作都是無狀態。每個請求是一個獨立的請求。從客戶端到服務器的每個請求都必須包含所有必要的信息,以便於理解。
4.3 RequestCallback
回調接口,用在操作ClientHTTPRequest的代碼中,包括操作請求的頭,寫入請求體。在內部被RestTemplate類使用,應用代碼中也有作用。幾個工廠方法如下(工廠方法:定義一個用於創建對象的接口,但是讓子類決定將哪一個類實例化。將實例化邏輯委托給子類的方法):
acceptHeaderRequestCallback(Class)}
RestTemplate#httpEntityCallback(Object)}
RestTemplate#httpEntityCallback(Object, Type)
4.4 AsyncRestTemplate
Web應用程序通常需要查詢外部REST服務。 在為滿足這些需求擴展應用程序時,HTTP和同步調用的本質會帶來挑戰:可能會阻塞多個線程,等待遠程HTTP響應。
AsyncRestTemplate類,在開發REST客戶端時允許非阻塞異步支持。是Spring的中心類,用於異步客戶端HTTP訪問。 公開與RestTemplate相似的方法,但返回ListenableFuture包裝器,而不是具體的結果。AsyncRestTemplate通過getRestOperations()方法公開一個同步RestTemplate,並與該RestTemplate共享其錯誤處理程序和消息轉換器。
默認情況下,AsyncRestTemplate依靠標准JDK工具建立HTTP連接。 您可以通過使用接受AsyncClientHttpRequestFactory的構造函數來切換使用其他HTTP庫,例如Apache HttpComponents,Netty和OkHttp。默認的AsyncRestTemplate構造函數注冊一個SimpleAsyncTaskExecutor來執行HTTP請求。
4.5 AsyncRestOperations
指定了一套異步RESTful操作的接口,該接口被AsyncRestTemplate類所實現。
4.6 AsyncRequestCallback
回調接口,用在操作AsyncClientHttpRequest的代碼中,包括操作請求的頭,寫入請求體。在內部被AsyncRestTemplate類使用,應用代碼中也有作用。
4.7 ResponseErrorHandler
RestTemplate請求結果的異常處理器接口,接口的第一個方法hasError用於判斷HttpResponse是否是異常響應(通過狀態碼),接口的第二個方法handleError用於處理異常響應結果(非200狀態碼段)。
4.8 DefaultResponseErrorHandler
ResponseErrorHandler的默認實現。該實現類進行處理異常響應:從HttpResponse解析出Http StatusCode,如果狀態碼StatusCode為null,就拋出UnknownHttpStatusCodeException異常;如果StatusCode存在,則解析出StatusCode的series,也就是狀態碼段(除了200段,其他全是異常狀態碼),解析規則是StatusCode/100取整。根據狀態碼段,進一步拋出HttpClientErrorException。
4.9 ExtractingResponseErrorHandler
繼承自DefaultResponseErrorHandler,利用HttpMessageConverter對象轉換器 將HTTP錯誤響應轉換RestClientException,需要指定ResponseErrorHandler。
4.10 ResponseExtractor
解析HTTP響應的數據,從Response中提取數據,通過它來從ClientHttpResponse提取出指定內容(比如請求頭、請求Body體等)。
4.11 HttpMessageConverterExtractor
返回值提取器,實現接口ResponseExtractor。
4.12 MessageBodyClientHttpResponseWrapper
ClientHttpResponse的包裝類,通過讀取輸入流來判斷這個響應是報文否包括響應體,響應體長度是否為0(如:empty)。
4.13 HttpServerErrorException
當接收到HTTP 5XX(服務器本身發生錯誤)拋出的異常。
4.14 HttpStatusCodeException
基於HttpStatus狀態碼異常的抽象類。
4.15 RestClientException
服務器響應錯誤導致請求失敗拋出的異常,由RestTemplate拋出,由ResponseErrorHandler#hasError(ClientHttpResponse)確定與否。
4.16 RestClientResponseException
包含HTTP響應數據的異常的基類。
4.17 ResourceAccessException
I/O error發生時拋出的異常。
4.18 HttpClientErrorException
當接收到HTTP 4xx(客戶端錯誤狀態碼)時拋出的異常。
4.19 UnknownHttpStatusCodeException
當接收到一個未知的HTTP狀態碼時拋出的異常。
web/client/support
4.20 RestGatewaySupport
作為需要REST access的應用類的基類使用,需要設置一個ClientHttpRequestFactory或者RestTemplate實例。
五、web/context
5.1 WebApplicationContext
Web應用上下文 ,專門為web應用准備。它允許從相對於web根目錄的路徑中裝載配置文件完成初始化工作,從WebApplicationContext中可以獲得ServletContext的引用,整個Web應用上下文對象將作為屬性放置在ServletContext中,以便web應用可以訪問spring上下文。spring中提供WebApplicationContextUtils的getWebApplicationContext(ServletContext src)方法來獲得WebApplicationContext對象。
5.2 ConfigurableWebApplicationContext
擴展了WebApplicationContext,它允許通過配置的方式實例化,同時設置兩個重要方法:
1、setServletContext(ServletContext context) 為spring設置web應用上下文,以便兩者整合。
2、setConfigLocations(String[]locations) 設置Spring配置的文件地址。
5.3 ConfigurableWebEnvironment
ConfigurableWebEnvironment:繼承自ConfigurableEnvironment,並且提供配置Servlet上下文和Servlet參數的功能。
5.4 ContextCleanupListener
Web應用監聽器,用來清除在Servlet上下文中使用過后殘留的屬性。ServletContext,當WEB服務器啟動時,會為每一個WEB應用程序創建一塊共享的存儲區域。ServletContext在WEB服務器啟動時創建,服務器關閉時銷毀。
5.5 AbstractContextLoaderInitializer
該抽象類只是為了創建ContextLoaderListener,並通過抽象方法createRootApplicationContext創建的RootApplicationContext注入進Servlet容器事件中。
5.6 ContextLoader
應用程序上下文Context是Spring管理的bean所在的容器。上下文加載器ContextLoader負責構建應用程序上下文。
5.7 ContextLoaderListener
ContextLoaderListener監聽器的作用就是啟動Web容器時,自動裝配ApplicationContext的配置信息。因為它實現了ServletContextListener這個接口,在web.xml配置這個監聽器,啟動容器時,就會默認執行它實現的方法。
ContextLoaderListener調用contextInitialized方法完成Spring上下文初始化;調用contextDestroyed方法完成Spring上下文銷毀。可自行定義ContextLoaderListener的子類,進而在上下文啟動與銷毀時加入自定義功能。
5.8 ServletConfigAware
ServletConfig是針對特定的Servlet的參數或屬性。當一個servlet被實例化后,對任何客戶端在任何時候訪問有效,但僅對本servlet有效,一個servlet的ServletConfig對象不能被另一個servlet訪問。
容器初始化一個servlet時,會為這個servlet建一個唯一的ServletConfig。容器從web.xml讀出Servlet初始化參數,並把這些參數交給ServletConfig,然后把ServletConfig傳遞給servlet的init(ServletConfig config)方法。
ServletConfigAware接口會被希望得到ServletConfig通知的對象所實現。
5.9 ServletContextAware
當 容器啟動時,容器會為每個 Web 應用創建一個唯一的 ServletContext 對象代表當前的 Web 應用,該對象封裝了當前 Web 應用的所有信息。可以利用該對象獲取 Web 應用程序的初始化信息、讀取資源文件等。
一個web應用對應一個ServletContext實例,一個WEB應用中的所有Servlet共享同一個ServletContext對象,因此Servlet對象之間可以通過ServletContext對象通訊。Spring中,凡是實現ServletContextAware接口的類,都可以取得ServletContext。
web/context/annotation
5.10 ApplicationScope
該注解是@Scope的一個特例。
如果把變量放到application里,就說明它的作用域是application,它的有效范圍是整個應用。 整個應用是指從應用啟動,到應用結束。沒有說“從服務器啟動,到服務器關閉”,是因為一個服務器可能部署多個應用,當然你關閉了服務器,就會把上面所有的應用都關閉了。 application作用域里的變量,它們的存活時間是最長的,如果不進行手工刪除,它們就一直可以使用。
@Scope注解是spring Ioc容器中的一個作用域,在 Spring IoC 容器中具有以下幾種作用域:基本作用域singleton(單例)、prototype(多例),Web 作用域(reqeust、session、globalsession),自定義作用域。
1、singleton單例模式: 全局有且僅有一個實例。
2、prototype原型模式:每次獲取Bean的時候會有一個新的實例。
3、request: request表示該針對每一次HTTP請求都會產生一個新的bean,同時該bean僅在當前HTTP request內有效。
4、session:session作用域表示該針對每一次HTTP請求都會產生一個新的bean,同時該bean僅在當前HTTP session內有效。
5、globalsession: global session作用域類似於標准的HTTP Session作用域,不過它僅僅在基於portlet的web應用中才有意義。
5.11 RequestScope
該注解是@Scope的一個特例。
如果把變量放到request里,就說明它的作用域是request,它的有效范圍是當前請求周期。 所謂請求周期,就是指從http請求發起,到服務器處理結束,返回響應的整個過程。
5.12 SessionScope
該注解是@Scope的一個特例。
如果把變量放到session里,就說明它的作用域是session,它的有效范圍是當前會話。所謂當前會話,就是指從用戶打開瀏覽器開始,到用戶關閉瀏覽器這中間的過程。這個過程可能包含多個請求響應。也就是說,只要用戶不關瀏覽器,服務器就有辦法知道這些請求是一個人發起的,整個過程被稱為一個會話(session),而放到會話中的變量,就可以在當前會話的所有請求里使用。
web/context/request
5.13 AbstractRequestAttributes
RequestAttributes接口實現類的抽象基類,提供了一個請求完成機制用於請求特定的銷毀回調和更新訪問過的會話屬性。
5.14 AbstractRequestAttributesScope
實現Scope接口的抽象基類,Request和Session作用域對應的Scope接口實例均繼承自該基類。
5.15 SessionScope
作用域是session,它的有效范圍是當前會話。所謂當前會話,就是指從用戶打開瀏覽器開始,到用戶關閉瀏覽器這中間的過程。這個過程可能包含多個請求響應。
5.16 RequestScope
作用域是request,它的有效范圍是當前請求周期。 所謂請求周期,就是指從http請求發起,到服務器處理結束,返回響應的整個過程。
5.17 DestructionCallbackBindingListener
該類是Servlet HttpSessionBindingListener監聽器接口的適配器,封裝了一個會話銷毀的回調函數。HttpSessionBindingListener 可以監聽實現了該接口的對象在 Session 中被添加或者移除的事件。
5.18 RequestContextListener
RequestContextListener用於監聽用戶的請求,當一個用戶發送一個請求,會將用戶的請求request對象保存在RequestContextHolder中的requestAttributesHolder本地線程池中,當用戶的請求執行完畢,會清除RequestContextHolder中的requestAttributesHolder本地線程池中的request對象。
5.19 RequestAttributes
Request相關的屬性對象的抽象。
5.20 FacesRequestAttributes
RequestAttributes適配器,適配一個JSF javax.faces.context.FacesContext,在JSF環境中使用,封裝當前的FacesContext。
5.21 ServletRequestAttributes
基於Servlet的RequestAttributes接口的實現。
5.22 WebRequest
Web請求的通用接口。 主要用於通用Web請求攔截器,使它們可以訪問通用請求元數據,而不是用於實際處理請求。
5.23 NativeWebRequest
拓展自WebRequest接口,暴露真正的request和response對象。
5.24 ServletWebRequest
繼承ServletRequestAttributes、實現NativeWebRequest接口,適配javax.servlet.http.HttpServletRequest。
5.25 FacesWebRequest
WebRequest適配器,適配一個JSF javax.faces.context.FacesContext。需要JSF2.1或者更高的版本。
Java Server Faces (JSF) 是一種用於構建Java Web 應用程序的標准框架(是Java Community Process 規定的JSR-127標准)。它提供了一種以組件為中心的用戶界面(UI)構建方法,從而簡化了Java服務器端應用程序的開發。
5.26 WebRequestInterceptor
WebRequestInterceptor接口同HandlerInterceptor接口一樣定義了三個方法:preHandle 、postHandle 以及afterCompletion。兩個接口的方法名都相同,調用次序也相同。即preHandle是在請求處理之前調用;postHandle實在請求處理之后,視圖渲染之前調用;afterCompletion是在視圖渲染之后調用。這三個方法都傳遞了同一個參數WebRequest 。
5.27 AsyncWebRequestInterceptor
AsyncWebRequestInterceptor繼承自WebRequestInterceptor接口,增加了一個異步請求處理時調用的回調方法。
5.28 RequestContextHolder
持有上下文的Request容器。通過RequestContextHolder的靜態方法可以隨時隨地取到當前請求的request對象。
web/context/request/async
5.29 AsyncRequestTimeoutException
一個異步請求超時時拋出的異常。默認情況下,這個異常會被當做503錯誤(503狀態碼,Service Unavailable,由於超載或系統維護,服務器暫時的無法處理客戶端的請求)進行處理。或者應用也可以注冊一個DeferredResultProcessingInterceptor或CallableProcessingInterceptor來處理這個超時。注冊可以通過MVC Java配置或MVC XML命名空間或直接通過RequestMappingHandlerAdapter的屬性。
5.30 AsyncWebRequest
異步請求接口,繼承NativeWebRequest,增加了支持異步請求處理的方法。
5.31 CallableInterceptorChain
調用CallableProcessingInterceptor的輔助類。
5.32 CallableProcessingInterceptor
Callable攔截器。
5.33 CallableProcessingInterceptorAdapter
抽象類實現CallableProcessingInterceptor接口,空實現。
5.34 DeferredResult
遞延結果,在兩個線程中傳遞的對象結果。實現Comparable接口以保證加入PriorityQueue隊列的正確順序。
5.35 DeferredResultInterceptorChain
調用DeferredResultProcessingInterceptor的輔助類
5.36 DeferredResultProcessingInterceptor
DeferredResult處理過程攔截器。在start async前,超時后/異步處理完成后/網絡超時后觸發攔截。
5.37 DeferredResultProcessingInterceptorAdapter
抽象類實現DeferredResultProcessingInterceptor,做空實現。
5.38 StandardServletAsyncWebRequest
繼承ServletWebRequest,實現AsyncWebRequest、AsyncListener,一個標准異步web請求的實現類。
5.39 TimeoutCallableProcessingInterceptor
繼承CallableProcessingInterceptorAdapter,實現超時處理方法。
5.40 TimeoutDeferredResultProcessingInterceptor
繼承DeferredResultProcessingInterceptorAdapter,實現超時處理方法。
5.41 WebAsyncManager
對Callables和DeferredResults啟動的管理,包括攔截器的注入,Excutor的注入等,異步處理的入口類。
5.42 WebAsyncTask
web異步任務,包含一個Callable類,一個超時時間,一個任務執行着或名字。
5.43 WebAsyncUtils
實現getAsyncManager()和createAsyncWebRequest()方法。
web/context/support
5.44 AbstractRefreshableWebApplicationContext
實現了ConfigurableWebApplicationContext和ThemeSource接口,主要是用於web環境下。在web程序啟動的時候,提供一個configLocations屬性,通過ConfigurableWebApplicationContext接口來進行填充。實現該接口主要就是實現loadBeanDefinitions方法,來實現你自己的bean定義的加載邏輯。
5.45 AnnotationConfigWebApplicationContext
繼承自AbstractRefreshableWebApplicationContext,接受注解的類作為輸入(特殊的@Configuration注解類,一般的@Component注解類,與JSR-330兼容的javax.inject注解)。允許一個一個的注入,同樣也能使用類路徑掃描。對於web環境,基本上是和AnnotationConfigApplicationContext等價的。使用AnnotatedBeanDefinitionReader來對注解的bean進行處理,使用ClassPathBeanDefinitionScanner來對類路徑下的bean進行掃描。
5.46 GenericWebApplicationContext
繼承自GenericApplicationContext,實現了ConfigurableWebApplicationContext和ThemeSource接口。該類設計的目的不是在web.xml中進行聲明式的安裝,而是編程式的安裝,例如使用WebApplicationInitializers來構建內嵌的上下文。該接口在ConfigurableWebApplicationContext的內容都是一個偽實現,調用其中的大多數方法都會拋出異常。他實現了ThemeSource接口,設計的目的主要是用於消息的國際化。
5.47 GroovyWebApplicationContext
繼承自AbstractRefreshableWebApplicationContext,實現了GroovyObject接口,接受能被GroovyBeanDefinitionReader所理解的groovy bean定義腳本和XML文檔配置。對於web環境,基本上是和GenericGroovyApplicationContext是等價的。對於根上下文,默認的配置文件路徑是/WEB-INF/applicationContext.groovy,對於命名空間為test-servlet的上下文,默認的配置文件路徑是/WEB-INF/test-servlet.xml(就像servlet-name為test的DispatcherServlet實例)。
5.48 StaticWebApplicationContext
繼承自StaticApplicationContext,實現了ConfigurableWebApplicationContext和ThemeSource接口。該接口主要是用在測試的環境,不用於產品環境。
5.49 XmlWebApplicationContext
繼承自AbstractRefreshableWebApplicationContext,用於web容器的應用上下文,接受能被XmlBeanDefinitionReader所理解的XML文檔配置。對於根上下文,默認的配置文件路徑是/WEB-INF/applicationContext.xml,對於命名空間為test-servlet的上下文,默認的配置文件路徑是/WEB-INF/test-servlet.xml(就像servlet-name為test的DispatcherServlet實例)。
5.50 ServletContextAttributeExporter
接受Spring定義的對象並將其公開為 ServletContext屬性。通常,bean引用轉換成Spring定義的bean,這些bean作為ServletContext屬性用。
ServletContext是javax.servlet包內定義的接口,Web容器會為每個Web程序構造一個實現該接口的對象實例,通過這個對象,Servlet可以和web容器進行交互,如獲取Web容器版本號,通過Web容器的日志機制記錄信息等;也可以和同一Web程序的其他Servlet進行交流,如可以通過該對象的屬性來共享數據。
5.51 ServletContextAttributeFactoryBean
FactoryBean接口實現類,用來獲取一個指定的、存在的ServletContext屬性。
5.52 ServletContextParameterFactoryBean
FactoryBean接口實現類,用來獲取一個指定的、存在的ServletContext參數。
5.53 ServletContextAwareProcessor
FactoryBean接口實現類,用來獲取一個指定的ServletContext初始參數(在web.xml中定義的一個"context-param")。
5.54 ServletContextLiveBeansView
LiveBeansView子類,在web應用中尋找所有的ApplicationContexts,暴露在ServletContext屬性中。
5.55 ServletContextResource
Spring提供了ServletContextResource類來訪問Web Context下相對路徑下的資源,ServletContextResource構造器接受一個代表資源位置的字符串參數,該資源位置是相對於Web應用根路徑的位置。
使用ServletContextResource訪問的資源, 也可通過文件IO訪問或URL訪問。通過java.io.File訪問要求資源被解壓縮,而且在本地文件系統中;但使用ServletContextResource進行訪問時則無須資源是否被解壓縮出來,或則直接存放在JAR文件中,總可通過Servlet容器訪問。
5.56 ServletContextPropertySource
Spring3.1提供了新的屬性管理API,而且功能非常強大且很完善,對於一些屬性配置信息都應該使用新的API來管理。
PropertySource是新的屬性管理API,一個抽象類,它包含一個source和一個name。source可以是map或其他,通常是一組鍵值對。
ServletContextPropertySource的屬性來自ServletContext上下文初始化參數等等。
5.57 ServletConfigPropertySource
ServletConfigPropertySource的源為ServletConfig。
5.58 ServletContextResourceLoader
繼承自DefaultReourceLoader,重寫了getResourceByPath(String path)方法,該類的擴展功能是可以從Servlet上下文的根目錄加載資源。
5.59 ServletContextResourcePatternResolver
ServletContext-aware的PathMatchingResourcePatternResolver的子類,能夠通過ServletContext#getResourcePaths方法在web應用根目錄下查找所有匹配額資源。轉到其父文件系統查找其他資源。
5.60 ServletContextScope
表示其生命周期、作用范圍是ServletContext。
ServletContext是一個全局的儲存信息的空間,服務器開始,其就存在,服務器關閉,其才釋放。request,一個用戶可有多個;session,一個用戶一個;而servletContext,所有用戶共用一個。
運行在Java虛擬機中的每一個Web應用程序都有一個與之相關的Servlet上下文。ServletContext對象是Web服務器中的一個已知路徑的根。一個ServletContext對象表示了一個Web應用程序的上下文。
5.61 ContextExposingHttpServletRequest
HttpServletRequest裝飾器,使得在一個給定的WebApplicationContext中的所有Spring beans能夠當成請求屬性進行存取。
5.62 HttpRequestHandlerServlet
一簡單的HttpServlet,代理一個在Spring root WebApplicationContext中定義的HttpRequestHandler bean。目標bean的名字必須和在web.xml中定義的HttpRequestHandlerServlet servlet-name匹配。
5.63 LiveBeansViewServlet
暴露LiveBeansView MBean的Servlet。為當前的beans和它們在所有ApplicationContexts中的依賴做一個json鏡像。
通常我們的Bean都是由Spring啟動時通過讀取配置加載進Spring容器的,我們可以讓Spring去管理我們的Bean的生成、配置以及Bean與Bean之間的依賴。但是Spring一旦啟動完畢,再想去修改Bean的配置,就要用到JMX了。JMX技術的前提就是你得提供MBean,把我們的Spring Bean變為Mbean。
JMX(Java Management Extensions,即Java管理擴展)是一個為應用程序、設備、系統等植入管理功能的框架。
5.64 RequestHandledEvent
請求處理事件,當一個請求被處理完成時發布。
5.65 ServletRequestHandledEvent
RequestHandledEvent的子類,增加了servlet-specific上下文信息。
5.66 SpringBeanAutowiringSupport
工具類,主要用來對Spring Web Application上下文的類提供@Autowired注入功能。
5.67 StandardServletEnvironment
Environment接口的實現類,被Servlet web應用所使用。所有web相關的ApplicationContext類默認都會初始化一個實例。
5.68 WebApplicationContextUtils
抽象類,其提供了一個很便利的方法來獲取spring應用的上下文即WebApplicationContext。
5.69 WebApplicationObjectSupport
在WebApplicationContext中運行的應用對象的功能父類,提供了getWebApplicationContext()、getServletContext()、getTempDir()等方法。
六、web/cors
6.1 CorsConfiguration
具體封裝跨域配置信息的pojo。
6.2 CorsConfigurationSource
request與跨域配置信息映射的容器。
6.3 CorsProcessor
具體進行跨域操作的類。
6.4 CorsUtils
基於CORS W3C recommendation的跨域資源請求處理的工具類。
6.5 DefaultCorsProcessor
CorsProcessor接口的默認實現。
6.6 UrlBasedCorsConfigurationSource
存儲request與跨域配置信息的容器。
web/cors/reactive
6.7 CorsConfigurationSource
request與跨域配置信息映射的容器。
6.8 CorsProcessor
具體進行跨域操作的類。
6.9 CorsUtils
基於CORS W3C recommendation的跨域資源響應式請求處理的工具類。
6.10 CorsWebFilter
WebFilter接口的實現類,處理CORS 跨域中的 preflight 請求,借助於CorsProcessor接口的實現類(默認為DefaultCorsProcessor)對CORS請求進行攔截,目的是在CorsConfigurationSource容器中添加相關的CORS響應頭(比如Access-Control-Allow-Origin)。
6.11 DefaultCorsProcessor
CorsProcessor接口的默認實現。
6.12 UrlBasedCorsConfigurationSource
存儲響應式request與跨域配置信息的容器。
七、web/filter
Spring的web包中有很多過濾器,這些過濾器位於org.springframework.web.filter,實現了javax.servlet.Filter,實現方式有以下幾類:
1、直接實現Filter,這一類過濾器只有CompositeFilter。
2、繼承抽象類GenericFilterBean,該類實現了javax.servlet.Filter,這一類的過濾器只有一個,即DelegatingFilterProxy。
3、繼承抽象類OncePerRequestFilter,該類為GenericFilterBean的直接子類,這一類過濾器包括CharacterEncodingFilter、HiddenHttpMethodFilter、HttpPutFormContentFilter、RequestContextFilter和ShallowEtagHeaderFilter。
4、繼承抽象類AbstractRequestLoggingFilter,該類為OncePerRequestFilter的直接子類,這一類過濾器包括CommonsRequestLoggingFilter、Log4jNestedDiagnosticContextFilter和ServletContextRequestLoggingFilter。
7.1 CompositeFilter
混合過濾器,通過將加入各種過濾器邏輯集filters加入到該混合器,按照過濾鏈FilterChain進行統一處理。
7.2 GenericFilterBean
抽象類GenericFilterBean實現了javax.servlet.Filter、org.springframework.beans.factory.BeanNameAware、org.springframework.context.EnvironmentAware、org.springframework.web.context.ServletContextAware、org.springframework.beans.factory.InitializingBean和org.springframework.beans.factory.DisposableBean六個接口,作用如下:
1、Filter,實現過濾器。
2、BeanNameAware,實現該接口的setBeanName方法,便於Bean管理器生成Bean。
3、EnvironmentAware,實現該接口的setEnvironment方法,指明該Bean運行的環境。
4、ServletContextAware,實現該接口的setServletContextAware方法,指明上下文。
5、 InitializingBean,實現該接口的afterPropertiesSet方法,指明設置屬性的操作。
6、DisposableBean,實現該接口的destroy方法,用於回收資源。
7.3 DelegatingFilterProxy
該類其實並不能說是一個過濾器,它的原型是FilterToBeanProxy,即將Filter作為spring的bean,由spring來管理。該類提供了在web.xml和application context之間的聯系。
有以下幾個參數可以設置:
1、contextAttribute,使用委派Bean的范圍,其值必須從org.springframework.context.ApplicationContext.WebApplicationContext中取得,默認值是session;其他可選的有request、globalSession和application。
2、targetFilterLifecycle,是否調用Filter的init和destroy方法,默認為false。
3、targetBeanName,被代理的過濾器的bean的名字,該bean的類必須實現Filter接口。
7.4 OncePerRequestFilter
該類為GenericFilterBean的直接子類,它保留了GenericFilterBean中的所有方法並對之進行了擴展,在oncePerRequestFilter中的主要方法是doFilter。
7.5 CharacterEncodingFilter
該過濾器是配置編碼格式的。服務器啟動的時候就會創建Filter,將init-param中的參數加載,注入到CharacterEncodingFilter 類中,瀏覽器每次發送請求都會經過這個過濾器,然后調用doFilterInternal。
7.6 HiddenHttpMethodFilter
html中form表單只支持GET與POST請求,而DELETE、PUT等method並不支持,spring3添加了一個過濾器,可以將這些請求轉換為標准的http方法,使得支持GET、POST、PUT與DELETE請求。
7.7 HttpPutFormContentFilter
由HiddenHttpMethodFilter可知,html中的form的method值只能為post或get,我們可以通過HiddenHttpMethodFilter獲取put表單中的參數鍵值對,而在Spring3中獲取put表單的參數鍵值對還有另一種方法,即使用HttpPutFormContentFilter過濾器。
HttpPutFormContentFilter過濾器的作為就是獲取put表單的值,並將之傳遞到Controller中標注了method為RequestMethod.put的方法中。
與HiddenHttpMethodFilter不同,在form中不用添加參數名為_method的隱藏域,且method不必是post,直接寫成put,但該過濾器只能接受enctype值為application/x-www-form-urlencoded的表單。
7.8 RequestContextFilter
這是在Spring2.0時添加的類,通過LocaleContextHolder和RequestContextHolder把Http request對象基於LocalThread綁定到請求提供服務的線程上。現在一般使用DispatcherServlet這個中央分發器。現在RequestContextFilter過濾器主要用於第三方的Servlet,如JSF的FacesServlet。在Spring2.5之前都是使用該過濾器配置。
7.9 ShallowEtagHeaderFilter
ShallowEtagHeaderFilter是spring提供的支持ETag的一個過濾器,所謂ETag是指被請求變量的實體值,是一個可以與Web資源關聯的記號,而Web資源可以是一個Web頁,也可以是JSON或XML文檔,服務器單獨負責判斷記號是什么及其含義,並在HTTP響應頭中將其傳送到客戶端。
7.10 CorsFilter
跨域請求過濾器。
7.11 FormContentFilter
該過濾器為HTTP的PUT、 PATCH和 DELETE請求解析表單數據,並暴露它為Servlet請求參數。默認情況下,Servlet spec僅要求對HTTP post進行此過濾。
7.12 RelativeRedirectResponseWrapper
Response包裝器,主要在RelativeRedirectFilter和 ForwardedHeaderFilter中使用。
7.13 ForwardedHeaderFilter
RFC 7239提出了一個標准化的Forwarded頭部,來攜帶反向代理的基本信息,用於替代X-Forwarded系列及X-Real-IP等非標准化的頭部。而ForwardedHeadersFilter提供了Forwarded頭部的轉發支持。
7.14 RelativeRedirectFilter
Servlet過濾器,將request 請求暴露給當前的線程,主要通過org.springframework.context.i18n.LocaleContextHolder和RequestContextHolder。該過濾器在web.xml中注冊。
7.15 AbstractRequestLoggingFilter
上下文信息過濾器 ,定義了兩個方法beforeRequest和afterRequest分別用於設定過濾前后執行的操作,它有三個子類,分別是CommonsRequestLoggingFilter、ServletContextRequestLoggingFilter和Log4jNestedDiagnosticContextFilter,這三個子類分別實現了各自的beforeRequest和afterRequest。
7.16 CommonsRequestLoggingFilter
繼承自AbstractRequestLoggingFilter,CommonsRequestLoggingFilter在過濾前后分別打印出一段debug的信息。
7.17 ServletContextRequestLoggingFilter
繼承自AbstractRequestLoggingFilter,ServletContextRequestLoggingFilter在過濾前后分別向日志文件中寫入一段日志信息,日志文件可由log4j.properties等指定。
web/filter/reactive。
7.18 ForwardedHeaderFilter
從"Forwarded"和"X-Forwarded-*"頭部提取值,用來重寫請求報文的URI。
7.19 HiddenHttpMethodFilter
響應式的webFilter,html中form表單只支持GET與POST請求,而DELETE、PUT等method並不支持,spring3添加了一個過濾器,可以將這些請求轉換為標准的http方法,使得支持GET、POST、PUT與DELETE請求。
7.20 ServerWebExchangeContextFilter
在響應式Context中插入屬性(屬性名EXCHANGE_CONTEXT_ATTRIBUTE),使得當前的ServerWebExchange可獲得。在想訪問ServerWebExchange但是又不顯示的將其傳奇給參與處理請求的組件時有用。
ServerWebExchange 命名為 服務網絡交換器 ,存放着重要的請求-響應屬性、請求實例和響應實例等等。
八、web/jsf
JavaServer Faces (JSF) 是一種用於構建Java Web 應用程序的標准框架(是Java Community Process 規定的JSR-127標准)。它提供了一種以組件為中心的用戶界面(UI)構建方法,從而簡化了Java服務器端應用程序的開發。它是一種頁面表示技術。
8.1 DecoratingNavigationHandler
JSF NavigationHandler實現類的基類,用來裝飾原始的NavigationHandler。
8.2 DelegatingNavigationHandlerProxy
JSF NavigationHandler實現類,代理從Spring root WebApplicationContext容器中獲取的NavigationHandler bean。
在faces-config.xml文件中配置該handler proxy。如下:
<pre class=""code"">
<application>
...
<navigation-handler>
org.springframework.web.jsf.DelegatingNavigationHandlerProxy
</navigation-handler>
...
</application>
</pre>
8.3 DelegatingPhaseListenerMulticaster
JSF PhaseListener接口實現類,代理一個或多個從Spring root WebApplicationContext容器中獲取的Spring-managed PhaseListener bean。
在faces-config.xml文件中配置該listener multicaster。如下:
<pre class=""code"">
<application>
...
<phase-listener>
org.springframework.web.jsf.DelegatingPhaseListenerMulticaster
</phase-listener>
...
</application>
</pre>
8.4 FacesContextUtils
為一個JSF FacesContext提取Spring的root WebApplication提供功能函數。用於在基於JSF框架的代碼中訪問Spring的application context情況下。
它類似於Spring中為ServletContext提供功能函數的WebApplicationContextUtils,該類是為FacesContext提供工具包。
web/jsf/el
8.5 SpringBeanFacesELResolver
JSF ELResolver接口的實現類,代理Spring的root WebApplicationContext。將名稱引用解析成Spring定義的beans。
在faces-context.xml文件中配置該解析器如下:
<pre class=""code"">
<application>
...
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
</pre>
8.6 WebApplicationContextFacesELResolver
繼承自JSF ELResolver,暴露Spring的WebApplicationContext一個實例,該實例變量的名字為"webApplicationContext"。
九、web/method
9.1 ControllerAdviceBean
該類關於@ControllerAdvice注解的相關信息,spring管理bean,並不要求一定要對其進行實例化。使用函數findAnnotatedBeans(ApplicationContext)可以來查找這種bean。這種bean可以被任何對象創建,包括沒有加@ControllerAdvice注解的對象。
對於@ControllerAdvice,我們比較熟知的用法是結合@ExceptionHandler用於全局異常的處理,但其作用不僅限於此。ControllerAdvice拆分開來就是Controller Advice,Advice用於封裝一個切面所有屬性的,包括切入點和需要織入的切面邏輯。這里ContrllerAdvice也可以這么理解,其抽象級別應該是用於對Controller進行“切面”環繞的,而具體的業務織入方式則是通過結合其他的注解來實現的。@ControllerAdvice是在類上聲明的注解,其用法主要有三點:
結合方法型注解@ExceptionHandler,用於捕獲Controller中拋出的指定類型的異常,從而達到不同類型的異常區別處理的目的;
結合方法型注解@InitBinder,用於request中自定義參數解析方式進行注冊,從而達到自定義指定格式參數的目的;
結合方法型注解@ModelAttribute,表示其標注的方法將會在目標Controller方法執行之前執行。
9.2 HandlerMethod
封裝了處理函數的信息,包括getMethod()、getBean()。提供了對方法的參數、返回值、注解等等方便的存取方法。
9.3 HandlerTypePredicate
繼承自Predicate接口。Predicate接口是JDK8 提供的函數式接口,提供一個抽象方法test, 接受一個參數,根據這個參數進行一些判斷,返回判斷結果 true/false。
web/method/annotation
9.4 AbstractCookieValueMethodArgumentResolver
抽象基類,用來解析帶@CookieValue注解的方法參數。實現的子類會從請求報文中將cookie值提取出來。@CookieValue注解主要是將請求的Cookie數據,映射到功能處理方法的參數上。
9.5 AbstractNamedValueMethodArgumentResolver
該抽象基類用來從命名值(named value)解析方法參數。如請求參數、請求的頭部信息、URL路徑變量都是命名值。每一個都有一個名字,一個必要的標志、一個默認值。
9.6 AbstractWebArgumentResolverAdapter
使用@WebArgumentResolver的基類,用於向后兼容適配WebArgumentResolver。
9.7 ErrorsMethodArgumentResolver
處理Errors子類參數。
9.8 ExceptionHandlerMethodResolver
在一個給定的類(包括它所有的子類)中找到用@ExceptionHandler注解的方法,然后幫助解析一個給定Exceptin到exception types。
9.9 ExpressionValueMethodArgumentResolver
解析@Value注解的參數。
9.10 RequestHeaderMapMethodArgumentResolver
處理使用@RequestHeader注解的map參數。
9.11 RequestHeaderMethodArgumentResolver
解析使用@RequestHeader注解的參數,不包括map類型。
9.12 RequestParamMapMethodArgumentResolver
處理使用@RequestParam注解的map參數。
9.13 RequestParamMethodArgumentResolver
解析從request流中獲取值的參數,如@RequestParam、MultipartFile、Part,默認使用時解析基本參數。
9.14 SessionStatusMethodArgumentResolver
處理SessionStatus類型參數。
9.15 SessionAttributesHandler
SessionAttributesHandler用來處理@SessionAttributes注釋的參數,不過它只是做一些宏觀的事情,比如,哪個Handler都可以緩存哪些參數、某個參數在當前的SessionAttributes中是否存在、如何同時操作多個參數等,而具體的存儲工作是交給SessionAttributeStore去做的,不過SessionAttributeStore並不是保存數據的容器,而是用於保存數據的工具,具體保存數據的容器默認使用的是Session。
9.16 ModelFactory
ModelFactory是用來維護Model的,具體包含兩個功能:1、初始化Model。2、處理器執行后將Model中相應的參數更新到SessionAttributes中。
9.17 InitBinderDataBinderFactory
通過@InitBinder注解的方法來初始化WebDataBinder。
9.18 MapMethodProcessor
處理map類型參數。
9.19 ModelMethodProcessor
處理model類型參數。
9.20 ModelAttributeMethodProcessor
解析使用@ModelAttribute注解參數。
9.21 MethodArgumentConversionNotSupportedException
在解析一個方法參數時引發的異常,提供了到目標MethodParameter的訪問方法。
9.22 MethodArgumentTypeMismatchException
在解析一個控制器方法參數時引發的異常,提供了到目標MethodParameter的訪問方法。
web/method/support
9.23 CompositeUriComponentsContributor
UriComponentsContributor接口的實現類,包含了一列contributors,還封裝了一個特定的ConversionService用來將方法參數值轉化成字符串格式。
9.24 HandlerMethodArgumentResolver
參數解析器,主要用途:統一封裝登錄的用戶信息;進行數據綁定,參數驗證。Spring MVC處理入參靠的是HandlerMethodArgumentResolver這個接口,解析返回值靠的是HandlerMethodReturnValueHandler這個策略接口。
9.25 HandlerMethodArgumentResolverComposite
所有的參數解析器的鏈表,保存了springMVC提供的所有的參數解析器,采用職責鏈的模式來完成參數解析器的查找,並完成參數解析生成目標對象。
9.26 HandlerMethodReturnValueHandler
策略接口,用來對調用處理函數之后的返回值進行處理,總共就兩個方法;
boolean supportsReturnType();
void handleReturnValue()
9.27 HandlerMethodReturnValueHandlerComposite
springMVC提供的所有的HandlerMethodReturnValueHandler集合,它定義了一個鏈表用於存儲所有實現的HandlerMethodReturnValueHandler。
9.28 AsyncHandlerMethodReturnValueHandler
繼承自HandlerMethodReturnValueHandler,支持異步模式。
9.29 InvocableHandlerMethod
InvocableHandlerMethod是對HandlerMethod的擴展,基於一組HandlerMethodArgumentResolver從請求上下文中解析出控制器方法的參數值,然后調用控制器方法。
9.30 ModelAndViewContainer
可以把它定義為ModelAndView上下文的容器,它承擔着整個請求過程中的數據傳遞工作,保存着Model和View。記錄HandlerMethodArgumentResolver和 HandlerMethodReturnValueHandler在處理Controller的handler方法時 使用的模型model和視圖view相關信息.。
9.31 UriComponentsContributor
幫助構建一個UriComponents,通過查找一個方法參數和參數值,決定目標URL哪一部分需要更新。
十、web/multipart
multipart/form-data請求說明:
先看一個帶multipart/form-data的請求報文。假設客戶端發送內容構造,接受文件的網頁程序位於 http://192.168.29.65/upload_file/UploadFile,我們要發送一個二進制文件、一個文本框表單項、一個密碼框表單項。文件名為 E:\s ,其內容如下:(其中的XXX代表二進制數據,如 01 02 03)abbXXXccc 客戶端應該向 192.168.29.65 發送如下內容:
POST /upload_file/UploadFile HTTP/1.1
Accept: text/plain, */*
Accept-Language: zh-cn
Host: 192.168.29.65:80
Content-Type:multipart/form-data;boundary=---------------------------7d33a816d302b6
User-Agent: Mozilla/4.0 (compatible; OpenOffice.org)
Content-Length: 424
Connection: Keep-Alive -----------------------------7d33a816d302b6
Content-Disposition:form-data;
name="userfile1";
filename="E:\s"Content-Type:
application/octet-stream abbXXXccc
-----------------------------7d33a816d302b6
Content-Disposition: form-data;
name="text1" foo
-----------------------------7d33a816d302b6
Content-Disposition: form-data;
name="password1" bar
—-----------------------------7d33a816d302b6—
注意這一行:
Content-Type: multipart/form-data; boundary=---------------------------7d33a816d302b6
根據 rfc1867,multipart/form-data是必須的。---------------------------7d33a816d302b6 是分隔符,分隔多個文件、表單項。 其中33a816d302b6 是即時生成的一個數字,用以確保整個分隔符不會在文件或表單項的內容中出現。前面的 ---------------------------7d 是 IE 特有的標志。
在最初的http協議中,沒有文件上傳功能。rfc1867為http協議添加了這個功能:multipart/form-data。客戶端瀏覽器按照此規范將用戶指定的文件發送到服務器。服務器端的網頁程序(如php、asp、jsp)按照此規范解析出用戶發送來的文件。
1、multipart/form-data的基礎方式是post,也就是說通過post組合方式來實現的。
2、multipart/form-data於post方法的不同之處在於請求頭和請求體。
3、multipart/form-data的請求頭必須包含一個特殊的頭信息:Content-Type,其值也必須為multipart/form-data,同時還需要規定一個內容分割用於分割請求提中多個post的內容,如文件內容和文本內容是需要分隔開來的,不然接收方就無法解析和還原這個文件了,具體的頭信息如下:
Content-Type: multipart/form-data; boundary=${bound}
其中${bound} 是一個占位符,代表我們規定的分割符,可以自己任意規定,但為了避免和正常文本重復了,盡量要使用復雜一點的內容。如上例中的:--------------------7d33a816d302b6
4、multipart/form-data的請求體也是一個字符串,不過和post的請求提不同的是它的構造方式,post是簡單的name=value鍵值連接,而multipart/form-data是添加了分隔符等內容的構造體。
10.1 MultipartFile
繼承自InputStreamSource接口,表示在一個接收到的multipart請求中的上傳文件。文件的內容要么存儲在內存中,要么暫時存在磁盤中。如果有要求的話,不管采取方式,用戶都需要將文件的內容拷貝到會話級別或者永久性的存儲中。臨時性的存儲會在multipart請求處理完畢后進行清空。
10.2 MultipartFileResource
使MultipartFile適配org.springframework.core.io.Resource,以InputStream暴露文件內容,重寫方法contentLength()和getFilename()。
10.3 MultipartRequest
這個接口定義了multipart請求的存取操作。該接口被MultipartHttpServletRequest繼承。
10.4 MultipartHttpServletRequest
繼承自HttpServletRequest、MultipartRequest。在servlet request中提供了額外的方法,專門用來處理multipart內容,允許存取上傳的文件。
10.5 MultipartResolver
MultipartResolver 用於處理文件上傳,當收到請求時 DispatcherServlet 的 checkMultipart() 方法會調用 MultipartResolver 的 isMultipart() 方法判斷請求中是否包含文件。如果請求數據中包含文件,則調用 MultipartResolver 的 resolveMultipart() 方法對請求的數據進行解析,然后將文件數據解析成 MultipartFile 並封裝在 MultipartHttpServletRequest (繼承了 HttpServletRequest)對象中,最后傳遞給 Controller,在 MultipartResolver 接口中有如下方法:
boolean isMultipart(HttpServletRequest request); // 是否是 multipart
MultipartHttpServletRequest resolveMultipart(HttpServletRequest request); // 解析請求
void cleanupMultipart(MultipartHttpServletRequest request);
10.6 MultipartException
multipart解析失敗時拋出的異常。
10.7 MaxUploadSizeExceededException
繼承自MultipartException,當上傳的文件大小超過了最大限制時拋出的異常。
web/multipart/commons
10.8 CommonsFileUploadSupport
使用Apache的Commons FileUpload組件(1.2或者更高的版本)的multipart解析器的基類。
10.9 CommonsMultipartFile
MultipartFile接口的實現類,專為Apache Commons FileUpload。
10.10 CommonsMultipartResolver
使用 commons Fileupload 來處理 multipart 請求。在使用時要引入相應的 jar 包。
web/multipart/support
10.11 MultipartFilter
Servlet過濾器,在root WebApplicationContext容器中通過一個MultipartResolver來解析multipart請求。
10.12 MultipartResolutionDelegate
HandlerMethodArgumentResolver接口實現類的一個通用代理,用來解析MultipartFile和Part參數。
10.13 AbstractMultipartHttpServletRequest
MultipartHttpServletRequest接口實現類的抽象基類。提供了對預生成的MultipartFile實例的管理。
10.14 DefaultMultipartHttpServletRequest
MultipartHttpServletRequest接口的默認實現,提供了對預生成的參數值的管理。該類在CommonsMultipartResolver中使用。
10.15 RequestPartServletServerHttpRequest
ServerHttpRequest接口的實現類,用來存取multipart請求的一部分。如果使用MultipartResolver配置,該部分就通過MultipartFile進行存取。如果使用Servlet 3.0進行multipart處理,該部分就通過ServletRequest.getPart進行存取。
10.16 StandardMultipartHttpServletRequest
Spring MultipartHttpServletRequest的適配器,包裝了一個ervlet 3.0 HttpServletRequest和它的Parts對象。
10.17 StandardServletMultipartResolver
基於 Servlet 3.0來處理 multipart 請求的,所以不需要引用其他 jar 包,但是必須使用支持 Servlet 3.0的容器才可以,以tomcat為例,從 Tomcat 7.0.x的版本開始就支持 Servlet 3.0了。
10.18 ByteArrayMultipartFileEditor
個性化的java.beans.PropertyEditor,用來將MultipartFiles轉換成字節數組。
10.19 StringMultipartFileEditor
個性化的java.beans.PropertyEditor,用來將MultipartFiles轉換成字符串。允許指定使用的字符集。
10.20 MissingServletRequestPartException
當通過名字進行尋找一個"multipart/form-data" 請求的一部分,但是查找不到時拋出異常。
十一、web/server
11.1 ServerWebExchange
ServerWebExchange名為服務網絡交換器,是一個HTTP請求-響應交互的契約。提供對HTTP請求和響應的訪問,並公開額外的服務器端處理相關屬性和特性,如請求屬性。存放着重要的請求-響應屬性、請求實例和響應實例等等,有點像Context的角色。
11.2 ServerWebExchangeDecorator
ServerWebExchange裝飾類,用於需要封裝一個ServerWebExchange的類的基類,通過委托給包裝實例預實現所有方法。
11.3 DefaultServerWebExchangeBuilder
ServerWebExchange的內部接口ServerWebExchange.Builder的實現類。
11.4 WebSession
使用服務器端會話的主要約定,提供了同HTTP請求間會話屬性的訪問。創建WebSession實例並不會自動開啟一個會話。會話屬性添加完畢后,調用WebSession.start()函數才開啟一個會話,繼而將會話id發送到客戶端(比如通過cookie)。
Cookie機制和Session機制用來唯一標識一個用戶,同時記錄該用戶的狀態。cookie是存儲子在客戶端,而Session是存儲在服務器端。
Session機制:采用的是在服務器端保持Http狀態信息的方案。服務器使用一種類似於散列表的結構(也可能就是使用散列表)來保存信息。
當程序需要為某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求里是否包含了一個session標識(即sessionId),如果已經包含一個sessionId則說明以前已經為此客戶創建過session,服務器就按照session id把這個session檢索出來使用。如果客戶請求不包含sessionId,則為此客戶創建一個session並且生成一個與此session相關聯的sessionId,這個sessionId將在本次響應中返回給客戶端保存。
11.5 WebFilter
使用攔截器鏈的方式來處理web請求的約定,主要被用來實現橫切請求,比如安全。
11.6 WebFilterChain
過濾器鏈,使得鏈中的web過濾器轉到下一個。
11.7 WebHandler
處理一個web請求。該接口定義了一個函數handle(ServerWebExchange exchange)。
11.8 WebExceptionHandler
對在執行處理ServerWebExchange時發生的異常進行處理。
11.9 ResponseStatusException
和指定的HTTP響應狀態碼相關的異常的基類。
11.10 ServerWebInputException
Spring web應用中遇到了響應狀態碼400(400 bad request,請求報文存在語法錯誤)拋出的異常。
11.11 MethodNotAllowedException
接收到響應狀態碼405(Method Not Allowed,請求行中指定的請求方法不能被用於請求相應的資源。)時拋出的異常。
11.12 ServerErrorException
HttpStatus為INTERNAL_SERVER_ERROR(服務器遇到了一個未曾預料的狀況,導致了它無法完成對請求的處理。)時拋出的異常。
11.13 NotAcceptableStatusException
發生response status 406(Not Acceptable請求的資源的內容特性無法滿足請求頭中的條件,因而無法生成響應實體。)拋出的異常。
11.14 MediaTypeNotSupportedStatusException
發生response status 415(Unsupported Media Type,對於當前請求的方法和所請求的資源,請求中提交的實體並不是服務器中所支持的格式,因此請求被拒絕。)拋出的異常。
11.15 UnsupportedMediaTypeStatusException
發生response status 415(Unsupported Media Type,對於當前請求的方法和所請求的資源,請求中提交的實體並不是服務器中所支持的格式,因此請求被拒絕。)拋出的異常。
web/server/adapter
11.16 AbstractReactiveWebInitializer
繼承自AbstractReactiveWebInitializer的類,可以在servlet容器中安裝一個Spring Reactive Web Application。它通過將ServletHttpHandlerAdapter實例作為一個servlet安裝到servler容器中。
11.17 DefaultServerWebExchange
ServerWebExchange接口的默認實現類。
11.18 ForwardedHeaderTransformer
處理HTTP頭部,包括提取和移除某些頭部鍵值對,或者只移除。
11.19 HttpWebHandlerAdapter
WebHandler的適配器。默認情況下創建和配置一個DefaultServerWebExchange,然后調用目標WebHandler。
11.20 WebHttpHandlerBuilder
此構建器有兩個用途:
一是用來組裝由目標WebHandler組成的處理鏈,使用一系列的WebFilters來裝飾,更進一步的裝飾使用一系列的WebExceptionHandlers。
二是借助HttpWebHandlerAdapter適配器使生成的處理器鏈適配一個HTTPHandler。
web/server/handler
11.21 DefaultWebFilterChain
WebFilterChain接口的默認實現,該類的每一個實例都表示鏈中的一個對象,構造器DefaultWebFilterChain(WebHandler, List)初始化了整個鏈,並執行鏈中第一個對象。
11.22 ExceptionHandlingWebHandler
WebHandler裝飾器,調用一個或者多個WebExceptionHandlers。
11.23 FilteringWebHandler
通過WebFilter進行過濾處理的類,類似於Servlet中的Filter。
11.24 ResponseStatusExceptionHandler
通過設置響應的狀態碼來處理ResponseStatusException類型的異常。
11.25 WebHandlerDecorator
WebHandler的裝飾器,利用裝飾模式實現相關功能的擴展。
web/server/i18n
11.26 LocaleContextResolver
springMVC給我們提供了國際化支持,簡單來說就是設置整個系統的運行語言,然后根據系統的運行語言來展示對應語言的頁面,一般我們稱之為多語言。springMVC國際化機制就是可以設置整個系統的運行語言。
LocaleContext該接口決定當前真正的Locale。
LocaleContextResolver:該接口用於解析基於web的local contex,允許通過request決定這個local context或者通過HTTP exchange來修改這個local contex。
11.27 AcceptHeaderLocaleContextResolver
LocaleContextResolver接口的實現類,解析器檢查HTTP request中攜帶的"Accept-Language" 請求頭,通常該請求頭字段中包含了客戶端地區信息。(這個地區信息由客戶端瀏覽器發送,在客戶端的操作系統中體系)。該解析器不支持設置LocalContext,
11.28 FixedLocaleContextResolver
LocaleContextResolver接口的實現類,一直使用固定的Local,不支持改變Local。默認的為JVM的默認local。
web/server/session
11.29 WebSessionIdResolver
WebSessionIdResolver定義了session id解析策略的契約。允許通過請求解析session id,並通過響應來發送session id或者終止會話。包含三個方法:
resolveSessionIds(ServerWebExchange exchange):解析與當前請求相關聯的sessionId。sessionId可能來自Cookie或請求頭。
setSessionId(ServerWebExchange exchange, String sessionId):將給定的sessionId發送給客戶端。這個方法是在創建一個新session時被調用,並告知客戶端新sessionId是什么。
expireSession(ServerWebExchange exchange):指示客戶端結束當前session。當session無效時調用此方法,並應通知客戶端sessionId不再有效。比如,它可能刪除一個包含sessionId的Cookie,或者設置一個HTTP響應頭,其值為空就表示客戶端不再提交sessionId。
11.30 CookieWebSessionIdResolver
基於Cookie的WebSessionIdResolver。
11.31 HeaderWebSessionIdResolver
WebSessionIdResolver接口的實現類,通過從請求頭header中解析出sessionId。
11.32 WebSessionManager
WebSession管理器,為HTTP request提供了訪問WebSession的方法。該接口定義了一個方法getSession(),為一個給定的ServerWebExchange返回WebSession。
11.33 DefaultWebSessionManager
實現了WebSessionManager接口,主要定義了session的創建,啟動,暫停與cookie的關聯的定義。
11.34 WebSessionStore
會話存儲接口,為WebSession持久化保存的策略接口。包含4個函數:
1、createWebSession()創建一個新的WebSession,該函數僅是創建一個會話實例,會話的啟動通過WebSession#start()函數,持久化通過WebSession#save()函數。
2、retrieveSession(String sessionId);根據給定的sessionId返回相應的WebSession。
3、removeSession(String sessionId);刪除指定sessionId的WebSession。
4、updateLastAccessTime(WebSession webSession):更新webSession的時間戳為當前時間。
11.35 InMemoryWebSessionStore
WebSessionStore接口的默認實現,采用map集合的方式來存儲WebSession實例。
十二、web/util
12.1 ContentCachingRequestWrapper
把請求內容緩存起來的代理類。servlet的request body一旦流被讀取了,就無法再次消費了,通過這個類能夠解決HttpServletRequest inputStream只能讀取一次的問題(request.getInputStream())。它使用一個字段:cachedContent來緩存body體里面的內容。
12.2 ContentCachingResponseWrapper
把響應內容緩存起來的代理類。緩存所有要寫入getOutputStream()和getWriter()中的內容,允許該內容通過函數getContentAsByteArray()獲得。
12.3 HtmlCharacterEntityDecoder
幫助類,通過使用實體字符(the referred character)來替換字符實體編碼(character entity references)進行HTML字符串的解碼操作。
12.4 HtmlCharacterEntityReferences
表示在HTML4.0標准中定義的一系列字符實體編碼。完整的描述在https://www.w3.org/TR/html4/charset.html中。
12.5 HtmlUtils
很多時候,由於特殊字符的原因,會造成用戶輸入的信息反饋到頁面上時會顯示成亂碼,造成頁面排版混亂;另外,黑客經常利用特殊字符對網站進行xss跨站攻擊,所以我們需要對頁面上提交的特殊字符進行html轉碼。
轉換為HTML轉義字符表示、轉換為數據轉義表示、轉換為十六進制數據轉義表示。
12.6 JavaScriptUtils
基於JavaScript 1.5 recommendation對JavaScript進行轉義。
12.7 WebUtils
WebUtils:該工具類主要用於Web應用程序,供各種框架使用。主要方法如下:
1、setWebAppRootSystemProperty:表示保存系統根路徑的key-value
2、removeWebAppRootSystemProperty:表示移除系統根路徑的key-value。
3、getDefaultHtmlEscape:看web.xml中的defaultHtmlEscape的值是否設置為true。
4、getTempDir:返回由當前servlet容器提供的 當前Web應用程序的臨時目錄。
5、getRealPath:返回由servlet容器提供的,Web應用程序中給定路徑的實際路徑。
6、getSessionId:返回指定的request的session id。
7、get/setSessionAttribute:根據當前的request和session attributes的name得到/設置session attributes的值。
8、getNativeRequest:返回指定類型的合適的請求對象,如果可用,會unwrapping給定的request請求。
9、getNativeResponse:返回指定類型的response對象。
10、isIncludeRequest:判斷請求是否是一個包含(Include)請求,即不是從外部進入的頂級Http請求。
11、getCookie:獲取制定名字的cookie。
12、getParametersStartingWith:返回包含具有給定前綴的所有參數的map。將單個值映射為String,多個值映射到String數組。
12.8 ServletContextPropertyUtils
用來解析文本中的占位符,常在文件路徑中使用。
12.9 TagUtils
jsp標簽的工具支持類。
12.10 UriUtils
處理uri里特殊字符的編碼。
12.11 HttpSessionMutexListener
HttpSessionListener接口實現類,該Servlet HTTP 會話監聽器會在一個Http會話創建的時候暴露會話的互斥鎖。該監聽器在web.xml中注冊。
12.12 IntrospectorCleanupListener
1、此監聽器主要用於解決java.beans.Introspector導致的內存泄漏的問題。
2、此監聽器應該配置在web.xml中與Spring相關監聽器中的第一個位置(也要在ContextLoaderListener的前面)。
3、JDK中的java.beans.Introspector類的用途是發現Java類是否符合JavaBean規范,如果有的框架或程序用到了Introspector類,那么就會啟用一個系統級別的緩存,此緩存會存放一些曾加載並分析過的JavaBean的引用。當Web服務器關閉時,由於此緩存中存放着這些JavaBean的引用,所以垃圾回收器無法回收Web容器中的JavaBean對象,最后導致 內存變大。
而org.springframework.web.util.IntrospectorCleanupListener就是專門用來處理Introspector內存泄漏問題的輔助類。IntrospectorCleanupListener會在Web服務器停止時清理Introspector緩存,使那些Javabean能被垃圾回收器正確回收。Spring自身不會出現這種問題,因為Spring在加載並分析完一個類之后會馬上刷新JavaBeans Introspector緩存,這就保證Spring中不會出現這種內存泄漏的問題。但有些程序和框架在使用了JavaBeans Introspector之后,沒有進行清理工作(如 Quartz,Struts),最后導致內存泄漏。
12.13 WebAppRootListener
這個listener的作用就是監聽web.xml中的配置param-name為webAppRootKey的值:
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>myroot</param-value>
</context-param>
然后配置這個監聽器:
<listener>
<listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
</listener>
作用:它會在ServletContext上下文初始化的時候,首先獲取根傳遞進來的servletContext得到物理路徑,String path=servletContext.getRealPath(""/"");然后找到context-param的webAooRootKey對應的param-value,把param-value的值作為key,上面配置的是""myroot""。
接着執行System.setProperty(""myroot"",path)。這樣在web中任意地方就可以使用System.getProperty(""myroot"")來獲取系統的絕對路徑。
12.14 UriBuilder
URIBuilder主要用於構造URI,URI(Uniform Resource Identifier)即通一資源標志符,表示的是web上每一種可用的資源,如 HTML文檔、圖像、視頻片段、程序等都由一個URI進行定位的。URL是URI的一個子集,它是Uniform Resource Locator的縮寫,譯為"統一資源定位符"。
12.15 UriBuilderFactory
用來創建UriBuilder實例。
12.16 DefaultUriBuilderFactory
UriBuilderFactory接口的實現類。依靠UriComponentsBuilder來實際創建一個URI。
12.17 UriComponents
表示一系列的不可改變的URI組件,將組件類型映射到字符串值。包含了所有組件的getters方法。實際上,同java.net.URI類似,不過擁有更強的編碼選擇,支持URI template變量。
12.18 OpaqueUriComponents
拓展自UriComponents,支持opaque URIs。
12.19 HierarchicalUriComponents
拓展自UriComponents,支持hierarchical URIs。
12.20 UriComponentsBuilder
Spring MVC 提供了一種機制,可以構造和編碼URI – 使用UriComponentsBuilder和UriComponents。這樣我們不再自己去拼接了,提高了正確性。它可以細粒度的控制URI的各個要素,如構建、擴展模板變量以及編碼。
12.21 UriTemplate
用於處理格式化Uri模板。
12.22 UriTemplateHandler
定義了用來拓展URI模板類的方法。
12.23 AbstractUriTemplateHandler
UriTemplateHandler接口實現類的抽象基類。提供了setBaseUrl和setDefaultUriVariables方法,在子類中不管是URI模板的拓展還是編碼機制都是密切相關的。
12.24 DefaultUriTemplateHandler
UriTemplateHandler接口的默認實現,使用UriComponentsBuilder來擴展和編碼uri的。
12.25 UrlPathHelper
Spring用來處理URL的工具類,位於包org.springframework.web.util內。它幫助Spring MVC處理URL相關的各種難題。
12.26 CookieGenerator
生成Cookie。一般在CAS單點登錄里用得較多。現在都用JWT了,就用得較少了。CAS (Central Authentication Server) 是 Yale 大學發起的一個開源項目,旨在為 Web 應用系統提供一種可靠的單點登錄方法。
Json web token (JWT),是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標准。該token被設計為緊湊且安全的,特別適用於分布式站點的單點登錄(SSO)場景。
12.27 NestedServletException
繼承自ServletException,從message和stacktrace角度來說,是在root處引發的異常,就像NestedChecked/RuntimeException。
web/util/pattern
12.28 SubSequence
用來返回一個數組的一個部分,當要把一個數據的子集傳給另外一個函數但是不希望創建一個新的字符串對象時有用。
12.29 PathPattern
表示一個解析過的路徑模式。包含一系列的路徑元素用來快速匹配。
12.30 PathPatternRouteMatcher
RouteMatcher接口實現類,屬性中包含了一個PathPatternParser對象,該類使用PathContainer和PathContainer表示route和patterns。
12.31 PathPatternParser
解析URI path patterns產生PathPattern實例對象,從而匹配request請求。
12.32 InternalPathPatternParser
解析URI template patterns。它把path pattern分解成許多PathElements,這些PathElements以鏈表形式組織。這些實例可重復使用,但是是非線程安全的。
12.33 PatternParseException
解析pattern時發生問題時拋出的異常。
12.34 PathElement
由抽象語法樹節點創建,用來表示一個路徑模式的通用超類。
12.35 LiteralPathElement
一個文字的路徑元素。在'/foo/bar/goo'模式中,有三個文件的路徑元素:'foo', 'bar'和 'goo'。
12.36 RegexPathElement
正則表達式的路徑元素。用來表示復雜的路徑元素。比如在'/foo/*_*/*_{foobar}' 中, *_* 和*_{foobar}都是正則表達式的路徑元素。
12.37 SeparatorPathElement
路徑分隔符元素,在模式'/foo/bar'總,兩次出現的'/'可以使用SeparatorPathElement類進行表示(如果默認的分隔符是'/')。
12.38 CaptureVariablePathElement
路徑中某一塊是個變量,那么這個變量元素可以使用CaptureVariablePathElement表示。比如在'/foo/{bar}/goo' 中,{bar}就可以用該類表示。
12.39 WildcardPathElement
通配符路徑元素。在'/foo/*/goo'中,這個*就可以用WildcardPathElement來表示。在整個路徑上(如上例),至少要匹配一個字符,但是在一個路徑的的末尾(如linux*),可以匹配0個字符。
12.40 SingleCharWildcardedPathElement
一個文字路徑元素,該元素包括一個或多個通配符'?'(一個?通配符代替一個字符)。
12.41 CaptureTheRestPathElement
一個路徑元素,表示捕獲路徑的其余部分,在'/foo/{*foobar}' 中/{*foobar}就可以用CaptureTheRestPathElement表示。
12.42 WildcardTheRestPathElement
一個路徑元素,表示通配路徑的其余部分。在'/foo/**'中/**就可以用WildcardTheRestPathElement來表示。
本文參考了博客園、CSDN部分文獻。
拓展閱讀:
Spring框架之beans源碼完全解析
Spring框架之AOP源碼完全解析
Spring框架之jdbc源碼完全解析
Spring源碼深度解析之數據庫連接JDBC
Spring框架之jms源碼完全解析
Spring框架之事務源碼完全解析
Spring源碼深度解析之事務
Spring源碼深度解析之Spring MVC
Spring框架之websocket源碼完全解析
WebSocket協議中文版
Spring框架之spring-web web源碼完全解析
Spring框架之spring-web http源碼完全解析
Spring框架之spring-webmvc源碼完全解析