RequestToViewNameTranslator可以在處理器返回的View為空時使用它根據Request獲得viewName。RequestToViewNameTranslator提供的實現類只有1個DefaultRequestToViewNameTranslator。
接口RequestToViewNameTranslator中定義的以下:提供了getViewName抽象方法,其實就是根據request要求獲得來組裝視圖名稱。
public interface RequestToViewNameTranslator { /** * Translate the given {@link HttpServletRequest} into a view name. * @param request the incoming {@link HttpServletRequest} providing * the context from which a view name is to be resolved * @return the view name (or {@code null} if no default found) * @throws Exception if view name translation fails */ String getViewName(HttpServletRequest request) throws Exception; }
@Override public String getViewName(HttpServletRequest request) { String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); return (this.prefix + transformPath(lookupPath) + this.suffix); }接下來我們看看RequestToViewNameTranslator在springMVC中的具體運行流程:
首先在DispatcherServlet的doDispatch函數中會設置默許的視圖名
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { ...... //設置默許的視圖名稱 applyDefaultViewName(processedRequest, mv); ...... }在applyDefaultViewName中會判斷ModelAndView的hasView為空時,就設置viewName
private void applyDefaultViewName(HttpServletRequest request, ModelAndView mv) throws Exception { if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } }
getDefaultViewName的實現邏輯還是在ViewNameTranslator中。
protected String getDefaultViewName(HttpServletRequest request) throws Exception { return this.viewNameTranslator.getViewName(request); }在DefaultViewNameTranslator中實現的getViewName的邏輯以下,其實就是將要求路徑作為ViewName
@Override public String getViewName(HttpServletRequest request) { String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); return (this.prefix + transformPath(lookupPath) + this.suffix); }
public class DefaultRequestToViewNameTranslator implements RequestToViewNameTranslator { private static final String SLASH = "/"; private String prefix = ""; private String suffix = ""; private String separator = SLASH; private boolean stripLeadingSlash = true; private boolean stripTrailingSlash = true; private boolean stripExtension = true; private UrlPathHelper urlPathHelper = new UrlPathHelper(); public void setPrefix(String prefix) { this.prefix = (prefix != null ? prefix : ""); } public void setSuffix(String suffix) { this.suffix = (suffix != null ? suffix : ""); } public void setSeparator(String separator) { this.separator = separator; } public void setStripLeadingSlash(boolean stripLeadingSlash) { this.stripLeadingSlash = stripLeadingSlash; } public void setStripTrailingSlash(boolean stripTrailingSlash) { this.stripTrailingSlash = stripTrailingSlash; } public void setStripExtension(boolean stripExtension) { this.stripExtension = stripExtension; } public void setAlwaysUseFullPath(boolean alwaysUseFullPath) { this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath); } public void setUrlDecode(boolean urlDecode) { this.urlPathHelper.setUrlDecode(urlDecode); } public void setRemoveSemicolonContent(boolean removeSemicolonContent) { this.urlPathHelper.setRemoveSemicolonContent(removeSemicolonContent); } public void setUrlPathHelper(UrlPathHelper urlPathHelper) { Assert.notNull(urlPathHelper, "UrlPathHelper must not be null"); this.urlPathHelper = urlPathHelper; } //根據要求獲得視圖名稱 @Override public String getViewName(HttpServletRequest request) { String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); return (this.prefix + transformPath(lookupPath) + this.suffix); } protected String transformPath(String lookupPath) { String path = lookupPath; if (this.stripLeadingSlash && path.startsWith(SLASH)) { path = path.substring(1); } if (this.stripTrailingSlash && path.endsWith(SLASH)) { path = path.substring(0, path.length() - 1); } if (this.stripExtension) { path = StringUtils.stripFilenameExtension(path); } if (!SLASH.equals(this.separator)) { path = StringUtils.replace(path, SLASH, this.separator); } return path; } }