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