RequestToViewNameTranslator可以在处理器返回的View为空时使用它根据Request获取viewName。RequestToViewNameTranslator提供的实现类只有一个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; }
其实现类DefaultRequestToViewNameTranslator中的实现如下:其实其简单实现就是将请求名称作为视图名称返回,逻辑还是比较简单的。
@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); }
实现类DefaultViewNameTranslator的完整源码如下:
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; } }