yolov3之pytorch源码解析_springmvc源码架构解析之view
說在前面
前期回顧
sharding-jdbc源碼解析?更新完畢
spring源碼解析 更新完畢
spring-mvc源碼解析 更新完畢
spring-tx源碼解析 更新完畢
spring-boot源碼解析 更新完畢
rocketmq源碼解析 更新完畢
dubbbo源碼解析 更新完畢
netty源碼解析 更新完畢
spring源碼架構更新完畢
springmvc源碼架構更新中
springboot源碼架構計劃中
github https://github.com/tianheframe
sharding-jdbc源碼解析 更新完畢
rocketmq源碼解析?更新完畢
seata 源碼解析 更新完畢
dubbo 源碼解析 更新完畢
netty 源碼解析 更新完畢
源碼解析
org.springframework.web.servlet.View 用于web交互的MVC視圖。實現負責呈現內容和公開模型。單個視圖公開多個模型屬性。這個類和與之相關的MVC方法在Rod Johnson (Wrox, 2002)的專家一對一J2EE設計和開發的第12章中進行了討論。視圖實現可能差別很大。一個明顯的實現是基于jsp的。其他實現可能是基于xsl的,或者使用HTML生成庫。此接口旨在避免限制可能實現的范圍。視圖應該是bean。它們很可能被視圖解析器實例化為bean。由于這個接口是無狀態的,所以視圖實現應該是線程安全的。
String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus";包含響應狀態代碼的HttpServletRequest屬性的名稱。注意:并非所有視圖實現都支持此屬性。
String PATH_VARIABLES = View.class.getName() + ".pathVariables";HttpServletRequest屬性的名稱,該屬性包含帶有路徑變量的映射。映射由基于字符串的URI模板變量名作為鍵及其對應的基于對象的值組成——從URL的片段中提取并轉換類型。注意:并非所有視圖實現都支持此屬性。
String SELECTED_CONTENT_TYPE = View.class.getName() + ".selectedContentType";在內容協商期間選擇的MediaType,它可能比視圖配置的MediaType更具體。例如:“應用程序/盾。example-v1 + xml”和“應用程序/ * + xml”。
String getContentType();如果預先確定,返回視圖的內容類型。可用于提前檢查視圖的內容類型,即在實際呈現嘗試之前。
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;呈現給定指定模型的視圖。第一步是準備請求:在JSP中,這意味著將模型對象設置為請求屬性。第二步是視圖的實際呈現,例如通過RequestDispatcher包含JSP。
org.springframework.web.servlet.SmartView 提供關于視圖的附加信息,如視圖是否執行重定向。
boolean isRedirectView();是否是重定向視圖
org.springframework.web.servlet.view.AbstractView 視圖實現的抽象基類。子類應該是javabean,以便作為spring管理的bean實例進行方便的配置。
提供對視圖可用的靜態屬性的支持,并提供多種方法來指定它們。靜態屬性將與每個呈現操作的給定動態屬性(控制器返回的模型)合并。擴展WebApplicationObjectSupport,這將對某些視圖有幫助。子類只需要實現實際的呈現。
public static final String DEFAULT_CONTENT_TYPE = "text/html;charset=ISO-8859-1";默認contentType
private static final int OUTPUT_BYTE_ARRAY_INITIAL_SIZE = 4096;初始化輸出數組大小
public void setExposeContextBeansAsAttributes(boolean exposeContextBeansAsAttributes) { this.exposeContextBeansAsAttributes = exposeContextBeansAsAttributes; }設置是否讓應用程序上下文中的所有Spring bean都可以作為請求屬性進行訪問,方法是在屬性被訪問后進行惰性檢查。這將使所有此類bean在普通${…}表達式,以及JSTL的c:out值表達式。默認設置是“假”。打開此標志以透明地公開request屬性名稱空間中的所有Spring bean。注意:上下文bean將覆蓋手動添加的任何相同名稱的自定義請求或會話屬性。然而,相同名稱的模型屬性(如顯式地公開給這個視圖)總是會覆蓋上下文bean。
public void setExposedContextBeanNames(String... exposedContextBeanNames) { this.exposedContextBeanNames = new HashSet<String>(Arrays.asList(exposedContextBeanNames)); }指定應該公開的上下文中bean的名稱。如果這是非空的,只有指定的bean才有資格作為屬性公開。如果您想在應用程序上下文中公開所有Spring bean,請打開“exposeContextBeansAsAttributes”標志,但不要為此屬性列出特定的bean名稱。
@Override public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { if (logger.isTraceEnabled()) { logger.trace("Rendering view with name '" + this.beanName + "' with model " + model + " and static attributes " + this.staticAttributes); } Map<String, Object> mergedModel = createMergedOutputModel(model, request, response); prepareResponse(request, response); renderMergedOutputModel(mergedModel, getRequestToExpose(request), response); }準備給定指定模型的視圖,必要時將其與靜態屬性和RequestContext屬性合并。將實際呈現委托給renderMergedOutputModel。這里是模板方法實現
org.springframework.web.servlet.view.AbstractView#createMergedOutputModel 創建包含動態值和靜態屬性的組合輸出映射(從不為空)。動態值優先于靜態屬性。
protected Map<String, Object> createMergedOutputModel(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) { @SuppressWarnings("unchecked") Map<String, Object> pathVars = (this.exposePathVariables ? (Map<String, Object>) request.getAttribute(View.PATH_VARIABLES) : null); // Consolidate static and dynamic model attributes. int size = this.staticAttributes.size(); size += (model != null ? model.size() : 0); size += (pathVars != null ? pathVars.size() : 0); Map<String, Object> mergedModel = new LinkedHashMap<String, Object>(size); mergedModel.putAll(this.staticAttributes); if (pathVars != null) { mergedModel.putAll(pathVars); } if (model != null) { mergedModel.putAll(model); } // Expose RequestContext? if (this.requestContextAttribute != null) { mergedModel.put(this.requestContextAttribute, createRequestContext(request, response, mergedModel)); } return mergedModel; }org.springframework.web.servlet.view.AbstractView#createRequestContext 創建一個RequestContext,在指定的屬性名下公開。默認實現為給定的請求和模型創建一個標準的RequestContext實例。可在自定義實例的子類中重寫。
protected RequestContext createRequestContext( HttpServletRequest request, HttpServletResponse response, Map<String, Object> model) { return new RequestContext(request, response, getServletContext(), model); }org.springframework.web.servlet.view.AbstractView#prepareResponse 為呈現準備給定的響應。默認的實現在通過HTTPS發送下載內容時應用了IE bug的解決方案。
protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) { if (generatesDownloadContent()) { response.setHeader("Pragma", "private"); response.setHeader("Cache-Control", "private, must-revalidate"); } }org.springframework.web.servlet.view.AbstractView#generatesDownloadContent 返回該視圖是否生成下載內容(通常是PDF或Excel文件等二進制內容)。默認實現返回false。如果子類知道在客戶端生成需要臨時緩存的下載內容(通常是通過響應OutputStream),那么在這里鼓勵它們返回true。
org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel 子類必須實現這個方法來實際呈現視圖。第一步是準備請求:在JSP中,這意味著將模型對象設置為請求屬性。第二步是視圖的實際呈現,例如通過RequestDispatcher包含JSP。
org.springframework.web.servlet.view.AbstractView#exposeModelAsRequestAttributes 將給定映射中的模型對象公開為請求屬性。名稱將取自模型映射。此方法適用于javax.servlet.RequestDispatcher可訪問的所有資源。
protected void exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request) throws Exception { for (Map.Entry<String, Object> entry : model.entrySet()) { String modelName = entry.getKey(); Object modelValue = entry.getValue(); if (modelValue != null) { request.setAttribute(modelName, modelValue); if (logger.isDebugEnabled()) { logger.debug("Added model object '" + modelName + "' of type [" + modelValue.getClass().getName() + "] to request in view with name '" + getBeanName() + "'"); } } else { request.removeAttribute(modelName); if (logger.isDebugEnabled()) { logger.debug("Removed model object '" + modelName + "' from request in view with name '" + getBeanName() + "'"); } } } }protected ByteArrayOutputStream createTemporaryOutputStream() { return new ByteArrayOutputStream(OUTPUT_BYTE_ARRAY_INITIAL_SIZE); }為這個視圖創建一個臨時輸出流。這通常用作IE解決方案,用于在實際將內容寫入HTTP響應之前設置臨時流的內容長度標頭。
protected void writeToResponse(HttpServletResponse response, ByteArrayOutputStream baos) throws IOException { // Write content type and also length (determined via byte array). response.setContentType(getContentType()); response.setContentLength(baos.size()); // Flush byte array to servlet output stream. ServletOutputStream out = response.getOutputStream(); baos.writeTo(out); out.flush(); }將給定的臨時輸出流寫入HTTP響應。
protected void setResponseContentType(HttpServletRequest request, HttpServletResponse response) { MediaType mediaType = (MediaType) request.getAttribute(View.SELECTED_CONTENT_TYPE); if (mediaType != null && mediaType.isConcrete()) { response.setContentType(mediaType.toString()); } else { response.setContentType(getContentType()); } }設置響應到配置的內容類型的內容類型,除非視圖。出現SELECTED_CONTENT_TYPE請求屬性,并將其設置為具體的媒體類型。
org.springframework.web.servlet.view.AbstractUrlBasedView 基于url視圖的抽象基類。提供以“URL”bean屬性的形式保存視圖包裝的URL的一致方式。
private String url;url
@Override public void afterPropertiesSet() throws Exception { if (isUrlRequired() && getUrl() == null) { throw new IllegalArgumentException("Property 'url' is required"); } }校驗url
org.springframework.web.servlet.view.RedirectView 重定向到絕對URL、上下文相對URL或當前請求相對URL的視圖。URL可能是URI模板,在這種情況下,URI模板變量將被模型中可用的值替換。默認情況下,所有基本模型屬性(或其集合)都作為HTTP查詢參數公開(假設它們沒有用作URI模板變量),但是可以通過覆蓋isEligibleProperty(String, Object)方法來更改這種行為。這個視圖的URL應該是一個HTTP重定向URL,即適合HttpServletResponse的sendRedirect方法,如果HTTP 1.0標志是打開的,或者通過發送一個HTTP 303代碼(如果HTTP 1.0兼容標志是關閉的)來重定向。注意,雖然“contextRelative”標志的默認值為off,但您可能希望幾乎總是將其設置為true。當標志關閉時,以“/”開頭的url被認為是相對于web服務器根的,而當標志打開時,它們被認為是相對于web應用程序根的。由于大多數web應用程序永遠不會知道或關心它們的上下文路徑實際上是什么,因此最好將此標志設置為true,并提交相對于web應用程序根目錄的路徑。在Portlet環境中使用此重定向視圖時請注意:確保您的控制器遵守Portlet sendRedirect約束。
public void setExposePathVariables(boolean exposePathVariables) { this.exposePathVariables = exposePathVariables; }指定是否向模型中添加路徑變量。路徑變量通常通過@PathVariable注釋綁定到URI模板變量。它們實際上是URI模板變量,類型轉換應用于它們以派生類型化的對象值。視圖中經常需要這些值來構造指向相同url和其他url的鏈接。添加到模型中的路徑變量覆蓋靜態屬性(參見setAttributes(Properties)),但不覆蓋模型中已經存在的屬性。默認情況下,此標志設置為true。具體的視圖類型可以覆蓋它。
public void setContextRelative(boolean contextRelative) { this.contextRelative = contextRelative; }設置是否將以斜杠("/")開頭的給定URL解釋為相對于當前ServletContext,即相對于web應用程序根目錄的URL。默認值是“false”:以斜杠開頭的URL將被解釋為絕對的,即按原樣接受。如果“true”,在這種情況下,上下文路徑將在URL之前。
public void setHttp10Compatible(boolean http10Compatible) { this.http10Compatible = http10Compatible; }sendRedirect設置是否與HTTP 1.0客戶端保持兼容。在默認實現中,這將在任何情況下強制執行HTTP狀態碼302,即委托給HttpServletResponse.sendRedirect。關閉此選項將發送HTTP狀態代碼303,這是HTTP 1.1客戶端的正確代碼,但HTTP 1.0客戶端不能理解。許多HTTP 1.1客戶端對待302就像對待303一樣,沒有任何區別。但是,有些客戶端在POST請求后重定向時依賴于303;在這種情況下,關閉此標志。
public void setExposeModelAttributes(final boolean exposeModelAttributes) { this.exposeModelAttributes = exposeModelAttributes; }設置說明文屬性標志,它表示模型屬性是否應該作為HTTP查詢參數公開。默認值為true。
public void setExpandUriTemplateVariables(boolean expandUriTemplateVariables) { this.expandUriTemplateVariables = expandUriTemplateVariables; }是否將重定向URL視為URI模板。如果重定向URL包含左花括號“{”和右花括號“}”,并且不希望它們被解釋為URI變量,則將此標志設置為false。默認值為true。
public void setPropagateQueryParams(boolean propagateQueryParams) { this.propagateQueryParams = propagateQueryParams; }當設置為true時,將追加當前URL的查詢字符串,從而傳播到重定向的URL。默認值為false。
@Override public boolean isRedirectView() { return true; }返回“true”,指示此視圖執行重定向。
@Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws IOException {// 創建url String targetUrl = createTargetUrl(model, request);// 更新url targetUrl = updateTargetUrl(targetUrl, model, request, response); FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request); if (!CollectionUtils.isEmpty(flashMap)) { UriComponents uriComponents = UriComponentsBuilder.fromUriString(targetUrl).build(); flashMap.setTargetRequestPath(uriComponents.getPath()); flashMap.addTargetRequestParams(uriComponents.getQueryParams()); FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request); if (flashMapManager == null) { throw new IllegalStateException("FlashMapManager not found despite output FlashMap having been set"); } flashMapManager.saveOutputFlashMap(flashMap, request, response); }// 重定向 sendRedirect(request, response, targetUrl, this.http10Compatible); }將模型轉換為請求參數并重定向到給定的URL。
org.springframework.web.servlet.view.RedirectView#createTargetUrl 首先檢查重定向字符串是否是URI模板,然后使用給定的模型展開它,然后可選地添加簡單類型模型屬性作為查詢字符串參數,從而創建目標URL。
protected final String createTargetUrl(Map<String, Object> model, HttpServletRequest request) throws UnsupportedEncodingException { // Prepare target URL. StringBuilder targetUrl = new StringBuilder(); if (this.contextRelative && getUrl().startsWith("/")) { // Do not apply context path to relative URLs. targetUrl.append(getContextPath(request)); } targetUrl.append(getUrl()); String enc = this.encodingScheme; if (enc == null) { enc = request.getCharacterEncoding(); } if (enc == null) { enc = WebUtils.DEFAULT_CHARACTER_ENCODING; } if (this.expandUriTemplateVariables && StringUtils.hasText(targetUrl)) { Map<String, String> variables = getCurrentRequestUriVariables(request); targetUrl = replaceUriTemplateVariables(targetUrl.toString(), model, variables, enc); } if (isPropagateQueryProperties()) { appendCurrentQueryParams(targetUrl, request); } if (this.exposeModelAttributes) { appendQueryProperties(targetUrl, model, enc); } return targetUrl.toString(); }org.springframework.web.servlet.view.RedirectView#updateTargetUrl 找到注冊的RequestDataValueProcessor(如果有的話),并允許它更新重定向目標URL。
protected String updateTargetUrl(String targetUrl, Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) { WebApplicationContext wac = getWebApplicationContext(); if (wac == null) { wac = RequestContextUtils.findWebApplicationContext(request, getServletContext()); } if (wac != null && wac.containsBean(RequestContextUtils.REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME)) { RequestDataValueProcessor processor = wac.getBean( RequestContextUtils.REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME, RequestDataValueProcessor.class); return processor.processUrl(request, targetUrl); } return targetUrl; }org.springframework.web.servlet.view.RedirectView#sendRedirect 將重定向發送回HTTP客戶機
protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String targetUrl, boolean http10Compatible) throws IOException { String encodedURL = (isRemoteHost(targetUrl) ? targetUrl : response.encodeRedirectURL(targetUrl)); if (http10Compatible) { HttpStatus attributeStatusCode = (HttpStatus) request.getAttribute(View.RESPONSE_STATUS_ATTRIBUTE); if (this.statusCode != null) { response.setStatus(this.statusCode.value()); response.setHeader("Location", encodedURL); } else if (attributeStatusCode != null) { response.setStatus(attributeStatusCode.value()); response.setHeader("Location", encodedURL); } else { // Send status code 302 by default. 執行response.sendRedirect重定向 response.sendRedirect(encodedURL); } } else { HttpStatus statusCode = getHttp11StatusCode(request, response, targetUrl); response.setStatus(statusCode.value()); response.setHeader("Location", encodedURL); } }org.springframework.web.servlet.view.document.AbstractPdfStamperView 抽象超類,用于對具有AcroForm的現有文檔進行操作的PDF視圖。特定于應用程序的視圖類將擴展這個類以合并PDF表單和模型數據。這個視圖實現使用Bruno Lowagie的iText API。已知可以使用原始的iText 2.1.7及其分支OpenPDF。我們強烈推薦OpenPDF,因為它是積極維護的,并且修復了不可信PDF內容的一個重要漏洞。
public AbstractPdfStamperView(){ setContentType("application/pdf"); }創建AbstractPdfStamperView,設置contentType=application/pdf
@Override protected final void renderMergedOutputModel( Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { // IE workaround: write into byte array first.創建輸出流 ByteArrayOutputStream baos = createTemporaryOutputStream(); PdfReader reader = readPdfResource(); PdfStamper stamper = new PdfStamper(reader, baos);// 模板方法 mergePdfDocument(model, stamper, request, response); stamper.close(); // Flush to HTTP response. writeToResponse(response, baos); }渲染輸出model
org.springframework.web.servlet.view.AbstractView#createTemporaryOutputStream 為這個視圖創建一個臨時輸出流。這通常用作IE解決方案,用于在實際將內容寫入HTTP響應之前設置臨時流的內容長度標頭。
protected ByteArrayOutputStream createTemporaryOutputStream() { return new ByteArrayOutputStream(OUTPUT_BYTE_ARRAY_INITIAL_SIZE); }org.springframework.web.servlet.view.document.AbstractPdfStamperView#mergePdfDocument 子類必須實現此方法來將PDF表單與給定的模型數據合并。這是您可以在AcroForm上設置值的地方。在這一級可以做的一個例子是:請注意,傳入的HTTP響應只用于設置cookie或其他HTTP報頭。在此方法返回后,構建的PDF文檔本身將自動寫入響應。
protected abstract void mergePdfDocument(Map<String, Object> model, PdfStamper stamper, HttpServletRequest request, HttpServletResponse response) throws Exception;org.springframework.web.servlet.view.AbstractView#writeToResponse 將給定的臨時輸出流寫入HTTP響應。
protected void writeToResponse(HttpServletResponse response, ByteArrayOutputStream baos) throws IOException { // Write content type and also length (determined via byte array). response.setContentType(getContentType()); response.setContentLength(baos.size()); // Flush byte array to servlet output stream. ServletOutputStream out = response.getOutputStream(); baos.writeTo(out); out.flush(); }org.springframework.web.servlet.view.InternalResourceView 同一web應用程序中JSP或其他資源的包裝器。將模型對象公開為請求屬性,并使用RequestDispatcher將請求轉發到指定的資源URL。這個視圖的URL應該指定web應用程序中的一個資源,該資源適合RequestDispatcher的轉發或包含方法。
如果在已包含的請求或已提交的響應中操作,該視圖將退回到包含而不是轉發。這可以通過在呈現視圖之前調用response. flushbuffer()(它將提交響應)來實現。
public void setAlwaysInclude(boolean alwaysInclude) { this.alwaysInclude = alwaysInclude; }指定是否總是包含視圖而不是轉發視圖。默認設置是“假”。打開此標志以強制使用Servlet include,即使可能使用轉發。
public void setPreventDispatchLoop(boolean preventDispatchLoop) { this.preventDispatchLoop = preventDispatchLoop; }設置是否顯式防止分派回當前處理程序路徑。默認設置是“假”。對于基于約定的視圖,將其切換為“true”,其中將分派回當前處理程序路徑是一個確定的錯誤。
@Override protected void renderMergedOutputModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { // Expose the model object as request attributes.將模型對象公開為請求屬性。 exposeModelAsRequestAttributes(model, request); // Expose helpers as request attributes, if any.將幫助程序公開為請求屬性(如果有的話)。模板方法 exposeHelpers(request); // Determine the path for the request dispatcher.確定請求分配器的路徑。 String dispatcherPath = prepareForRendering(request, response); // Obtain a RequestDispatcher for the target resource (typically a JSP). 獲取請求轉發器 RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath); if (rd == null) { throw new ServletException("Could not get RequestDispatcher for [" + getUrl() + "]: Check that the corresponding file exists within your web application archive!"); } // If already included or response already committed, perform include, else forward. 如果include請求就執行,否則就轉發 if (useInclude(request, response)) { response.setContentType(getContentType()); if (logger.isDebugEnabled()) { logger.debug("Including resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'"); }// 執行include rd.include(request, response); } else { // Note: The forwarded resource is supposed to determine the content type itself.注意:轉發的資源應該確定內容類型本身。 if (logger.isDebugEnabled()) { logger.debug("Forwarding to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'"); }// 執行轉發 rd.forward(request, response); } }根據指定的模型呈現內部資源。這包括將模型設置為請求屬性。這里是模板方法實現,如果inlude請求執行include請求,如果是forward執行請求轉發
org.springframework.web.servlet.view.AbstractView#exposeModelAsRequestAttributes 將給定映射中的模型對象公開為請求屬性。名稱將取自模型映射。此方法適用于javax.servlet.RequestDispatcher可訪問的所有資源。
protected void exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request) throws Exception { for (Map.Entry<String, Object> entry : model.entrySet()) { String modelName = entry.getKey(); Object modelValue = entry.getValue(); if (modelValue != null) { request.setAttribute(modelName, modelValue); if (logger.isDebugEnabled()) { logger.debug("Added model object '" + modelName + "' of type [" + modelValue.getClass().getName() + "] to request in view with name '" + getBeanName() + "'"); } } else { request.removeAttribute(modelName); if (logger.isDebugEnabled()) { logger.debug("Removed model object '" + modelName + "' from request in view with name '" + getBeanName() + "'"); } } } }org.springframework.web.servlet.view.InternalResourceView#exposeHelpers 公開每個呈現操作唯一的助手。這是必要的,這樣不同的呈現操作就不會覆蓋彼此的上下文等等。由renderMergedOutputModel(Map, HttpServletRequest, HttpServletResponse)調用。默認實現為空。可以重寫此方法,以將自定義助手添加為請求屬性。
protected void exposeHelpers(HttpServletRequest request) throws Exception { }org.springframework.web.servlet.view.InternalResourceView#prepareForRendering 準備呈現,并確定轉發(或包含)的請求分派器路徑。此實現僅返回配置的URL。子類可以覆蓋它以確定要呈現的資源,通常以不同的方式解釋URL。
protected String prepareForRendering(HttpServletRequest request, HttpServletResponse response) throws Exception { String path = getUrl(); if (this.preventDispatchLoop) { String uri = request.getRequestURI(); if (path.startsWith("/") ? uri.equals(path) : uri.equals(StringUtils.applyRelativePath(uri, path))) { throw new ServletException("Circular view path [" + path + "]: would dispatch back " + "to the current handler URL [" + uri + "] again. Check your ViewResolver setup! " + "(Hint: This may be the result of an unspecified view, due to default view name generation.)"); } } return path; }org.springframework.web.servlet.view.InternalResourceView#getRequestDispatcher 獲取用于轉發/包含的RequestDispatcher。默認實現只是調用HttpServletRequest.getRequestDispatcher(字符串)。可以在子類中重寫。
protected RequestDispatcher getRequestDispatcher(HttpServletRequest request, String path) { return request.getRequestDispatcher(path); }protected boolean useInclude(HttpServletRequest request, HttpServletResponse response) { return (this.alwaysInclude || WebUtils.isIncludeRequest(request) || response.isCommitted()); }確定是使用RequestDispatcher的include方法還是轉發方法。執行檢查請求中是否找到包含URI屬性,指示包含請求,以及響應是否已經提交。在這兩種情況下,都將執行include,因為轉發不再可能。
org.springframework.web.util.WebUtils#isIncludeRequest 確定給定的請求是否是包含請求,即不是來自外部的頂級HTTP請求。檢查“javax.servlet.include”的存在。request_uri”請求屬性。可以檢查僅出現在包含請求中的任何請求屬性。
public static boolean isIncludeRequest(ServletRequest request) { return (request.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE) != null); }org.springframework.web.servlet.view.JstlView JSTL頁面的InternalResourceView的專門化,即使用JSP標準標記庫的JSP頁面。使用Spring的區域設置和MessageSource公開特定于JSTL的請求屬性,這些屬性指定JSTL的格式化和消息標記的區域設置和資源包。
org.springframework.web.servlet.view.AbstractTemplateView 用于基于模板的視圖技術(如Velocity和FreeMarker)的適配器基類,可以在模型中使用請求和會話屬性,還可以為Spring的Velocity/FreeMarker宏庫公開助手對象。JSP/JSTL和其他視圖技術自動訪問HttpServletRequest對象,從而訪問當前用戶的請求/會話屬性。此外,它們還能夠創建幫助對象并將其緩存為請求屬性本身。
public void setExposeRequestAttributes(boolean exposeRequestAttributes) { this.exposeRequestAttributes = exposeRequestAttributes; }設置是否應該在與模板合并之前將所有請求屬性添加到模型中。默認設置是“假”。
public void setAllowRequestOverride(boolean allowRequestOverride) { this.allowRequestOverride = allowRequestOverride; }設置是否允許HttpServletRequest屬性覆蓋(隱藏)控制器生成的同名模型屬性。默認值是“false”,如果發現與模型屬性同名的請求屬性,將引發異常。
public void setExposeSessionAttributes(boolean exposeSessionAttributes) { this.exposeSessionAttributes = exposeSessionAttributes; }設置是否應該在與模板合并之前將所有HttpSession屬性添加到模型中。默認設置是“假”
public void setAllowSessionOverride(boolean allowSessionOverride) { this.allowSessionOverride = allowSessionOverride; }設置是否允許HttpSession屬性覆蓋(隱藏)控制器生成的同名模型屬性。默認值是“false”,如果發現與模型屬性同名的會話屬性,將引發異常。
public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) { this.exposeSpringMacroHelpers = exposeSpringMacroHelpers; }設置是否以“springMacroRequestContext”的名稱公開一個RequestContext以供Spring的宏庫使用。默認設置是“真實的”。目前需要為Spring的Velocity和FreeMarker默認宏。注意,對于使用HTML表單的模板,這不是必需的,除非您希望利用Spring helper宏。
@Override protected final void renderMergedOutputModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { if (this.exposeRequestAttributes) { for (Enumeration<String> en = request.getAttributeNames(); en.hasMoreElements();) { String attribute = en.nextElement(); if (model.containsKey(attribute) && !this.allowRequestOverride) { throw new ServletException("Cannot expose request attribute '" + attribute + "' because of an existing model object of the same name"); } Object attributeValue = request.getAttribute(attribute); if (logger.isDebugEnabled()) { logger.debug("Exposing request attribute '" + attribute + "' with value [" + attributeValue + "] to model"); } model.put(attribute, attributeValue); } } if (this.exposeSessionAttributes) { HttpSession session = request.getSession(false); if (session != null) { for (Enumeration<String> en = session.getAttributeNames(); en.hasMoreElements();) { String attribute = en.nextElement(); if (model.containsKey(attribute) && !this.allowSessionOverride) { throw new ServletException("Cannot expose session attribute '" + attribute + "' because of an existing model object of the same name"); } Object attributeValue = session.getAttribute(attribute); if (logger.isDebugEnabled()) { logger.debug("Exposing session attribute '" + attribute + "' with value [" + attributeValue + "] to model"); } model.put(attribute, attributeValue); } } } if (this.exposeSpringMacroHelpers) { if (model.containsKey(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE)) { throw new ServletException( "Cannot expose bind macro helper '" + SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE + "' because of an existing model object of the same name"); } // Expose RequestContext instance for Spring macros. model.put(SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE, new RequestContext(request, response, getServletContext(), model)); } applyContentType(response);// 模板方法 renderMergedTemplateModel(model, request, response); }渲染輸出model,這里是模板方法實現,org.springframework.web.servlet.view.AbstractTemplateView#applyContentType 將“contentType”bean屬性中指定的視圖內容類型應用于給定的響應。只有在響應上沒有設置內容類型的情況下,才應用視圖的contentType。這允許處理程序預先覆蓋默認的內容類型。
protected void applyContentType(HttpServletResponse response) { if (response.getContentType() == null) { response.setContentType(getContentType()); } }org.springframework.web.servlet.view.AbstractTemplateView#renderMergedTemplateModel 子類必須實現這個方法來實際呈現視圖。
protected abstract void renderMergedTemplateModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception;org.springframework.web.servlet.view.freemarker.FreeMarkerView 使用FreeMarker模板引擎查看。
公開以下JavaBean屬性:url:要包裝的FreeMarker模板相對于FreeMarker模板上下文(目錄)的位置。編碼(可選,默認由FreeMarker配置決定):FreeMarker模板文件的編碼,依賴于一個單獨的FreeMarkerConfig對象,例如FreeMarkerConfigurer,可以在當前web應用程序上下文中使用任何bean名稱進行訪問。或者,您可以將FreeMarker配置對象設置為bean屬性。注意:Spring對FreeMarker的支持要求FreeMarker 2.3或更高。
private String encoding;encoding
@Override protected void initServletContext(ServletContext servletContext) throws BeansException { if (getConfiguration() != null) { this.taglibFactory = new TaglibFactory(servletContext); } else { FreeMarkerConfig config = autodetectConfiguration(); setConfiguration(config.getConfiguration()); this.taglibFactory = config.getTaglibFactory(); } GenericServlet servlet = new GenericServletAdapter(); try {// 初始化servlet servlet.init(new DelegatingServletConfig()); } catch (ServletException ex) { throw new BeanInitializationException("Initialization of GenericServlet adapter failed", ex); } this.servletContextHashModel = new ServletContextHashModel(servlet, getObjectWrapper()); }在啟動時調用。查找單個FreeMarkerConfig bean以查找此工廠的相關配置。檢查是否可以找到默認語言環境的模板:如果沒有找到特定于語言環境的模板,FreeMarker將檢查非特定于語言環境的模板。
@Override protected void renderMergedTemplateModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { exposeHelpers(model, request); doRender(model, request, response); }通過將模型映射與FreeMarker模板合并來處理它。輸出被定向到servlet響應。如果需要自定義行為,可以重寫此方法。
@Override protected void renderMergedTemplateModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { exposeHelpers(model, request);// 渲染模型 doRender(model, request, response); }org.springframework.web.servlet.view.freemarker.FreeMarkerView#exposeHelpers 公開每個呈現操作唯一的助手。這是必要的,以便不同的呈現操作不會覆蓋彼此的格式等。叫renderMergedTemplateModel。默認實現為空。可以重寫此方法以向模型中添加自定義助手。
protected void exposeHelpers(Map<String, Object> model, HttpServletRequest request) throws Exception { }org.springframework.web.servlet.view.freemarker.FreeMarkerView#doRender 使用包含要使用的完整模板模型的給定模型映射,將FreeMarker視圖呈現給給定的響應。默認實現呈現由“url”bean屬性指定的模板,該屬性通過getTemplate檢索。它委托processTemplate方法將模板實例與給定的模板模型合并。將標準的Freemarker散列模型添加到模型中:請求參數、請求、會話和應用程序(ServletContext),以及JSP標記庫散列模型。可以重寫以自定義行為,例如將多個模板呈現到單個視圖中。
protected void doRender(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { // Expose model to JSP tags (as request attributes). 解析請求參數 exposeModelAsRequestAttributes(model, request); // Expose all standard FreeMarker hash models. 構建模板模型 SimpleHash fmModel = buildTemplateModel(model, request, response); if (logger.isDebugEnabled()) { logger.debug("Rendering FreeMarker template [" + getUrl() + "] in FreeMarkerView '" + getBeanName() + "'"); } // Grab the locale-specific version of the template. Locale locale = RequestContextUtils.getLocale(request);// 處理模板 processTemplate(getTemplate(locale), fmModel, response); }org.springframework.web.servlet.view.json.AbstractJackson2View 抽象基類,用于基于Jackson和內容類型獨立的AbstractView實現。
private ObjectMapper objectMapper;objectMapper
@Override protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) { setResponseContentType(request, response); response.setCharacterEncoding(this.encoding.getJavaName()); if (this.disableCaching) { response.addHeader("Cache-Control", "no-store"); } }設置響應contentType、緩存相關header
@Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { OutputStream stream = (this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream()); Object value = filterAndWrapModel(model, request); writeContent(stream, value); if (this.updateContentLength) { writeToResponse(response, (ByteArrayOutputStream) stream); } }渲染輸出model
org.springframework.web.servlet.view.xml.MappingJackson2XmlView Spring MVC視圖,通過使用Jackson 2的XmlMapper序列化當前請求的模型來呈現XML內容。要序列化的對象作為模型中的參數提供。使用第一個可序列化條目。用戶可以通過sourceKey屬性在模型中指定一個特定的條目。默認構造函數使用Jackson2ObjectMapperBuilder提供的默認配置。
public static final String DEFAULT_CONTENT_TYPE = "application/xml";默認contentType
@Override protected Object filterModel(Map model) { Object value = null; if (this.modelKey != null) { value = model.get(this.modelKey); if (value == null) { throw new IllegalStateException( "Model contains no object with key [" + this.modelKey + "]"); } } else { for (Map.Entry entry : model.entrySet()) { if (!(entry.getValue() instanceof BindingResult) && !entry.getKey().equals(JsonView.class.getName())) { if (value != null) { throw new IllegalStateException("Model contains more than one object to render, only one is supported"); } value = entry.getValue(); } } } return value; }解析json model
org.springframework.web.servlet.view.json.MappingJackson2JsonView Spring MVC視圖,通過使用Jackson 2的ObjectMapper序列化當前請求的模型來呈現JSON內容。默認情況下,模型映射的整個內容(框架特定類除外)將被編碼為JSON。如果模型只包含一個鍵,您可以通過setExtractValueFromSingleKeyModel將其提取編碼為JSON。默認構造函數使用Jackson2ObjectMapperBuilder提供的默認配置。
public static final String DEFAULT_CONTENT_TYPE = "application/json";默認內容類型:“application/json”。通過setContentType重寫的。
public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel) { this.extractValueFromSingleKeyModel = extractValueFromSingleKeyModel; }設置是將包含單個屬性的模型序列化為映射,還是從模型中提取單個值并直接序列化它。設置此標志的效果類似于使用帶有@ResponseBody請求處理方法的MappingJackson2HttpMessageConverter。默認的是假的
org.springframework.web.servlet.view.xml.MarshallingView 允許響應上下文作為編組器編組的結果呈現的Spring-MVC視圖。將編組的對象作為模型中的參數提供,然后在響應呈現期間檢測。用戶可以通過sourceKey屬性在模型中指定一個特定的條目,或者讓Spring定位源對象。
public static final String DEFAULT_CONTENT_TYPE = "application/xml";默認contentType
private Marshaller marshaller;marshaller
@Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { Object toBeMarshalled = locateToBeMarshalled(model); if (toBeMarshalled == null) { throw new IllegalStateException("Unable to locate object to be marshalled in model: " + model); } ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); this.marshaller.marshal(toBeMarshalled, new StreamResult(baos)); setResponseContentType(request, response); response.setContentLength(baos.size()); baos.writeTo(response.getOutputStream()); }渲染輸出model
org.springframework.web.servlet.view.document.AbstractXlsView 方便的超類,用于傳統XLS格式的Excel文檔視圖。兼容Apache POI 3.5及更高版本。
public AbstractXlsView() { setContentType("application/vnd.ms-excel"); }設置contentType=application/vnd.ms-excel
@Override protected final void renderMergedOutputModel( Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { // Create a fresh workbook instance for this render step. Workbook workbook = createWorkbook(model, request); // Delegate to application-provided document code.模板方法 buildExcelDocument(model, workbook, request, response); // Set the content type. response.setContentType(getContentType()); // Flush byte array to servlet output stream. renderWorkbook(workbook, response); }渲染視圖model,這里是模板方法實現,org.springframework.web.servlet.view.document.AbstractXlsView#buildExcelDocument 給定模型,應用程序提供的子類必須實現此方法來填充Excel工作簿文檔。
protected abstract void buildExcelDocument( Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception;org.springframework.web.servlet.view.document.AbstractXlsxView Office 2007 XLSX格式(由POI-OOXML支持)中Excel文檔視圖的方便超類。兼容Apache POI 3.5及更高版本。
public AbstractXlsxView() { setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); }設置contentType=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
org.springframework.web.servlet.view.document.AbstractXlsxStreamingView ?Office 2007 XLSX格式的Excel文檔視圖,使用POI的流媒體變體,方便的超類。兼容Apache POI 3.9及更高版本。
org.springframework.web.servlet.view.document.AbstractPdfView PDF視圖的抽象超類。特定于應用程序的視圖類將擴展這個類。視圖將保存在子類本身中,而不是在模板中。這個視圖實現使用Bruno Lowagie的iText API。已知可以使用原始的iText 2.1.7及其分支OpenPDF。我們強烈推薦OpenPDF,因為它是積極維護的,并且修復了不可信PDF內容的一個重要漏洞。注:Internet Explorer需要一個"。擴展,因為它并不總是尊重聲明的內容類型。
public AbstractPdfView() { setContentType("application/pdf"); }此構造函數設置適當的內容類型“application/pdf”。請注意,IE不會注意到這一點,但我們對此無能為力。生成的文檔應該有一個“”。pdf”擴展。
@Override protected final void renderMergedOutputModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { // IE workaround: write into byte array first.IE工作區:寫入字節數組第一。 ByteArrayOutputStream baos = createTemporaryOutputStream(); // Apply preferences and build metadata. Document document = newDocument(); PdfWriter writer = newWriter(document, baos); prepareWriter(model, writer, request);// 模板方法 buildPdfMetadata(model, document, request); // Build PDF document. document.open();// 模板方法 buildPdfDocument(model, document, writer, request, response); document.close(); // Flush to HTTP response. writeToResponse(response, baos); }渲染輸出model,這里是模板方法實現。org.springframework.web.servlet.view.document.AbstractPdfView#buildPdfMetadata 填充iText文檔的元字段(作者、標題等)。默認值是一個空實現。子類可以重寫此方法來添加元字段,如標題、主題、作者、創建者、關鍵字等。此方法在將PdfWriter分配給文檔后調用,并在調用Document .open()之前調用。
protected void buildPdfMetadata(Map<String, Object> model, Document document, HttpServletRequest request) { }org.springframework.web.servlet.view.document.AbstractPdfView#buildPdfDocument 子類必須實現此方法來構建給定模型的iText PDF文檔。在Document.open()和Document.close()調用之間調用。請注意,傳入的HTTP響應只用于設置cookie或其他HTTP報頭。在此方法返回后,構建的PDF文檔本身將自動寫入響應。
protected abstract void buildPdfDocument(Map<String, Object> model, Document document, PdfWriter writer, HttpServletRequest request, HttpServletResponse response) throws Exception;org.springframework.web.servlet.view.AbstractView#writeToResponse 將給定的臨時輸出流寫入HTTP響應。
protected void writeToResponse(HttpServletResponse response, ByteArrayOutputStream baos) throws IOException { // Write content type and also length (determined via byte array). response.setContentType(getContentType()); response.setContentLength(baos.size()); // Flush byte array to servlet output stream. ServletOutputStream out = response.getOutputStream(); baos.writeTo(out); out.flush(); }說在最后
本次解析僅代表個人觀點,僅供參考。
掃碼進入技術微信群
釘釘技術群qq技術群
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的yolov3之pytorch源码解析_springmvc源码架构解析之view的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一粒红尘13、14集 叶昭觉对简晨烨失望
- 下一篇: 装修砸墙多少钱啊?