001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.servlet.view; 018 019import javax.servlet.http.HttpServletRequest; 020 021import org.springframework.lang.Nullable; 022import org.springframework.util.Assert; 023import org.springframework.util.StringUtils; 024import org.springframework.web.servlet.HandlerMapping; 025import org.springframework.web.servlet.RequestToViewNameTranslator; 026import org.springframework.web.util.UrlPathHelper; 027 028/** 029 * {@link RequestToViewNameTranslator} that simply transforms the URI of 030 * the incoming request into a view name. 031 * 032 * <p>Can be explicitly defined as the {@code viewNameTranslator} bean in a 033 * {@link org.springframework.web.servlet.DispatcherServlet} context. 034 * Otherwise, a plain default instance will be used. 035 * 036 * <p>The default transformation simply strips leading and trailing slashes 037 * as well as the file extension of the URI, and returns the result as the 038 * view name with the configured {@link #setPrefix prefix} and a 039 * {@link #setSuffix suffix} added as appropriate. 040 * 041 * <p>The stripping of the leading slash and file extension can be disabled 042 * using the {@link #setStripLeadingSlash stripLeadingSlash} and 043 * {@link #setStripExtension stripExtension} properties, respectively. 044 * 045 * <p>Find below some examples of request to view name translation. 046 * <ul> 047 * <li>{@code http://localhost:8080/gamecast/display.html} » {@code display}</li> 048 * <li>{@code http://localhost:8080/gamecast/displayShoppingCart.html} » {@code displayShoppingCart}</li> 049 * <li>{@code http://localhost:8080/gamecast/admin/index.html} » {@code admin/index}</li> 050 * </ul> 051 * 052 * @author Rob Harrop 053 * @author Juergen Hoeller 054 * @since 2.0 055 * @see org.springframework.web.servlet.RequestToViewNameTranslator 056 * @see org.springframework.web.servlet.ViewResolver 057 */ 058public class DefaultRequestToViewNameTranslator implements RequestToViewNameTranslator { 059 060 private static final String SLASH = "/"; 061 062 063 private String prefix = ""; 064 065 private String suffix = ""; 066 067 private String separator = SLASH; 068 069 private boolean stripLeadingSlash = true; 070 071 private boolean stripTrailingSlash = true; 072 073 private boolean stripExtension = true; 074 075 private UrlPathHelper urlPathHelper = new UrlPathHelper(); 076 077 078 /** 079 * Set the prefix to prepend to generated view names. 080 * @param prefix the prefix to prepend to generated view names 081 */ 082 public void setPrefix(@Nullable String prefix) { 083 this.prefix = (prefix != null ? prefix : ""); 084 } 085 086 /** 087 * Set the suffix to append to generated view names. 088 * @param suffix the suffix to append to generated view names 089 */ 090 public void setSuffix(@Nullable String suffix) { 091 this.suffix = (suffix != null ? suffix : ""); 092 } 093 094 /** 095 * Set the value that will replace '{@code /}' as the separator 096 * in the view name. The default behavior simply leaves '{@code /}' 097 * as the separator. 098 */ 099 public void setSeparator(String separator) { 100 this.separator = separator; 101 } 102 103 /** 104 * Set whether or not leading slashes should be stripped from the URI when 105 * generating the view name. Default is "true". 106 */ 107 public void setStripLeadingSlash(boolean stripLeadingSlash) { 108 this.stripLeadingSlash = stripLeadingSlash; 109 } 110 111 /** 112 * Set whether or not trailing slashes should be stripped from the URI when 113 * generating the view name. Default is "true". 114 */ 115 public void setStripTrailingSlash(boolean stripTrailingSlash) { 116 this.stripTrailingSlash = stripTrailingSlash; 117 } 118 119 /** 120 * Set whether or not file extensions should be stripped from the URI when 121 * generating the view name. Default is "true". 122 */ 123 public void setStripExtension(boolean stripExtension) { 124 this.stripExtension = stripExtension; 125 } 126 127 /** 128 * Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}. 129 * @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath 130 */ 131 public void setAlwaysUseFullPath(boolean alwaysUseFullPath) { 132 this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath); 133 } 134 135 /** 136 * Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}. 137 * @see org.springframework.web.util.UrlPathHelper#setUrlDecode 138 */ 139 public void setUrlDecode(boolean urlDecode) { 140 this.urlPathHelper.setUrlDecode(urlDecode); 141 } 142 143 /** 144 * Set if ";" (semicolon) content should be stripped from the request URI. 145 * @see org.springframework.web.util.UrlPathHelper#setRemoveSemicolonContent(boolean) 146 */ 147 public void setRemoveSemicolonContent(boolean removeSemicolonContent) { 148 this.urlPathHelper.setRemoveSemicolonContent(removeSemicolonContent); 149 } 150 151 /** 152 * Set the {@link org.springframework.web.util.UrlPathHelper} to use for 153 * the resolution of lookup paths. 154 * <p>Use this to override the default UrlPathHelper with a custom subclass, 155 * or to share common UrlPathHelper settings across multiple web components. 156 */ 157 public void setUrlPathHelper(UrlPathHelper urlPathHelper) { 158 Assert.notNull(urlPathHelper, "UrlPathHelper must not be null"); 159 this.urlPathHelper = urlPathHelper; 160 } 161 162 163 /** 164 * Translates the request URI of the incoming {@link HttpServletRequest} 165 * into the view name based on the configured parameters. 166 * @see org.springframework.web.util.UrlPathHelper#getLookupPathForRequest 167 * @see #transformPath 168 */ 169 @Override 170 public String getViewName(HttpServletRequest request) { 171 String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, HandlerMapping.LOOKUP_PATH); 172 return (this.prefix + transformPath(lookupPath) + this.suffix); 173 } 174 175 /** 176 * Transform the request URI (in the context of the webapp) stripping 177 * slashes and extensions, and replacing the separator as required. 178 * @param lookupPath the lookup path for the current request, 179 * as determined by the UrlPathHelper 180 * @return the transformed path, with slashes and extensions stripped 181 * if desired 182 */ 183 @Nullable 184 protected String transformPath(String lookupPath) { 185 String path = lookupPath; 186 if (this.stripLeadingSlash && path.startsWith(SLASH)) { 187 path = path.substring(1); 188 } 189 if (this.stripTrailingSlash && path.endsWith(SLASH)) { 190 path = path.substring(0, path.length() - 1); 191 } 192 if (this.stripExtension) { 193 path = StringUtils.stripFilenameExtension(path); 194 } 195 if (!SLASH.equals(this.separator)) { 196 path = StringUtils.replace(path, SLASH, this.separator); 197 } 198 return path; 199 } 200 201}