Here are the examples of the java api org.springframework.util.PathMatcher taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
203 Examples
19
View Source File : SysBaseApiImpl.java
License : Apache License 2.0
Project Creator : zhangdaiscott
License : Apache License 2.0
Project Creator : zhangdaiscott
/**
* 匹配前端传过来的地址 匹配成功返回正则地址
* AntPathMatcher匹配地址
* ()* 匹配0个或多个字符
* ()**匹配0个或多个目录
*/
private String getRegexpUrl(String url) {
List<String> list = sysPermissionMapper.queryPermissionUrlWithStar();
if (list != null && list.size() > 0) {
for (String p : list) {
PathMatcher matcher = new AntPathMatcher();
if (matcher.match(p, url)) {
return p;
}
}
}
return null;
}
19
View Source File : WebConfiguration.java
License : MIT License
Project Creator : YunaiV
License : MIT License
Project Creator : YunaiV
/**
* 创建 XssFilter Bean,解决 Xss 安全问题
*/
@Bean
public FilterRegistrationBean<XssFilter> xssFilter(XssProperties properties, PathMatcher pathMatcher) {
return createFilterBean(new XssFilter(properties, pathMatcher), FilterOrderEnum.XSS_FILTER);
}
19
View Source File : ClassLoaderFilesResourcePatternResolver.java
License : Apache License 2.0
Project Creator : yuanmabiji
License : Apache License 2.0
Project Creator : yuanmabiji
/**
* A {@code ResourcePatternResolver} that considers {@link ClreplacedLoaderFiles} when
* resolving resources.
*
* @author Andy Wilkinson
* @author Phillip Webb
* @author Stephane Nicoll
*/
final clreplaced ClreplacedLoaderFilesResourcePatternResolver implements ResourcePatternResolver {
private static final String[] LOCATION_PATTERN_PREFIXES = { CLreplacedPATH_ALL_URL_PREFIX, CLreplacedPATH_URL_PREFIX };
private static final String WEB_CONTEXT_CLreplaced = "org.springframework.web.context." + "WebApplicationContext";
private final ResourcePatternResolver patternResolverDelegate;
private final PathMatcher antPathMatcher = new AntPathMatcher();
private final ClreplacedLoaderFiles clreplacedLoaderFiles;
ClreplacedLoaderFilesResourcePatternResolver(ApplicationContext applicationContext, ClreplacedLoaderFiles clreplacedLoaderFiles) {
this.clreplacedLoaderFiles = clreplacedLoaderFiles;
this.patternResolverDelegate = getResourcePatternResolverFactory().getResourcePatternResolver(applicationContext, retrieveResourceLoader(applicationContext));
}
private ResourceLoader retrieveResourceLoader(ApplicationContext applicationContext) {
Field field = ReflectionUtils.findField(applicationContext.getClreplaced(), "resourceLoader", ResourceLoader.clreplaced);
if (field == null) {
return null;
}
ReflectionUtils.makeAccessible(field);
return (ResourceLoader) ReflectionUtils.getField(field, applicationContext);
}
private ResourcePatternResolverFactory getResourcePatternResolverFactory() {
if (ClreplacedUtils.isPresent(WEB_CONTEXT_CLreplaced, null)) {
return new WebResourcePatternResolverFactory();
}
return new ResourcePatternResolverFactory();
}
@Override
public ClreplacedLoader getClreplacedLoader() {
return this.patternResolverDelegate.getClreplacedLoader();
}
@Override
public Resource getResource(String location) {
Resource candidate = this.patternResolverDelegate.getResource(location);
if (isDeleted(candidate)) {
return new DeletedClreplacedLoaderFileResource(location);
}
return candidate;
}
@Override
public Resource[] getResources(String locationPattern) throws IOException {
List<Resource> resources = new ArrayList<>();
Resource[] candidates = this.patternResolverDelegate.getResources(locationPattern);
for (Resource candidate : candidates) {
if (!isDeleted(candidate)) {
resources.add(candidate);
}
}
resources.addAll(getAdditionalResources(locationPattern));
return resources.toArray(new Resource[0]);
}
private List<Resource> getAdditionalResources(String locationPattern) throws MalformedURLException {
List<Resource> additionalResources = new ArrayList<>();
String trimmedLocationPattern = trimLocationPattern(locationPattern);
for (SourceFolder sourceFolder : this.clreplacedLoaderFiles.getSourceFolders()) {
for (Entry<String, ClreplacedLoaderFile> entry : sourceFolder.getFilesEntrySet()) {
String name = entry.getKey();
ClreplacedLoaderFile file = entry.getValue();
if (file.getKind() != Kind.DELETED && this.antPathMatcher.match(trimmedLocationPattern, name)) {
URL url = new URL("reloaded", null, -1, "/" + name, new ClreplacedLoaderFileURLStreamHandler(file));
UrlResource resource = new UrlResource(url);
additionalResources.add(resource);
}
}
}
return additionalResources;
}
private String trimLocationPattern(String pattern) {
for (String prefix : LOCATION_PATTERN_PREFIXES) {
if (pattern.startsWith(prefix)) {
return pattern.substring(prefix.length());
}
}
return pattern;
}
private boolean isDeleted(Resource resource) {
for (SourceFolder sourceFolder : this.clreplacedLoaderFiles.getSourceFolders()) {
for (Entry<String, ClreplacedLoaderFile> entry : sourceFolder.getFilesEntrySet()) {
try {
String name = entry.getKey();
ClreplacedLoaderFile file = entry.getValue();
if (file.getKind() == Kind.DELETED && resource.exists() && resource.getURI().toString().endsWith(name)) {
return true;
}
} catch (IOException ex) {
throw new IllegalStateException("Failed to retrieve URI from '" + resource + "'", ex);
}
}
}
return false;
}
/**
* A {@link Resource} that represents a {@link ClreplacedLoaderFile} that has been
* {@link Kind#DELETED deleted}.
*/
static final clreplaced DeletedClreplacedLoaderFileResource extends AbstractResource {
private final String name;
private DeletedClreplacedLoaderFileResource(String name) {
this.name = name;
}
@Override
public boolean exists() {
return false;
}
@Override
public String getDescription() {
return "Deleted: " + this.name;
}
@Override
public InputStream getInputStream() throws IOException {
throw new IOException(this.name + " has been deleted");
}
}
/**
* Factory used to create the {@link ResourcePatternResolver} delegate.
*/
private static clreplaced ResourcePatternResolverFactory {
public ResourcePatternResolver getResourcePatternResolver(ApplicationContext applicationContext, ResourceLoader resourceLoader) {
if (resourceLoader == null) {
resourceLoader = new DefaultResourceLoader();
copyProtocolResolvers(applicationContext, resourceLoader);
}
return new PathMatchingResourcePatternResolver(resourceLoader);
}
protected final void copyProtocolResolvers(ApplicationContext applicationContext, ResourceLoader resourceLoader) {
if (applicationContext instanceof DefaultResourceLoader && resourceLoader instanceof DefaultResourceLoader) {
copyProtocolResolvers((DefaultResourceLoader) applicationContext, (DefaultResourceLoader) resourceLoader);
}
}
protected final void copyProtocolResolvers(DefaultResourceLoader source, DefaultResourceLoader destination) {
for (ProtocolResolver resolver : source.getProtocolResolvers()) {
destination.addProtocolResolver(resolver);
}
}
}
/**
* {@link ResourcePatternResolverFactory} to be used when the clreplacedloader can access
* {@link WebApplicationContext}.
*/
private static clreplaced WebResourcePatternResolverFactory extends ResourcePatternResolverFactory {
@Override
public ResourcePatternResolver getResourcePatternResolver(ApplicationContext applicationContext, ResourceLoader resourceLoader) {
if (applicationContext instanceof WebApplicationContext) {
return getResourcePatternResolver((WebApplicationContext) applicationContext, resourceLoader);
}
return super.getResourcePatternResolver(applicationContext, resourceLoader);
}
private ResourcePatternResolver getResourcePatternResolver(WebApplicationContext applicationContext, ResourceLoader resourceLoader) {
if (resourceLoader == null) {
resourceLoader = new WebApplicationContextResourceLoader(applicationContext);
copyProtocolResolvers(applicationContext, resourceLoader);
}
return new ServletContextResourcePatternResolver(resourceLoader);
}
}
/**
* {@link ResourceLoader} that optionally supports {@link ServletContextResource
* ServletContextResources}.
*/
private static clreplaced WebApplicationContextResourceLoader extends DefaultResourceLoader {
private final WebApplicationContext applicationContext;
WebApplicationContextResourceLoader(WebApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
protected Resource getResourceByPath(String path) {
if (this.applicationContext.getServletContext() != null) {
return new ServletContextResource(this.applicationContext.getServletContext(), path);
}
return super.getResourceByPath(path);
}
}
}
19
View Source File : WebContext.java
License : MIT License
Project Creator : yizzuide
License : MIT License
Project Creator : yizzuide
/**
* WebContext
*
* @author yizzuide
* @since 1.14.0
* @version 3.0.0
* Create at 2019/11/11 21:38
*/
public clreplaced WebContext {
/**
* 路径匹配器
*/
private static PathMatcher mvcPathMatcher;
/**
* URL路径帮助类
*/
private static UrlPathHelper urlPathHelper;
public static void setMvcPathMatcher(PathMatcher mvcPathMatcher) {
WebContext.mvcPathMatcher = mvcPathMatcher;
}
/**
* 路径匹配器
* @return PathMatcher
*/
public static PathMatcher getMvcPathMatcher() {
return mvcPathMatcher;
}
public static void setUrlPathHelper(UrlPathHelper urlPathHelper) {
WebContext.urlPathHelper = urlPathHelper;
}
/**
* 请求路径帮助类
* @return UrlPathHelper
*/
public static UrlPathHelper getUrlPathHelper() {
return urlPathHelper;
}
/**
* 获取请求信息
* @return ServletRequestAttributes
*/
public static ServletRequestAttributes getRequestAttributes() {
return (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
}
/**
* 获得请求对象
* @return HttpServletRequest
*/
public static HttpServletRequest getRequest() {
return getRequestAttributes().getRequest();
}
/**
* 获取响应对象
* @return HttpServletResponse
*/
public static HttpServletResponse getResponse() {
return getRequestAttributes().getResponse();
}
/**
* 获取当前会话
* @return HttpSession
*/
public static HttpSession getSession() {
return getRequest().getSession();
}
/**
* 动态注册并返回bean
* @param applicationContext 应用上下文
* @param name bean name
* @param clazz bean clreplaced
* @param args 构造参数
* @param <T> 实体类型
* @return Bean
*/
public static <T> T registerBean(ConfigurableApplicationContext applicationContext, String name, Clreplaced<T> clazz, Object... args) {
if (applicationContext.containsBean(name)) {
return applicationContext.getBean(name, clazz);
}
BeanDefinition beanDefinition = build(clazz, args);
return registerBean(applicationContext, name, clazz, beanDefinition);
}
/**
* 构建BeanDefinition
* @param clazz bean类
* @param args 构造参数
* @return BeanDefinition
*/
public static BeanDefinition build(Clreplaced<?> clazz, Object... args) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
for (Object arg : args) {
beanDefinitionBuilder.addConstructorArgValue(arg);
}
return beanDefinitionBuilder.getRawBeanDefinition();
}
/**
* 注册BeanDefinition
* @param applicationContext 应用上下文
* @param name bean name
* @param clazz bean clreplaced
* @param beanDefinition BeanDefinition
* @param <T> 实体类型
* @return Bean
*/
public static <T> T registerBean(ConfigurableApplicationContext applicationContext, String name, Clreplaced<T> clazz, BeanDefinition beanDefinition) {
BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) applicationContext.getBeanFactory();
beanFactory.registerBeanDefinition(name, beanDefinition);
return applicationContext.getBean(name, clazz);
}
}
19
View Source File : WebContext.java
License : MIT License
Project Creator : yizzuide
License : MIT License
Project Creator : yizzuide
public static void setMvcPathMatcher(PathMatcher mvcPathMatcher) {
WebContext.mvcPathMatcher = mvcPathMatcher;
}
19
View Source File : MilkomedaContextConfig.java
License : MIT License
Project Creator : yizzuide
License : MIT License
Project Creator : yizzuide
@Autowired
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public void config(PathMatcher mvcPathMatcher, UrlPathHelper mvcUrlPathHelper) {
WebContext.setMvcPathMatcher(mvcPathMatcher);
WebContext.setUrlPathHelper(mvcUrlPathHelper);
}
19
View Source File : UrlPatternManager.java
License : MIT License
Project Creator : yangziwen
License : MIT License
Project Creator : yangziwen
@Slf4j
public clreplaced UrlPatternManager {
private static final String PATTERN_UNKNOWN = "unknown";
private static final PathMatcher URL_PATH_MATCHER = new MultiPathMatcher();
// 不包含模糊匹配模式的url
private static Set<String> simpleUrlPatterns = Collections.emptySet();
// 第一节路径中包含模糊匹配模式的url
private static Set<String> complicatedUrlPatterns = Collections.emptySet();
// 第一节路径中不包含模块匹配模式,但后续路径中包括模糊匹配模式的url
private static Multimap<String, String> prefixKeyedUrlMap = ImmutableSetMultimap.of();
static {
MonitorService.reloadUrlPatterns();
log.info("loaded {} url patterns", UrlPatternManager.getLoadedUrlPatternCount());
}
private UrlPatternManager() {
}
public static void reloadUrlPatterns(Collection<String> urlPatterns) {
Multimap<String, String> prefixKeyedUrlMap = HashMultimap.create();
Set<String> simpleUrlPatterns = new HashSet<>();
Set<String> complicatedUrlPatterns = new HashSet<>();
for (String pattern : urlPatterns) {
if (!pattern.contains("*") && !pattern.contains("{")) {
simpleUrlPatterns.add(pattern);
continue;
}
String[] array = StringUtils.split(pattern, "/");
String prefix = array[0];
if (prefix.contains("*") || prefix.contains("{")) {
complicatedUrlPatterns.add(pattern);
continue;
}
prefixKeyedUrlMap.put(prefix, pattern);
}
UrlPatternManager.simpleUrlPatterns = Collections.unmodifiableSet(simpleUrlPatterns);
UrlPatternManager.complicatedUrlPatterns = Collections.unmodifiableSet(complicatedUrlPatterns);
UrlPatternManager.prefixKeyedUrlMap = ImmutableSetMultimap.copyOf(prefixKeyedUrlMap);
}
public static String getBestMatchedUrlPattern(String url) {
if (StringUtils.isEmpty(url)) {
return PATTERN_UNKNOWN;
}
int paramStartIdx = url.indexOf("?");
String path = paramStartIdx >= 0 ? url.substring(0, paramStartIdx) : url;
if (StringUtils.isEmpty(path)) {
return PATTERN_UNKNOWN;
}
if (simpleUrlPatterns.contains(path)) {
return path;
}
String[] array = StringUtils.split(path, "/");
if (ArrayUtils.isEmpty(array)) {
return PATTERN_UNKNOWN;
}
String prefix = array[0];
Collection<String> urlPatterns = Collections.emptySet();
if (prefixKeyedUrlMap.containsKey(prefix)) {
urlPatterns = prefixKeyedUrlMap.get(prefix);
} else {
urlPatterns = complicatedUrlPatterns;
}
return urlPatterns.stream().filter(pattern -> URL_PATH_MATCHER.match(pattern, path)).sorted(URL_PATH_MATCHER.getPatternComparator(path)).findFirst().orElse(PATTERN_UNKNOWN);
}
public static int getLoadedUrlPatternCount() {
return simpleUrlPatterns.size() + complicatedUrlPatterns.size() + prefixKeyedUrlMap.values().size();
}
}
19
View Source File : UrlFilenameViewControllerTests.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* @author Juergen Hoeller
* @author Rick Evans
* @since 14.09.2005
*/
public clreplaced UrlFilenameViewControllerTests {
private PathMatcher pathMatcher = new AntPathMatcher();
@Test
public void withPlainFilename() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withFilenamePlusExtension() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withFilenameAndMatrixVariables() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index;a=A;b=B");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withPrefixAndSuffix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix("mypre_");
ctrl.setSuffix("_mysuf");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("mypre_index_mysuf", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withPrefix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix("mypre_");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("mypre_index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withSuffix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setSuffix("_mysuf");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index_mysuf", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void multiLevel() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("docs/cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void multiLevelWithMapping() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
exposePathInMapping(request, "/docs/**");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void multiLevelMappingWithFallback() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
exposePathInMapping(request, "/docs/cvs/commit.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("docs/cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withContextMapping() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/docs/cvs/commit.html");
request.setContextPath("/myapp");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("docs/cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void settingPrefixToNullCausesEmptyStringToBeUsed() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix(null);
replacedertNotNull("For setPrefix(..) with null, the empty string must be used instead.", ctrl.getPrefix());
replacedertEquals("For setPrefix(..) with null, the empty string must be used instead.", "", ctrl.getPrefix());
}
@Test
public void settingSuffixToNullCausesEmptyStringToBeUsed() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setSuffix(null);
replacedertNotNull("For setPrefix(..) with null, the empty string must be used instead.", ctrl.getSuffix());
replacedertEquals("For setPrefix(..) with null, the empty string must be used instead.", "", ctrl.getSuffix());
}
/**
* This is the expected behavior, and it now has a test to prove it.
* https://opensource.atlreplacedian.com/projects/spring/browse/SPR-2789
*/
@Test
public void nestedPathisUsedAsViewName_InBreakingChangeFromSpring12Line() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/products/view.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("products/view", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withFlashAttributes() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
request.setAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE, new ModelMap("name", "value"));
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertEquals(1, mv.getModel().size());
replacedertEquals("value", mv.getModel().get("name"));
}
private void exposePathInMapping(MockHttpServletRequest request, String mapping) {
String pathInMapping = this.pathMatcher.extractPathWithinPattern(mapping, request.getRequestURI());
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathInMapping);
}
}
19
View Source File : ResourceUrlProvider.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* A central component to use to obtain the public URL path that clients should
* use to access a static resource.
*
* <p>This clreplaced is aware of Spring MVC handler mappings used to serve static
* resources and uses the {@code ResourceResolver} chains of the configured
* {@code ResourceHttpRequestHandler}s to make its decisions.
*
* @author Rossen Stoyanchev
* @since 4.1
*/
public clreplaced ResourceUrlProvider implements ApplicationListener<ContextRefreshedEvent> {
protected final Log logger = LogFactory.getLog(getClreplaced());
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private final Map<String, ResourceHttpRequestHandler> handlerMap = new LinkedHashMap<>();
private boolean autodetect = true;
/**
* Configure a {@code UrlPathHelper} to use in
* {@link #getForRequestUrl(javax.servlet.http.HttpServletRequest, String)}
* in order to derive the lookup path for a target request URL path.
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
this.urlPathHelper = urlPathHelper;
}
/**
* Return the configured {@code UrlPathHelper}.
* @since 4.2.8
*/
public UrlPathHelper getUrlPathHelper() {
return this.urlPathHelper;
}
/**
* Configure a {@code PathMatcher} to use when comparing target lookup path
* against resource mappings.
*/
public void setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
/**
* Return the configured {@code PathMatcher}.
*/
public PathMatcher getPathMatcher() {
return this.pathMatcher;
}
/**
* Manually configure the resource mappings.
* <p><strong>Note:</strong> by default resource mappings are auto-detected
* from the Spring {@code ApplicationContext}. However if this property is
* used, the auto-detection is turned off.
*/
public void setHandlerMap(@Nullable Map<String, ResourceHttpRequestHandler> handlerMap) {
if (handlerMap != null) {
this.handlerMap.clear();
this.handlerMap.putAll(handlerMap);
this.autodetect = false;
}
}
/**
* Return the resource mappings, either manually configured or auto-detected
* when the Spring {@code ApplicationContext} is refreshed.
*/
public Map<String, ResourceHttpRequestHandler> getHandlerMap() {
return this.handlerMap;
}
/**
* Return {@code false} if resource mappings were manually configured,
* {@code true} otherwise.
*/
public boolean isAutodetect() {
return this.autodetect;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (isAutodetect()) {
this.handlerMap.clear();
detectResourceHandlers(event.getApplicationContext());
if (!this.handlerMap.isEmpty()) {
this.autodetect = false;
}
}
}
protected void detectResourceHandlers(ApplicationContext appContext) {
Map<String, SimpleUrlHandlerMapping> beans = appContext.getBeansOfType(SimpleUrlHandlerMapping.clreplaced);
List<SimpleUrlHandlerMapping> mappings = new ArrayList<>(beans.values());
AnnotationAwareOrderComparator.sort(mappings);
for (SimpleUrlHandlerMapping mapping : mappings) {
for (String pattern : mapping.getHandlerMap().keySet()) {
Object handler = mapping.getHandlerMap().get(pattern);
if (handler instanceof ResourceHttpRequestHandler) {
ResourceHttpRequestHandler resourceHandler = (ResourceHttpRequestHandler) handler;
this.handlerMap.put(pattern, resourceHandler);
}
}
}
if (this.handlerMap.isEmpty()) {
logger.trace("No resource handling mappings found");
}
}
/**
* A variation on {@link #getForLookupPath(String)} that accepts a full request
* URL path (i.e. including context and servlet path) and returns the full request
* URL path to expose for public use.
* @param request the current request
* @param requestUrl the request URL path to resolve
* @return the resolved public URL path, or {@code null} if unresolved
*/
@Nullable
public final String getForRequestUrl(HttpServletRequest request, String requestUrl) {
int prefixIndex = getLookupPathIndex(request);
int suffixIndex = getEndPathIndex(requestUrl);
if (prefixIndex >= suffixIndex) {
return null;
}
String prefix = requestUrl.substring(0, prefixIndex);
String suffix = requestUrl.substring(suffixIndex);
String lookupPath = requestUrl.substring(prefixIndex, suffixIndex);
String resolvedLookupPath = getForLookupPath(lookupPath);
return (resolvedLookupPath != null ? prefix + resolvedLookupPath + suffix : null);
}
private int getLookupPathIndex(HttpServletRequest request) {
UrlPathHelper pathHelper = getUrlPathHelper();
String requestUri = pathHelper.getRequestUri(request);
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, HandlerMapping.LOOKUP_PATH);
return requestUri.indexOf(lookupPath);
}
private int getEndPathIndex(String lookupPath) {
int suffixIndex = lookupPath.length();
int queryIndex = lookupPath.indexOf('?');
if (queryIndex > 0) {
suffixIndex = queryIndex;
}
int hashIndex = lookupPath.indexOf('#');
if (hashIndex > 0) {
suffixIndex = Math.min(suffixIndex, hashIndex);
}
return suffixIndex;
}
/**
* Compare the given path against configured resource handler mappings and
* if a match is found use the {@code ResourceResolver} chain of the matched
* {@code ResourceHttpRequestHandler} to resolve the URL path to expose for
* public use.
* <p>It is expected that the given path is what Spring MVC would use for
* request mapping purposes, i.e. excluding context and servlet path portions.
* <p>If several handler mappings match, the handler used will be the one
* configured with the most specific pattern.
* @param lookupPath the lookup path to check
* @return the resolved public URL path, or {@code null} if unresolved
*/
@Nullable
public final String getForLookupPath(String lookupPath) {
// Clean duplicate slashes or pathWithinPattern won't match lookupPath
String previous;
do {
previous = lookupPath;
lookupPath = StringUtils.replace(lookupPath, "//", "/");
} while (!lookupPath.equals(previous));
List<String> matchingPatterns = new ArrayList<>();
for (String pattern : this.handlerMap.keySet()) {
if (getPathMatcher().match(pattern, lookupPath)) {
matchingPatterns.add(pattern);
}
}
if (!matchingPatterns.isEmpty()) {
Comparator<String> patternComparator = getPathMatcher().getPatternComparator(lookupPath);
matchingPatterns.sort(patternComparator);
for (String pattern : matchingPatterns) {
String pathWithinMapping = getPathMatcher().extractPathWithinPattern(pattern, lookupPath);
String pathMapping = lookupPath.substring(0, lookupPath.indexOf(pathWithinMapping));
ResourceHttpRequestHandler handler = this.handlerMap.get(pattern);
ResourceResolverChain chain = new DefaultResourceResolverChain(handler.getResourceResolvers());
String resolved = chain.resolveUrlPath(pathWithinMapping, handler.getLocations());
if (resolved == null) {
continue;
}
return pathMapping + resolved;
}
}
if (logger.isTraceEnabled()) {
logger.trace("No match for \"" + lookupPath + "\"");
}
return null;
}
}
19
View Source File : ResourceUrlProvider.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Configure a {@code PathMatcher} to use when comparing target lookup path
* against resource mappings.
*/
public void setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
19
View Source File : WebContentInterceptor.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Handler interceptor that checks the request and prepares the response.
* Checks for supported methods and a required session, and applies the
* specified {@link org.springframework.http.CacheControl} builder.
* See superclreplaced bean properties for configuration options.
*
* <p>All the settings supported by this interceptor can also be set on
* {@link AbstractController}. This interceptor is mainly intended for applying
* checks and preparations to a set of controllers mapped by a HandlerMapping.
*
* @author Juergen Hoeller
* @author Brian Clozel
* @since 27.11.2003
* @see AbstractController
*/
public clreplaced WebContentInterceptor extends WebContentGenerator implements HandlerInterceptor {
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private Map<String, Integer> cacheMappings = new HashMap<>();
private Map<String, CacheControl> cacheControlMappings = new HashMap<>();
public WebContentInterceptor() {
// No restriction of HTTP methods by default,
// in particular for use with annotated controllers...
super(false);
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
*/
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
*/
public void setUrlDecode(boolean urlDecode) {
this.urlPathHelper.setUrlDecode(urlDecode);
}
/**
* Set the UrlPathHelper to use for resolution of lookup paths.
* <p>Use this to override the default UrlPathHelper with a custom subclreplaced,
* or to share common UrlPathHelper settings across multiple HandlerMappings
* and MethodNameResolvers.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#setUrlPathHelper
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
replacedert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
}
/**
* Map specific URL paths to specific cache seconds.
* <p>Overrides the default cache seconds setting of this interceptor.
* Can specify "-1" to exclude a URL path from default caching.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and a various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher javadoc.
* <p><b>NOTE:</b> Path patterns are not supposed to overlap. If a request
* matches several mappings, it is effectively undefined which one will apply
* (due to the lack of key ordering in {@code java.util.Properties}).
* @param cacheMappings a mapping between URL paths (as keys) and
* cache seconds (as values, need to be integer-parsable)
* @see #setCacheSeconds
* @see org.springframework.util.AntPathMatcher
*/
public void setCacheMappings(Properties cacheMappings) {
this.cacheMappings.clear();
Enumeration<?> propNames = cacheMappings.propertyNames();
while (propNames.hasMoreElements()) {
String path = (String) propNames.nextElement();
int cacheSeconds = Integer.parseInt(cacheMappings.getProperty(path));
this.cacheMappings.put(path, cacheSeconds);
}
}
/**
* Map specific URL paths to a specific {@link org.springframework.http.CacheControl}.
* <p>Overrides the default cache seconds setting of this interceptor.
* Can specify a empty {@link org.springframework.http.CacheControl} instance
* to exclude a URL path from default caching.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and a various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher javadoc.
* <p><b>NOTE:</b> Path patterns are not supposed to overlap. If a request
* matches several mappings, it is effectively undefined which one will apply
* (due to the lack of key ordering in the underlying {@code java.util.HashMap}).
* @param cacheControl the {@code CacheControl} to use
* @param paths the URL paths that will map to the given {@code CacheControl}
* @since 4.2
* @see #setCacheSeconds
* @see org.springframework.util.AntPathMatcher
*/
public void addCacheMapping(CacheControl cacheControl, String... paths) {
for (String path : paths) {
this.cacheControlMappings.put(path, cacheControl);
}
}
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns, for determining cache mappings.
* Default is AntPathMatcher.
* @see #addCacheMapping
* @see #setCacheMappings
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException {
checkRequest(request);
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, HandlerMapping.LOOKUP_PATH);
CacheControl cacheControl = lookupCacheControl(lookupPath);
Integer cacheSeconds = lookupCacheSeconds(lookupPath);
if (cacheControl != null) {
if (logger.isTraceEnabled()) {
logger.trace("Applying " + cacheControl);
}
applyCacheControl(response, cacheControl);
} else if (cacheSeconds != null) {
if (logger.isTraceEnabled()) {
logger.trace("Applying cacheSeconds " + cacheSeconds);
}
applyCacheSeconds(response, cacheSeconds);
} else {
if (logger.isTraceEnabled()) {
logger.trace("Applying default cacheSeconds");
}
prepareResponse(response);
}
return true;
}
/**
* Look up a {@link org.springframework.http.CacheControl} instance for the given URL path.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher clreplaced.
* @param urlPath the URL the bean is mapped to
* @return the replacedociated {@code CacheControl}, or {@code null} if not found
* @see org.springframework.util.AntPathMatcher
*/
@Nullable
protected CacheControl lookupCacheControl(String urlPath) {
// Direct match?
CacheControl cacheControl = this.cacheControlMappings.get(urlPath);
if (cacheControl != null) {
return cacheControl;
}
// Pattern match?
for (String registeredPath : this.cacheControlMappings.keySet()) {
if (this.pathMatcher.match(registeredPath, urlPath)) {
return this.cacheControlMappings.get(registeredPath);
}
}
return null;
}
/**
* Look up a cacheSeconds integer value for the given URL path.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher clreplaced.
* @param urlPath the URL the bean is mapped to
* @return the cacheSeconds integer value, or {@code null} if not found
* @see org.springframework.util.AntPathMatcher
*/
@Nullable
protected Integer lookupCacheSeconds(String urlPath) {
// Direct match?
Integer cacheSeconds = this.cacheMappings.get(urlPath);
if (cacheSeconds != null) {
return cacheSeconds;
}
// Pattern match?
for (String registeredPath : this.cacheMappings.keySet()) {
if (this.pathMatcher.match(registeredPath, urlPath)) {
return this.cacheMappings.get(registeredPath);
}
}
return null;
}
/**
* This implementation is empty.
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
19
View Source File : WebContentInterceptor.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns, for determining cache mappings.
* Default is AntPathMatcher.
* @see #addCacheMapping
* @see #setCacheMappings
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
}
19
View Source File : RequestMatchResult.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Container for the result from request pattern matching via
* {@link MatchableHandlerMapping} with a method to further extract
* URI template variables from the pattern.
*
* @author Rossen Stoyanchev
* @since 4.3.1
*/
public clreplaced RequestMatchResult {
private final String matchingPattern;
private final String lookupPath;
private final PathMatcher pathMatcher;
/**
* Create an instance with a matching pattern.
* @param matchingPattern the matching pattern, possibly not the same as the
* input pattern, e.g. inputPattern="/foo" and matchingPattern="/foo/".
* @param lookupPath the lookup path extracted from the request
* @param pathMatcher the PathMatcher used
*/
public RequestMatchResult(String matchingPattern, String lookupPath, PathMatcher pathMatcher) {
replacedert.hasText(matchingPattern, "'matchingPattern' is required");
replacedert.hasText(lookupPath, "'lookupPath' is required");
replacedert.notNull(pathMatcher, "'pathMatcher' is required");
this.matchingPattern = matchingPattern;
this.lookupPath = lookupPath;
this.pathMatcher = pathMatcher;
}
/**
* Extract URI template variables from the matching pattern as defined in
* {@link PathMatcher#extractUriTemplateVariables}.
* @return a map with URI template variables
*/
public Map<String, String> extractUriTemplateVariables() {
return this.pathMatcher.extractUriTemplateVariables(this.matchingPattern, this.lookupPath);
}
}
19
View Source File : MappedInterceptor.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Contains and delegates calls to a {@link HandlerInterceptor} along with
* include (and optionally exclude) path patterns to which the interceptor should apply.
* Also provides matching logic to test if the interceptor applies to a given request path.
*
* <p>A MappedInterceptor can be registered directly with any
* {@link org.springframework.web.servlet.handler.AbstractHandlerMethodMapping}.
* Furthermore, beans of type {@code MappedInterceptor} are automatically detected by
* {@code AbstractHandlerMethodMapping} (including ancestor ApplicationContext's) which
* effectively means the interceptor is registered "globally" with all handler mappings.
*
* @author Keith Donald
* @author Rossen Stoyanchev
* @author Brian Clozel
* @since 3.0
*/
public final clreplaced MappedInterceptor implements HandlerInterceptor {
@Nullable
private final String[] includePatterns;
@Nullable
private final String[] excludePatterns;
private final HandlerInterceptor interceptor;
@Nullable
private PathMatcher pathMatcher;
/**
* Create a new MappedInterceptor instance.
* @param includePatterns the path patterns to map (empty for matching to all paths)
* @param interceptor the HandlerInterceptor instance to map to the given patterns
*/
public MappedInterceptor(@Nullable String[] includePatterns, HandlerInterceptor interceptor) {
this(includePatterns, null, interceptor);
}
/**
* Create a new MappedInterceptor instance.
* @param includePatterns the path patterns to map (empty for matching to all paths)
* @param excludePatterns the path patterns to exclude (empty for no specific excludes)
* @param interceptor the HandlerInterceptor instance to map to the given patterns
*/
public MappedInterceptor(@Nullable String[] includePatterns, @Nullable String[] excludePatterns, HandlerInterceptor interceptor) {
this.includePatterns = includePatterns;
this.excludePatterns = excludePatterns;
this.interceptor = interceptor;
}
/**
* Create a new MappedInterceptor instance.
* @param includePatterns the path patterns to map (empty for matching to all paths)
* @param interceptor the WebRequestInterceptor instance to map to the given patterns
*/
public MappedInterceptor(@Nullable String[] includePatterns, WebRequestInterceptor interceptor) {
this(includePatterns, null, interceptor);
}
/**
* Create a new MappedInterceptor instance.
* @param includePatterns the path patterns to map (empty for matching to all paths)
* @param excludePatterns the path patterns to exclude (empty for no specific excludes)
* @param interceptor the WebRequestInterceptor instance to map to the given patterns
*/
public MappedInterceptor(@Nullable String[] includePatterns, @Nullable String[] excludePatterns, WebRequestInterceptor interceptor) {
this(includePatterns, excludePatterns, new WebRequestHandlerInterceptorAdapter(interceptor));
}
/**
* Configure a PathMatcher to use with this MappedInterceptor instead of the one preplaceded
* by default to the {@link #matches(String, org.springframework.util.PathMatcher)} method.
* <p>This is an advanced property that is only required when using custom PathMatcher
* implementations that support mapping metadata other than the Ant-style path patterns
* supported by default.
*/
public void setPathMatcher(@Nullable PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
/**
* The configured PathMatcher, or {@code null} if none.
*/
@Nullable
public PathMatcher getPathMatcher() {
return this.pathMatcher;
}
/**
* The path into the application the interceptor is mapped to.
*/
@Nullable
public String[] getPathPatterns() {
return this.includePatterns;
}
/**
* The actual {@link HandlerInterceptor} reference.
*/
public HandlerInterceptor getInterceptor() {
return this.interceptor;
}
/**
* Determine a match for the given lookup path.
* @param lookupPath the current request path
* @param pathMatcher a path matcher for path pattern matching
* @return {@code true} if the interceptor applies to the given request path
*/
public boolean matches(String lookupPath, PathMatcher pathMatcher) {
PathMatcher pathMatcherToUse = (this.pathMatcher != null ? this.pathMatcher : pathMatcher);
if (!ObjectUtils.isEmpty(this.excludePatterns)) {
for (String pattern : this.excludePatterns) {
if (pathMatcherToUse.match(pattern, lookupPath)) {
return false;
}
}
}
if (ObjectUtils.isEmpty(this.includePatterns)) {
return true;
}
for (String pattern : this.includePatterns) {
if (pathMatcherToUse.match(pattern, lookupPath)) {
return true;
}
}
return false;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return this.interceptor.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
this.interceptor.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
this.interceptor.afterCompletion(request, response, handler, ex);
}
}
19
View Source File : MappedInterceptor.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Configure a PathMatcher to use with this MappedInterceptor instead of the one preplaceded
* by default to the {@link #matches(String, org.springframework.util.PathMatcher)} method.
* <p>This is an advanced property that is only required when using custom PathMatcher
* implementations that support mapping metadata other than the Ant-style path patterns
* supported by default.
*/
public void setPathMatcher(@Nullable PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
19
View Source File : AbstractHandlerMapping.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns. Default is AntPathMatcher.
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
if (this.corsConfigurationSource instanceof UrlBasedCorsConfigurationSource) {
((UrlBasedCorsConfigurationSource) this.corsConfigurationSource).setPathMatcher(pathMatcher);
}
}
19
View Source File : PathMatchConfigurer.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Helps with configuring HandlerMappings path matching options such as trailing
* slash match, suffix registration, path matcher and path helper.
*
* <p>Configured path matcher and path helper instances are shared for:
* <ul>
* <li>RequestMappings</li>
* <li>ViewControllerMappings</li>
* <li>ResourcesMappings</li>
* </ul>
*
* @author Brian Clozel
* @since 4.0.3
* @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
* @see org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
*/
public clreplaced PathMatchConfigurer {
@Nullable
private Boolean suffixPatternMatch;
@Nullable
private Boolean trailingSlashMatch;
@Nullable
private Boolean registeredSuffixPatternMatch;
@Nullable
private UrlPathHelper urlPathHelper;
@Nullable
private PathMatcher pathMatcher;
@Nullable
private Map<String, Predicate<Clreplaced<?>>> pathPrefixes;
/**
* Whether to use suffix pattern match (".*") when matching patterns to
* requests. If enabled a method mapped to "/users" also matches to "/users.*".
* <p>By default this is set to {@code true}.
* @see #registeredSuffixPatternMatch
*/
public PathMatchConfigurer setUseSuffixPatternMatch(Boolean suffixPatternMatch) {
this.suffixPatternMatch = suffixPatternMatch;
return this;
}
/**
* Whether to match to URLs irrespective of the presence of a trailing slash.
* If enabled a method mapped to "/users" also matches to "/users/".
* <p>The default value is {@code true}.
*/
public PathMatchConfigurer setUseTrailingSlashMatch(Boolean trailingSlashMatch) {
this.trailingSlashMatch = trailingSlashMatch;
return this;
}
/**
* Whether suffix pattern matching should work only against path extensions
* explicitly registered when you
* {@link WebMvcConfigurer#configureContentNegotiation configure content
* negotiation}. This is generally recommended to reduce ambiguity and to
* avoid issues such as when a "." appears in the path for other reasons.
* <p>By default this is set to "false".
* @see WebMvcConfigurer#configureContentNegotiation
*/
public PathMatchConfigurer setUseRegisteredSuffixPatternMatch(Boolean registeredSuffixPatternMatch) {
this.registeredSuffixPatternMatch = registeredSuffixPatternMatch;
return this;
}
/**
* Set the UrlPathHelper to use for resolution of lookup paths.
* <p>Use this to override the default UrlPathHelper with a custom subclreplaced,
* or to share common UrlPathHelper settings across multiple HandlerMappings
* and MethodNameResolvers.
*/
public PathMatchConfigurer setUrlPathHelper(UrlPathHelper urlPathHelper) {
this.urlPathHelper = urlPathHelper;
return this;
}
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns. Default is AntPathMatcher.
* @see org.springframework.util.AntPathMatcher
*/
public PathMatchConfigurer setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
return this;
}
/**
* Configure a path prefix to apply to matching controller methods.
* <p>Prefixes are used to enrich the mappings of every {@code @RequestMapping}
* method whose controller type is matched by the corresponding
* {@code Predicate}. The prefix for the first matching predicate is used.
* <p>Consider using {@link org.springframework.web.method.HandlerTypePredicate
* HandlerTypePredicate} to group controllers.
* @param prefix the prefix to apply
* @param predicate a predicate for matching controller types
* @since 5.1
*/
public PathMatchConfigurer addPathPrefix(String prefix, Predicate<Clreplaced<?>> predicate) {
if (this.pathPrefixes == null) {
this.pathPrefixes = new LinkedHashMap<>();
}
this.pathPrefixes.put(prefix, predicate);
return this;
}
@Nullable
public Boolean isUseSuffixPatternMatch() {
return this.suffixPatternMatch;
}
@Nullable
public Boolean isUseTrailingSlashMatch() {
return this.trailingSlashMatch;
}
@Nullable
public Boolean isUseRegisteredSuffixPatternMatch() {
return this.registeredSuffixPatternMatch;
}
@Nullable
public UrlPathHelper getUrlPathHelper() {
return this.urlPathHelper;
}
@Nullable
public PathMatcher getPathMatcher() {
return this.pathMatcher;
}
@Nullable
protected Map<String, Predicate<Clreplaced<?>>> getPathPrefixes() {
return this.pathPrefixes;
}
}
19
View Source File : PathMatchConfigurer.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns. Default is AntPathMatcher.
* @see org.springframework.util.AntPathMatcher
*/
public PathMatchConfigurer setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
return this;
}
19
View Source File : InterceptorRegistration.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* A PathMatcher implementation to use with this interceptor. This is an optional,
* advanced property required only if using custom PathMatcher implementations
* that support mapping metadata other than the Ant path patterns supported
* by default.
*/
public InterceptorRegistration pathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
return this;
}
19
View Source File : UrlBasedCorsConfigurationSource.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Provide a per request {@link CorsConfiguration} instance based on a
* collection of {@link CorsConfiguration} mapped on path patterns.
*
* <p>Exact path mapping URIs (such as {@code "/admin"}) are supported
* as well as Ant-style path patterns (such as {@code "/admin/**"}).
*
* @author Sebastien Deleuze
* @since 4.2
*/
public clreplaced UrlBasedCorsConfigurationSource implements CorsConfigurationSource {
private final Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<>();
private PathMatcher pathMatcher = new AntPathMatcher();
private UrlPathHelper urlPathHelper = new UrlPathHelper();
@Nullable
private String lookupPathAttributeName;
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns. Default is AntPathMatcher.
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
*/
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
*/
public void setUrlDecode(boolean urlDecode) {
this.urlPathHelper.setUrlDecode(urlDecode);
}
/**
* Optionally configure the name of the attribute that caches the lookupPath.
* This is used to make the call to
* {@link UrlPathHelper#getLookupPathForRequest(HttpServletRequest, String)}
* @param lookupPathAttributeName the request attribute to check
* @since 5.2
*/
public void setLookupPathAttributeName(@Nullable String lookupPathAttributeName) {
this.lookupPathAttributeName = lookupPathAttributeName;
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* @see org.springframework.web.util.UrlPathHelper#setRemoveSemicolonContent(boolean)
*/
public void setRemoveSemicolonContent(boolean removeSemicolonContent) {
this.urlPathHelper.setRemoveSemicolonContent(removeSemicolonContent);
}
/**
* Set the UrlPathHelper to use for resolution of lookup paths.
* <p>Use this to override the default UrlPathHelper with a custom subclreplaced.
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
replacedert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
}
/**
* Set CORS configuration based on URL patterns.
*/
public void setCorsConfigurations(@Nullable Map<String, CorsConfiguration> corsConfigurations) {
this.corsConfigurations.clear();
if (corsConfigurations != null) {
this.corsConfigurations.putAll(corsConfigurations);
}
}
/**
* Get the CORS configuration.
*/
public Map<String, CorsConfiguration> getCorsConfigurations() {
return Collections.unmodifiableMap(this.corsConfigurations);
}
/**
* Register a {@link CorsConfiguration} for the specified path pattern.
*/
public void registerCorsConfiguration(String path, CorsConfiguration config) {
this.corsConfigurations.put(path, config);
}
@Override
@Nullable
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, this.lookupPathAttributeName);
for (Map.Entry<String, CorsConfiguration> entry : this.corsConfigurations.entrySet()) {
if (this.pathMatcher.match(entry.getKey(), lookupPath)) {
return entry.getValue();
}
}
return null;
}
}
19
View Source File : UrlBasedCorsConfigurationSource.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns. Default is AntPathMatcher.
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
}
19
View Source File : DefaultUserDestinationResolver.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Provide the {@code PathMatcher} in use for working with destinations
* which in turn helps to determine whether the leading slash should be
* kept in actual destinations after removing the
* {@link #setUserDestinationPrefix userDestinationPrefix}.
* <p>By default actual destinations have a leading slash, e.g.
* {@code /queue/position-updates} which makes sense with brokers that
* support destinations with slash as separator. When a {@code PathMatcher}
* is provided that supports an alternative separator, then resulting
* destinations won't have a leading slash, e.g. {@code
* jms.queue.position-updates}.
* @param pathMatcher the PathMatcher used to work with destinations
* @since 4.3
* @deprecated as of 4.3.14 this property is no longer used and is replaced
* by {@link #setRemoveLeadingSlash(boolean)} that indicates more explicitly
* whether to keep the leading slash which may or may not be the case
* regardless of how the {@code PathMatcher} is configured.
*/
@Deprecated
public void setPathMatcher(@Nullable PathMatcher pathMatcher) {
// Do nothing
}
19
View Source File : MessageBrokerRegistry.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* A registry for configuring message broker options.
*
* @author Rossen Stoyanchev
* @author Sebastien Deleuze
* @since 4.0
*/
public clreplaced MessageBrokerRegistry {
private final SubscribableChannel clientInboundChannel;
private final MessageChannel clientOutboundChannel;
@Nullable
private SimpleBrokerRegistration simpleBrokerRegistration;
@Nullable
private StompBrokerRelayRegistration brokerRelayRegistration;
private final ChannelRegistration brokerChannelRegistration = new ChannelRegistration();
@Nullable
private String[] applicationDestinationPrefixes;
@Nullable
private String userDestinationPrefix;
@Nullable
private Integer userRegistryOrder;
@Nullable
private PathMatcher pathMatcher;
@Nullable
private Integer cacheLimit;
private boolean preservePublishOrder;
public MessageBrokerRegistry(SubscribableChannel clientInboundChannel, MessageChannel clientOutboundChannel) {
replacedert.notNull(clientInboundChannel, "Inbound channel must not be null");
replacedert.notNull(clientOutboundChannel, "Outbound channel must not be null");
this.clientInboundChannel = clientInboundChannel;
this.clientOutboundChannel = clientOutboundChannel;
}
/**
* Enable a simple message broker and configure one or more prefixes to filter
* destinations targeting the broker (e.g. destinations prefixed with "/topic").
*/
public SimpleBrokerRegistration enableSimpleBroker(String... destinationPrefixes) {
this.simpleBrokerRegistration = new SimpleBrokerRegistration(this.clientInboundChannel, this.clientOutboundChannel, destinationPrefixes);
return this.simpleBrokerRegistration;
}
/**
* Enable a STOMP broker relay and configure the destination prefixes supported by the
* message broker. Check the STOMP doreplacedentation of the message broker for supported
* destinations.
*/
public StompBrokerRelayRegistration enableStompBrokerRelay(String... destinationPrefixes) {
this.brokerRelayRegistration = new StompBrokerRelayRegistration(this.clientInboundChannel, this.clientOutboundChannel, destinationPrefixes);
return this.brokerRelayRegistration;
}
/**
* Customize the channel used to send messages from the application to the message
* broker. By default, messages from the application to the message broker are sent
* synchronously, which means application code sending a message will find out
* if the message cannot be sent through an exception. However, this can be changed
* if the broker channel is configured here with task executor properties.
*/
public ChannelRegistration configureBrokerChannel() {
return this.brokerChannelRegistration;
}
protected ChannelRegistration getBrokerChannelRegistration() {
return this.brokerChannelRegistration;
}
@Nullable
protected String getUserDestinationBroadcast() {
return (this.brokerRelayRegistration != null ? this.brokerRelayRegistration.getUserDestinationBroadcast() : null);
}
@Nullable
protected String getUserRegistryBroadcast() {
return (this.brokerRelayRegistration != null ? this.brokerRelayRegistration.getUserRegistryBroadcast() : null);
}
/**
* Configure one or more prefixes to filter destinations targeting application
* annotated methods. For example destinations prefixed with "/app" may be
* processed by annotated methods while other destinations may target the
* message broker (e.g. "/topic", "/queue").
* <p>When messages are processed, the matching prefix is removed from the destination
* in order to form the lookup path. This means annotations should not contain the
* destination prefix.
* <p>Prefixes that do not have a trailing slash will have one automatically appended.
*/
public MessageBrokerRegistry setApplicationDestinationPrefixes(String... prefixes) {
this.applicationDestinationPrefixes = prefixes;
return this;
}
@Nullable
protected Collection<String> getApplicationDestinationPrefixes() {
return (this.applicationDestinationPrefixes != null ? Arrays.asList(this.applicationDestinationPrefixes) : null);
}
/**
* Configure the prefix used to identify user destinations. User destinations
* provide the ability for a user to subscribe to queue names unique to their
* session as well as for others to send messages to those unique,
* user-specific queues.
* <p>For example when a user attempts to subscribe to "/user/queue/position-updates",
* the destination may be translated to "/queue/position-updatesi9oqdfzo" yielding a
* unique queue name that does not collide with any other user attempting to do the same.
* Subsequently when messages are sent to "/user/{username}/queue/position-updates",
* the destination is translated to "/queue/position-updatesi9oqdfzo".
* <p>The default prefix used to identify such destinations is "/user/".
*/
public MessageBrokerRegistry setUserDestinationPrefix(String destinationPrefix) {
this.userDestinationPrefix = destinationPrefix;
return this;
}
@Nullable
protected String getUserDestinationPrefix() {
return this.userDestinationPrefix;
}
/**
* Set the order for the
* {@link org.springframework.messaging.simp.user.SimpUserRegistry
* SimpUserRegistry} to use as a {@link SmartApplicationListener}.
* @param order the order value
* @since 5.0.8
*/
public void setUserRegistryOrder(int order) {
this.userRegistryOrder = order;
}
@Nullable
protected Integer getUserRegistryOrder() {
return this.userRegistryOrder;
}
/**
* Configure the PathMatcher to use to match the destinations of incoming
* messages to {@code @MessageMapping} and {@code @SubscribeMapping} methods.
* <p>By default {@link org.springframework.util.AntPathMatcher} is configured.
* However applications may provide an {@code AntPathMatcher} instance
* customized to use "." (commonly used in messaging) instead of "/" as path
* separator or provide a completely different PathMatcher implementation.
* <p>Note that the configured PathMatcher is only used for matching the
* portion of the destination after the configured prefix. For example given
* application destination prefix "/app" and destination "/app/price.stock.**",
* the message might be mapped to a controller with "price" and "stock.**"
* as its type and method-level mappings respectively.
* <p>When the simple broker is enabled, the PathMatcher configured here is
* also used to match message destinations when brokering messages.
* @since 4.1
* @see org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry#setPathMatcher
*/
public MessageBrokerRegistry setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
return this;
}
@Nullable
protected PathMatcher getPathMatcher() {
return this.pathMatcher;
}
/**
* Configure the cache limit to apply for registrations with the broker.
* <p>This is currently only applied for the destination cache in the
* subscription registry. The default cache limit there is 1024.
* @since 4.3.2
* @see org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry#setCacheLimit
*/
public MessageBrokerRegistry setCacheLimit(int cacheLimit) {
this.cacheLimit = cacheLimit;
return this;
}
/**
* Whether the client must receive messages in the order of publication.
* <p>By default messages sent to the {@code "clientOutboundChannel"} may
* not be processed in the same order because the channel is backed by a
* ThreadPoolExecutor that in turn does not guarantee processing in order.
* <p>When this flag is set to {@code true} messages within the same session
* will be sent to the {@code "clientOutboundChannel"} one at a time in
* order to preserve the order of publication. Enable this only if needed
* since there is some performance overhead to keep messages in order.
* @since 5.1
*/
public MessageBrokerRegistry setPreservePublishOrder(boolean preservePublishOrder) {
this.preservePublishOrder = preservePublishOrder;
return this;
}
@Nullable
protected SimpleBrokerMessageHandler getSimpleBroker(SubscribableChannel brokerChannel) {
if (this.simpleBrokerRegistration == null && this.brokerRelayRegistration == null) {
enableSimpleBroker();
}
if (this.simpleBrokerRegistration != null) {
SimpleBrokerMessageHandler handler = this.simpleBrokerRegistration.getMessageHandler(brokerChannel);
handler.setPathMatcher(this.pathMatcher);
handler.setCacheLimit(this.cacheLimit);
handler.setPreservePublishOrder(this.preservePublishOrder);
return handler;
}
return null;
}
@Nullable
protected StompBrokerRelayMessageHandler getStompBrokerRelay(SubscribableChannel brokerChannel) {
if (this.brokerRelayRegistration != null) {
StompBrokerRelayMessageHandler relay = this.brokerRelayRegistration.getMessageHandler(brokerChannel);
relay.setPreservePublishOrder(this.preservePublishOrder);
return relay;
}
return null;
}
}
19
View Source File : MessageBrokerRegistry.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Configure the PathMatcher to use to match the destinations of incoming
* messages to {@code @MessageMapping} and {@code @SubscribeMapping} methods.
* <p>By default {@link org.springframework.util.AntPathMatcher} is configured.
* However applications may provide an {@code AntPathMatcher} instance
* customized to use "." (commonly used in messaging) instead of "/" as path
* separator or provide a completely different PathMatcher implementation.
* <p>Note that the configured PathMatcher is only used for matching the
* portion of the destination after the configured prefix. For example given
* application destination prefix "/app" and destination "/app/price.stock.**",
* the message might be mapped to a controller with "price" and "stock.**"
* as its type and method-level mappings respectively.
* <p>When the simple broker is enabled, the PathMatcher configured here is
* also used to match message destinations when brokering messages.
* @since 4.1
* @see org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry#setPathMatcher
*/
public MessageBrokerRegistry setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
return this;
}
19
View Source File : SimpleBrokerMessageHandler.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* When configured, the given PathMatcher is preplaceded down to the underlying
* SubscriptionRegistry to use for matching destination to subscriptions.
* <p>Default is a standard {@link org.springframework.util.AntPathMatcher}.
* @since 4.1
* @see #setSubscriptionRegistry
* @see DefaultSubscriptionRegistry#setPathMatcher
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(@Nullable PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
initPathMatcherToUse();
}
19
View Source File : DefaultSubscriptionRegistry.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* Specify the {@link PathMatcher} to use.
*/
public void setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
19
View Source File : DestinationPatternsMessageCondition.java
License : MIT License
Project Creator : Vip-Augus
License : MIT License
Project Creator : Vip-Augus
/**
* A {@link MessageCondition} for matching the destination of a Message
* against one or more destination patterns using a {@link PathMatcher}.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public clreplaced DestinationPatternsMessageCondition extends AbstractMessageCondition<DestinationPatternsMessageCondition> {
/**
* The name of the "lookup destination" header.
*/
public static final String LOOKUP_DESTINATION_HEADER = "lookupDestination";
private final Set<String> patterns;
private final PathMatcher pathMatcher;
/**
* Creates a new instance with the given destination patterns.
* Each pattern that is not empty and does not start with "/" is prepended with "/".
* @param patterns 0 or more URL patterns; if 0 the condition will match to every request.
*/
public DestinationPatternsMessageCondition(String... patterns) {
this(patterns, null);
}
/**
* Alternative constructor accepting a custom PathMatcher.
* @param patterns the URL patterns to use; if 0, the condition will match to every request.
* @param pathMatcher the PathMatcher to use
*/
public DestinationPatternsMessageCondition(String[] patterns, @Nullable PathMatcher pathMatcher) {
this(Arrays.asList(patterns), pathMatcher);
}
private DestinationPatternsMessageCondition(Collection<String> patterns, @Nullable PathMatcher pathMatcher) {
this.pathMatcher = (pathMatcher != null ? pathMatcher : new AntPathMatcher());
this.patterns = Collections.unmodifiableSet(prependLeadingSlash(patterns, this.pathMatcher));
}
private static Set<String> prependLeadingSlash(Collection<String> patterns, PathMatcher pathMatcher) {
boolean slashSeparator = pathMatcher.combine("a", "a").equals("a/a");
Set<String> result = new LinkedHashSet<>(patterns.size());
for (String pattern : patterns) {
if (slashSeparator && StringUtils.hasLength(pattern) && !pattern.startsWith("/")) {
pattern = "/" + pattern;
}
result.add(pattern);
}
return result;
}
public Set<String> getPatterns() {
return this.patterns;
}
@Override
protected Collection<String> getContent() {
return this.patterns;
}
@Override
protected String getToStringInfix() {
return " || ";
}
/**
* Returns a new instance with URL patterns from the current instance ("this") and
* the "other" instance as follows:
* <ul>
* <li>If there are patterns in both instances, combine the patterns in "this" with
* the patterns in "other" using {@link org.springframework.util.PathMatcher#combine(String, String)}.
* <li>If only one instance has patterns, use them.
* <li>If neither instance has patterns, use an empty String (i.e. "").
* </ul>
*/
@Override
public DestinationPatternsMessageCondition combine(DestinationPatternsMessageCondition other) {
Set<String> result = new LinkedHashSet<>();
if (!this.patterns.isEmpty() && !other.patterns.isEmpty()) {
for (String pattern1 : this.patterns) {
for (String pattern2 : other.patterns) {
result.add(this.pathMatcher.combine(pattern1, pattern2));
}
}
} else if (!this.patterns.isEmpty()) {
result.addAll(this.patterns);
} else if (!other.patterns.isEmpty()) {
result.addAll(other.patterns);
} else {
result.add("");
}
return new DestinationPatternsMessageCondition(result, this.pathMatcher);
}
/**
* Check if any of the patterns match the given Message destination and return an instance
* that is guaranteed to contain matching patterns, sorted via
* {@link org.springframework.util.PathMatcher#getPatternComparator(String)}.
* @param message the message to match to
* @return the same instance if the condition contains no patterns;
* or a new condition with sorted matching patterns;
* or {@code null} either if a destination can not be extracted or there is no match
*/
@Override
@Nullable
public DestinationPatternsMessageCondition getMatchingCondition(Message<?> message) {
String destination = (String) message.getHeaders().get(LOOKUP_DESTINATION_HEADER);
if (destination == null) {
return null;
}
if (this.patterns.isEmpty()) {
return this;
}
List<String> matches = new ArrayList<>();
for (String pattern : this.patterns) {
if (pattern.equals(destination) || this.pathMatcher.match(pattern, destination)) {
matches.add(pattern);
}
}
if (matches.isEmpty()) {
return null;
}
matches.sort(this.pathMatcher.getPatternComparator(destination));
return new DestinationPatternsMessageCondition(matches, this.pathMatcher);
}
/**
* Compare the two conditions based on the destination patterns they contain.
* Patterns are compared one at a time, from top to bottom via
* {@link org.springframework.util.PathMatcher#getPatternComparator(String)}.
* If all compared patterns match equally, but one instance has more patterns,
* it is considered a closer match.
* <p>It is replacedumed that both instances have been obtained via
* {@link #getMatchingCondition(Message)} to ensure they contain only patterns
* that match the request and are sorted with the best matches on top.
*/
@Override
public int compareTo(DestinationPatternsMessageCondition other, Message<?> message) {
String destination = (String) message.getHeaders().get(LOOKUP_DESTINATION_HEADER);
if (destination == null) {
return 0;
}
Comparator<String> patternComparator = this.pathMatcher.getPatternComparator(destination);
Iterator<String> iterator = this.patterns.iterator();
Iterator<String> iteratorOther = other.patterns.iterator();
while (iterator.hasNext() && iteratorOther.hasNext()) {
int result = patternComparator.compare(iterator.next(), iteratorOther.next());
if (result != 0) {
return result;
}
}
if (iterator.hasNext()) {
return -1;
} else if (iteratorOther.hasNext()) {
return 1;
} else {
return 0;
}
}
}
19
View Source File : VaadinFrontendInterceptor.java
License : Apache License 2.0
Project Creator : vaadin
License : Apache License 2.0
Project Creator : vaadin
/**
* Intercepts calls to ResourceHttpRequestHandler in order to verify when the
* resource does not exist and forward to '/'
*
* By default it only intercepts paths without any extension. If you want to
* configure the interceptor to match your routing pattern, you need to provide
* a {@link VaadinFrontendRouteMatcher} bean in your configuration.
*/
@Configuration
public clreplaced VaadinFrontendInterceptor implements HandlerInterceptor, WebMvcConfigurer {
private final PathMatcher pathMatcher;
/**
* Default constructor.
*
* @param routeMatcher
* the custom route matcher for the interceptor, if null it uses
* default implementation
*/
public VaadinFrontendInterceptor(@Autowired(required = false) VaadinFrontendRouteMatcher routeMatcher) {
pathMatcher = new DelegatingPathMatcher(routeMatcher);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(this).addPathPatterns("*").pathMatcher(pathMatcher);
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof ResourceHttpRequestHandler) {
// Wrap the response to check if sendError is called
HttpServletResponse wrappedResponse = new HttpServletResponseWrapper(response) {
@Override
public void sendError(int sc) throws IOException {
setStatus(sc);
}
};
wrappedResponse.setStatus(SC_OK);
// Check whether the static resource can be handled
((ResourceHttpRequestHandler) handler).handleRequest(request, wrappedResponse);
// forward to root when not found and not already redirected
if (wrappedResponse.getStatus() == SC_NOT_FOUND && request.getAttribute("vaadin-frontend-redirected") == null) {
request.getRequestDispatcher("/").forward(request, response);
request.setAttribute("vaadin-frontend-redirected", true);
// pretend that the response is OK since we forwarded it
wrappedResponse.setStatus(SC_OK);
}
// handleRequest was already run, do not continue
return false;
}
return true;
}
private static clreplaced DelegatingPathMatcher implements PathMatcher {
private final VaadinFrontendRouteMatcher routeMatcher;
private DelegatingPathMatcher(VaadinFrontendRouteMatcher routeMatcher) {
this.routeMatcher = routeMatcher != null ? routeMatcher : new VaadinFrontendRouteMatcher() {
};
}
@Override
public boolean match(String pattern, String path) {
return routeMatcher.isDynamicRoutePath(path);
}
@Override
public boolean isPattern(String path) {
throw new UnsupportedOperationException();
}
@Override
public boolean matchStart(String pattern, String path) {
throw new UnsupportedOperationException();
}
@Override
public String extractPathWithinPattern(String pattern, String path) {
throw new UnsupportedOperationException();
}
@Override
public Map<String, String> extractUriTemplateVariables(String pattern, String path) {
throw new UnsupportedOperationException();
}
@Override
public Comparator<String> getPatternComparator(String path) {
throw new UnsupportedOperationException();
}
@Override
public String combine(String pattern1, String pattern2) {
throw new UnsupportedOperationException();
}
}
}
19
View Source File : JWTAuthenticationTokenFilter.java
License : Apache License 2.0
Project Creator : u014427391
License : Apache License 2.0
Project Creator : u014427391
private Boolean checkRequestUri(String requestUri) {
boolean filter = true;
final PathMatcher pathMatcher = new AntPathMatcher();
for (String permitUri : permitAllUris) {
if (pathMatcher.match(permitUri, requestUri)) {
// permit all的链接直接放过
filter = true;
}
}
for (String authUri : authenticateUris) {
if (pathMatcher.match(authUri, requestUri)) {
filter = false;
}
}
return filter;
}
19
View Source File : PathMatcherServerWebExchangeMatcher.java
License : Apache License 2.0
Project Creator : spring-projects
License : Apache License 2.0
Project Creator : spring-projects
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "pathMatcher cannot be null");
this.pathMatcher = pathMatcher;
}
19
View Source File : HostRoutePredicateFactory.java
License : Apache License 2.0
Project Creator : spring-cloud
License : Apache License 2.0
Project Creator : spring-cloud
/**
* @author Spencer Gibb
*/
public clreplaced HostRoutePredicateFactory extends AbstractRoutePredicateFactory<HostRoutePredicateFactory.Config> {
private PathMatcher pathMatcher = new AntPathMatcher(".");
public HostRoutePredicateFactory() {
super(Config.clreplaced);
}
public void setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList("patterns");
}
@Override
public ShortcutType shortcutType() {
return ShortcutType.GATHER_LIST;
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
String host = exchange.getRequest().getHeaders().getFirst("Host");
Optional<String> optionalPattern = config.getPatterns().stream().filter(pattern -> pathMatcher.match(pattern, host)).findFirst();
if (optionalPattern.isPresent()) {
Map<String, String> variables = pathMatcher.extractUriTemplateVariables(optionalPattern.get(), host);
ServerWebExchangeUtils.putUriTemplateVariables(exchange, variables);
return true;
}
return false;
}
@Override
public String toString() {
return String.format("Hosts: %s", config.getPatterns());
}
};
}
@Validated
public static clreplaced Config {
private List<String> patterns = new ArrayList<>();
public List<String> getPatterns() {
return patterns;
}
public Config setPatterns(List<String> patterns) {
this.patterns = patterns;
return this;
}
@Override
public String toString() {
return new ToStringCreator(this).append("patterns", patterns).toString();
}
}
}
19
View Source File : HostRoutePredicateFactory.java
License : Apache License 2.0
Project Creator : spring-cloud
License : Apache License 2.0
Project Creator : spring-cloud
public void setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
19
View Source File : UrlFilenameViewControllerTests.java
License : Apache License 2.0
Project Creator : SourceHot
License : Apache License 2.0
Project Creator : SourceHot
/**
* @author Juergen Hoeller
* @author Rick Evans
* @since 14.09.2005
*/
public clreplaced UrlFilenameViewControllerTests {
private PathMatcher pathMatcher = new AntPathMatcher();
@Test
public void withPlainFilename() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("index");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void withFilenamePlusExtension() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("index");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void withFilenameAndMatrixVariables() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index;a=A;b=B");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("index");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void withPrefixAndSuffix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix("mypre_");
ctrl.setSuffix("_mysuf");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("mypre_index_mysuf");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void withPrefix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix("mypre_");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("mypre_index");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void withSuffix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setSuffix("_mysuf");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("index_mysuf");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void multiLevel() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("docs/cvs/commit");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void multiLevelWithMapping() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
exposePathInMapping(request, "/docs/**");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("cvs/commit");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void multiLevelMappingWithFallback() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
exposePathInMapping(request, "/docs/cvs/commit.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("docs/cvs/commit");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void withContextMapping() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/docs/cvs/commit.html");
request.setContextPath("/myapp");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("docs/cvs/commit");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void settingPrefixToNullCausesEmptyStringToBeUsed() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix(null);
replacedertThat(ctrl.getPrefix()).as("For setPrefix(..) with null, the empty string must be used instead.").isNotNull();
replacedertThat(ctrl.getPrefix()).as("For setPrefix(..) with null, the empty string must be used instead.").isEqualTo("");
}
@Test
public void settingSuffixToNullCausesEmptyStringToBeUsed() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setSuffix(null);
replacedertThat(ctrl.getSuffix()).as("For setPrefix(..) with null, the empty string must be used instead.").isNotNull();
replacedertThat(ctrl.getSuffix()).as("For setPrefix(..) with null, the empty string must be used instead.").isEqualTo("");
}
/**
* This is the expected behavior, and it now has a test to prove it.
* https://opensource.atlreplacedian.com/projects/spring/browse/SPR-2789
*/
@Test
public void nestedPathisUsedAsViewName_InBreakingChangeFromSpring12Line() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/products/view.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("products/view");
replacedertThat(mv.getModel().isEmpty()).isTrue();
}
@Test
public void withFlashAttributes() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
request.setAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE, new ModelMap("name", "value"));
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertThat(mv.getViewName()).isEqualTo("index");
replacedertThat(mv.getModel().size()).isEqualTo(1);
replacedertThat(mv.getModel().get("name")).isEqualTo("value");
}
private void exposePathInMapping(MockHttpServletRequest request, String mapping) {
String pathInMapping = this.pathMatcher.extractPathWithinPattern(mapping, request.getRequestURI());
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathInMapping);
}
}
19
View Source File : WebContentInterceptor.java
License : Apache License 2.0
Project Creator : SourceHot
License : Apache License 2.0
Project Creator : SourceHot
/**
* Handler interceptor that checks the request and prepares the response.
* Checks for supported methods and a required session, and applies the
* specified {@link org.springframework.http.CacheControl} builder.
* See superclreplaced bean properties for configuration options.
*
* <p>All the settings supported by this interceptor can also be set on
* {@link AbstractController}. This interceptor is mainly intended for applying
* checks and preparations to a set of controllers mapped by a HandlerMapping.
*
* @author Juergen Hoeller
* @author Brian Clozel
* @since 27.11.2003
* @see AbstractController
*/
public clreplaced WebContentInterceptor extends WebContentGenerator implements HandlerInterceptor {
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private Map<String, Integer> cacheMappings = new HashMap<>();
private Map<String, CacheControl> cacheControlMappings = new HashMap<>();
public WebContentInterceptor() {
// No restriction of HTTP methods by default,
// in particular for use with annotated controllers...
super(false);
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
*/
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
*/
public void setUrlDecode(boolean urlDecode) {
this.urlPathHelper.setUrlDecode(urlDecode);
}
/**
* Set the UrlPathHelper to use for resolution of lookup paths.
* <p>Use this to override the default UrlPathHelper with a custom subclreplaced,
* or to share common UrlPathHelper settings across multiple HandlerMappings
* and MethodNameResolvers.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#setUrlPathHelper
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
replacedert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
}
/**
* Map specific URL paths to specific cache seconds.
* <p>Overrides the default cache seconds setting of this interceptor.
* Can specify "-1" to exclude a URL path from default caching.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and a various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher javadoc.
* <p><b>NOTE:</b> Path patterns are not supposed to overlap. If a request
* matches several mappings, it is effectively undefined which one will apply
* (due to the lack of key ordering in {@code java.util.Properties}).
* @param cacheMappings a mapping between URL paths (as keys) and
* cache seconds (as values, need to be integer-parsable)
* @see #setCacheSeconds
* @see org.springframework.util.AntPathMatcher
*/
public void setCacheMappings(Properties cacheMappings) {
this.cacheMappings.clear();
Enumeration<?> propNames = cacheMappings.propertyNames();
while (propNames.hasMoreElements()) {
String path = (String) propNames.nextElement();
int cacheSeconds = Integer.parseInt(cacheMappings.getProperty(path));
this.cacheMappings.put(path, cacheSeconds);
}
}
/**
* Map specific URL paths to a specific {@link org.springframework.http.CacheControl}.
* <p>Overrides the default cache seconds setting of this interceptor.
* Can specify a empty {@link org.springframework.http.CacheControl} instance
* to exclude a URL path from default caching.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and a various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher javadoc.
* <p><b>NOTE:</b> Path patterns are not supposed to overlap. If a request
* matches several mappings, it is effectively undefined which one will apply
* (due to the lack of key ordering in the underlying {@code java.util.HashMap}).
* @param cacheControl the {@code CacheControl} to use
* @param paths the URL paths that will map to the given {@code CacheControl}
* @since 4.2
* @see #setCacheSeconds
* @see org.springframework.util.AntPathMatcher
*/
public void addCacheMapping(CacheControl cacheControl, String... paths) {
for (String path : paths) {
this.cacheControlMappings.put(path, cacheControl);
}
}
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns, for determining cache mappings.
* Default is AntPathMatcher.
* @see #addCacheMapping
* @see #setCacheMappings
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException {
checkRequest(request);
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, HandlerMapping.LOOKUP_PATH);
CacheControl cacheControl = lookupCacheControl(lookupPath);
Integer cacheSeconds = lookupCacheSeconds(lookupPath);
if (cacheControl != null) {
if (logger.isTraceEnabled()) {
logger.trace("Applying " + cacheControl);
}
applyCacheControl(response, cacheControl);
} else if (cacheSeconds != null) {
if (logger.isTraceEnabled()) {
logger.trace("Applying cacheSeconds " + cacheSeconds);
}
applyCacheSeconds(response, cacheSeconds);
} else {
if (logger.isTraceEnabled()) {
logger.trace("Applying default cacheSeconds");
}
prepareResponse(response);
}
return true;
}
/**
* Look up a {@link org.springframework.http.CacheControl} instance for the given URL path.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher clreplaced.
* @param urlPath the URL the bean is mapped to
* @return the replacedociated {@code CacheControl}, or {@code null} if not found
* @see org.springframework.util.AntPathMatcher
*/
@Nullable
protected CacheControl lookupCacheControl(String urlPath) {
// Direct match?
CacheControl cacheControl = this.cacheControlMappings.get(urlPath);
if (cacheControl != null) {
return cacheControl;
}
// Pattern match?
for (Map.Entry<String, CacheControl> entry : this.cacheControlMappings.entrySet()) {
if (this.pathMatcher.match(entry.getKey(), urlPath)) {
return entry.getValue();
}
}
return null;
}
/**
* Look up a cacheSeconds integer value for the given URL path.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher clreplaced.
* @param urlPath the URL the bean is mapped to
* @return the cacheSeconds integer value, or {@code null} if not found
* @see org.springframework.util.AntPathMatcher
*/
@Nullable
protected Integer lookupCacheSeconds(String urlPath) {
// Direct match?
Integer cacheSeconds = this.cacheMappings.get(urlPath);
if (cacheSeconds != null) {
return cacheSeconds;
}
// Pattern match?
for (Map.Entry<String, Integer> entry : this.cacheMappings.entrySet()) {
if (this.pathMatcher.match(entry.getKey(), urlPath)) {
return entry.getValue();
}
}
return null;
}
/**
* This implementation is empty.
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
19
View Source File : PermissionDataAspect.java
License : MIT License
Project Creator : smallyunet
License : MIT License
Project Creator : smallyunet
/**
* 匹配前端传过来的地址 匹配成功返回正则地址
* AntPathMatcher匹配地址
* ()* 匹配0个或多个字符
* ()**匹配0个或多个目录
*/
private String getRegexpUrl(String url) {
List<String> list = sysPermissionService.queryPermissionUrlWithStar();
if (list != null && list.size() > 0) {
for (String p : list) {
PathMatcher matcher = new AntPathMatcher();
if (matcher.match(p, url)) {
return p;
}
}
}
return null;
}
19
View Source File : MappingDelegate.java
License : MIT License
Project Creator : six-ddc
License : MIT License
Project Creator : six-ddc
RequestMappingInfo buildRequestMappingInfo(UrlPathHelper urlPathHelper, PathMatcher pathMatcher) {
RequestMappingInfo.BuilderConfiguration configuration = new RequestMappingInfo.BuilderConfiguration();
configuration.setUrlPathHelper(urlPathHelper);
configuration.setPathMatcher(pathMatcher);
return RequestMappingInfo.paths(paths).methods(methods).params(params).headers(headers).consumes(consumes).produces(produces).mappingName(name).options(configuration).build();
}
19
View Source File : ServiceMatcher.java
License : Apache License 2.0
Project Creator : osswangxining
License : Apache License 2.0
Project Creator : osswangxining
/**
* @author Spencer Gibb
*/
public clreplaced ServiceMatcher implements ApplicationContextAware {
private ApplicationContext context;
private PathMatcher matcher;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
public void setMatcher(PathMatcher matcher) {
this.matcher = matcher;
}
public boolean isFromSelf(RemoteApplicationEvent event) {
String originService = event.getOriginService();
String serviceId = getServiceId();
return this.matcher.match(originService, serviceId);
}
public boolean isForSelf(RemoteApplicationEvent event) {
String destinationService = event.getDestinationService();
return (destinationService == null || destinationService.trim().isEmpty() || this.matcher.match(destinationService, getServiceId()));
}
public String getServiceId() {
return this.context.getId();
}
}
19
View Source File : ServiceMatcher.java
License : Apache License 2.0
Project Creator : osswangxining
License : Apache License 2.0
Project Creator : osswangxining
public void setMatcher(PathMatcher matcher) {
this.matcher = matcher;
}
19
View Source File : DefaultBusPathMatcher.java
License : Apache License 2.0
Project Creator : osswangxining
License : Apache License 2.0
Project Creator : osswangxining
/**
* {@link BusPathMatcher} that matches application context ids with multiple, comma-separated, profiles.
* Original https://gist.github.com/kelapure/61d3f948acf478cc95225ff1d7d239c4
*
* See https://github.com/spring-cloud/spring-cloud-config/issues/678
*
* @author Rohit Kelapure
* @author Spencer Gibb
*/
public clreplaced DefaultBusPathMatcher implements PathMatcher {
private static final Log log = LogFactory.getLog(DefaultBusPathMatcher.clreplaced);
private final PathMatcher delagateMatcher;
public DefaultBusPathMatcher(PathMatcher delagateMatcher) {
this.delagateMatcher = delagateMatcher;
}
protected boolean matchMultiProfile(String pattern, String applicationContextID) {
log.debug("matchMultiProfile : " + pattern + ", " + applicationContextID);
// parse the application-context-id
String[] appContextIDTokens = tokenizeToStringArray(applicationContextID, ":");
if (appContextIDTokens.length <= 1) {
// no parts, default to delegate which already returned false;
return false;
}
String selfProfiles = appContextIDTokens[1];
// short circuit if possible
String[] profiles = tokenizeToStringArray(selfProfiles, ",");
if (profiles.length == 1) {
// there aren't multiple profiles to check, the delegate match was
// originally false so return what delegate determined
return false;
}
// gather candidate ids with a single profile rather than a comma separated list
String[] idsWithSingleProfile = new String[profiles.length];
for (int i = 0; i < profiles.length; i++) {
// replace comma separated profiles with single profile
String profile = profiles[i];
String[] newTokens = new String[appContextIDTokens.length];
System.arraycopy(appContextIDTokens, 0, newTokens, 0, appContextIDTokens.length);
newTokens[1] = profile;
idsWithSingleProfile[i] = StringUtils.arrayToDelimitedString(newTokens, ":");
}
for (String id : idsWithSingleProfile) {
if (delagateMatcher.match(pattern, id)) {
log.debug("matched true");
return true;
}
}
log.debug("matched false");
return false;
}
@Override
public boolean isPattern(String path) {
return delagateMatcher.isPattern(path);
}
@Override
public boolean match(String pattern, String path) {
log.debug("In match: " + pattern + ", " + path);
if (!delagateMatcher.match(pattern, path)) {
return matchMultiProfile(pattern, path);
}
return true;
}
@Override
public boolean matchStart(String pattern, String path) {
return delagateMatcher.matchStart(pattern, path);
}
@Override
public String extractPathWithinPattern(String pattern, String path) {
return delagateMatcher.extractPathWithinPattern(pattern, path);
}
@Override
public Map<String, String> extractUriTemplateVariables(String pattern, String path) {
return delagateMatcher.extractUriTemplateVariables(pattern, path);
}
@Override
public Comparator<String> getPatternComparator(String path) {
return delagateMatcher.getPatternComparator(path);
}
@Override
public String combine(String pattern1, String pattern2) {
return delagateMatcher.combine(pattern1, pattern2);
}
}
19
View Source File : RequestMappingInfo.java
License : MIT License
Project Creator : OlegNyr
License : MIT License
Project Creator : OlegNyr
/**
* Описание метода обработки
*/
clreplaced RequestMappingInfo {
private final Set<String> patterns;
private final PathMatcher pathMatcher;
private final Set<MessageType> messageTypes;
private RequestMappingInfo(Collection<String> patterns, Collection<MessageType> messageTypes) {
this.patterns = Collections.unmodifiableSet(Sets.newLinkedHashSet(patterns));
this.pathMatcher = new AntPathMatcher();
this.messageTypes = ImmutableSet.copyOf(messageTypes);
}
public static Builder newBuilder() {
return new Builder();
}
public static final clreplaced Builder {
private String[] path;
private MessageType[] messageTypes;
private Builder() {
}
public Builder path(String... val) {
path = val;
return this;
}
public Builder messageType(MessageType... val) {
messageTypes = val;
return this;
}
public RequestMappingInfo build() {
return new RequestMappingInfo(asList(path), asList(messageTypes));
}
}
private static <T> List<T> asList(T... patterns) {
return (patterns != null ? Arrays.asList(patterns) : Collections.emptyList());
}
public RequestMappingInfo getMatchingCondition(String requestText) {
if (this.patterns.isEmpty()) {
return this;
}
if (requestText == null) {
requestText = "";
}
List<String> matches = getMatchingPatterns(requestText);
return matches.isEmpty() ? null : this;
}
public List<String> getMatchingPatterns(String lookupPath) {
List<String> matches = new ArrayList<String>();
for (String pattern : this.patterns) {
String match = getMatchingPattern(pattern, lookupPath);
if (match != null) {
matches.add(match);
}
}
Collections.sort(matches, this.pathMatcher.getPatternComparator(lookupPath));
return matches;
}
private String getMatchingPattern(String pattern, String lookupPath) {
if (pattern.equals(lookupPath)) {
return pattern;
}
if (this.pathMatcher.match(pattern, lookupPath)) {
return pattern;
}
return null;
}
public Set<String> getPatterns() {
return patterns;
}
public PathMatcher getPathMatcher() {
return pathMatcher;
}
public Set<MessageType> getMessageTypes() {
return messageTypes;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof RequestMappingInfo))
return false;
RequestMappingInfo that = (RequestMappingInfo) o;
return Objects.equals(patterns, that.patterns) && Objects.equals(messageTypes, that.messageTypes);
}
@Override
public int hashCode() {
return Objects.hash(patterns, messageTypes);
}
}
19
View Source File : UrlFilenameViewControllerTests.java
License : MIT License
Project Creator : mindcarver
License : MIT License
Project Creator : mindcarver
/**
* @author Juergen Hoeller
* @author Rick Evans
* @since 14.09.2005
*/
public clreplaced UrlFilenameViewControllerTests {
private PathMatcher pathMatcher = new AntPathMatcher();
@Test
public void withPlainFilename() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withFilenamePlusExtension() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withFilenameAndMatrixVariables() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index;a=A;b=B");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withPrefixAndSuffix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix("mypre_");
ctrl.setSuffix("_mysuf");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("mypre_index_mysuf", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withPrefix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix("mypre_");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("mypre_index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withSuffix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setSuffix("_mysuf");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index_mysuf", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void multiLevel() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("docs/cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void multiLevelWithMapping() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
exposePathInMapping(request, "/docs/**");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void multiLevelMappingWithFallback() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
exposePathInMapping(request, "/docs/cvs/commit.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("docs/cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withContextMapping() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/docs/cvs/commit.html");
request.setContextPath("/myapp");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("docs/cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void settingPrefixToNullCausesEmptyStringToBeUsed() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix(null);
replacedertNotNull("For setPrefix(..) with null, the empty string must be used instead.", ctrl.getPrefix());
replacedertEquals("For setPrefix(..) with null, the empty string must be used instead.", "", ctrl.getPrefix());
}
@Test
public void settingSuffixToNullCausesEmptyStringToBeUsed() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setSuffix(null);
replacedertNotNull("For setPrefix(..) with null, the empty string must be used instead.", ctrl.getSuffix());
replacedertEquals("For setPrefix(..) with null, the empty string must be used instead.", "", ctrl.getSuffix());
}
/**
* This is the expected behavior, and it now has a test to prove it.
* http://opensource.atlreplacedian.com/projects/spring/browse/SPR-2789
*/
@Test
public void nestedPathisUsedAsViewName_InBreakingChangeFromSpring12Line() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/products/view.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("products/view", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withFlashAttributes() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
request.setAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE, new ModelMap("name", "value"));
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertEquals(1, mv.getModel().size());
replacedertEquals("value", mv.getModel().get("name"));
}
private void exposePathInMapping(MockHttpServletRequest request, String mapping) {
String pathInMapping = this.pathMatcher.extractPathWithinPattern(mapping, request.getRequestURI());
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathInMapping);
}
}
19
View Source File : ResourceUrlProvider.java
License : MIT License
Project Creator : mindcarver
License : MIT License
Project Creator : mindcarver
/**
* A central component to use to obtain the public URL path that clients should
* use to access a static resource.
*
* <p>This clreplaced is aware of Spring MVC handler mappings used to serve static
* resources and uses the {@code ResourceResolver} chains of the configured
* {@code ResourceHttpRequestHandler}s to make its decisions.
*
* @author Rossen Stoyanchev
* @since 4.1
*/
public clreplaced ResourceUrlProvider implements ApplicationListener<ContextRefreshedEvent> {
protected final Log logger = LogFactory.getLog(getClreplaced());
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private final Map<String, ResourceHttpRequestHandler> handlerMap = new LinkedHashMap<>();
private boolean autodetect = true;
/**
* Configure a {@code UrlPathHelper} to use in
* {@link #getForRequestUrl(javax.servlet.http.HttpServletRequest, String)}
* in order to derive the lookup path for a target request URL path.
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
this.urlPathHelper = urlPathHelper;
}
/**
* Return the configured {@code UrlPathHelper}.
* @since 4.2.8
*/
public UrlPathHelper getUrlPathHelper() {
return this.urlPathHelper;
}
/**
* Configure a {@code PathMatcher} to use when comparing target lookup path
* against resource mappings.
*/
public void setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
/**
* Return the configured {@code PathMatcher}.
*/
public PathMatcher getPathMatcher() {
return this.pathMatcher;
}
/**
* Manually configure the resource mappings.
* <p><strong>Note:</strong> by default resource mappings are auto-detected
* from the Spring {@code ApplicationContext}. However if this property is
* used, the auto-detection is turned off.
*/
public void setHandlerMap(@Nullable Map<String, ResourceHttpRequestHandler> handlerMap) {
if (handlerMap != null) {
this.handlerMap.clear();
this.handlerMap.putAll(handlerMap);
this.autodetect = false;
}
}
/**
* Return the resource mappings, either manually configured or auto-detected
* when the Spring {@code ApplicationContext} is refreshed.
*/
public Map<String, ResourceHttpRequestHandler> getHandlerMap() {
return this.handlerMap;
}
/**
* Return {@code false} if resource mappings were manually configured,
* {@code true} otherwise.
*/
public boolean isAutodetect() {
return this.autodetect;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (isAutodetect()) {
this.handlerMap.clear();
detectResourceHandlers(event.getApplicationContext());
if (!this.handlerMap.isEmpty()) {
this.autodetect = false;
}
}
}
protected void detectResourceHandlers(ApplicationContext appContext) {
Map<String, SimpleUrlHandlerMapping> beans = appContext.getBeansOfType(SimpleUrlHandlerMapping.clreplaced);
List<SimpleUrlHandlerMapping> mappings = new ArrayList<>(beans.values());
AnnotationAwareOrderComparator.sort(mappings);
for (SimpleUrlHandlerMapping mapping : mappings) {
for (String pattern : mapping.getHandlerMap().keySet()) {
Object handler = mapping.getHandlerMap().get(pattern);
if (handler instanceof ResourceHttpRequestHandler) {
ResourceHttpRequestHandler resourceHandler = (ResourceHttpRequestHandler) handler;
this.handlerMap.put(pattern, resourceHandler);
}
}
}
if (this.handlerMap.isEmpty()) {
logger.trace("No resource handling mappings found");
}
}
/**
* A variation on {@link #getForLookupPath(String)} that accepts a full request
* URL path (i.e. including context and servlet path) and returns the full request
* URL path to expose for public use.
* @param request the current request
* @param requestUrl the request URL path to resolve
* @return the resolved public URL path, or {@code null} if unresolved
*/
@Nullable
public final String getForRequestUrl(HttpServletRequest request, String requestUrl) {
int prefixIndex = getLookupPathIndex(request);
int suffixIndex = getEndPathIndex(requestUrl);
if (prefixIndex >= suffixIndex) {
return null;
}
String prefix = requestUrl.substring(0, prefixIndex);
String suffix = requestUrl.substring(suffixIndex);
String lookupPath = requestUrl.substring(prefixIndex, suffixIndex);
String resolvedLookupPath = getForLookupPath(lookupPath);
return (resolvedLookupPath != null ? prefix + resolvedLookupPath + suffix : null);
}
private int getLookupPathIndex(HttpServletRequest request) {
UrlPathHelper pathHelper = getUrlPathHelper();
String requestUri = pathHelper.getRequestUri(request);
String lookupPath = pathHelper.getLookupPathForRequest(request);
return requestUri.indexOf(lookupPath);
}
private int getEndPathIndex(String lookupPath) {
int suffixIndex = lookupPath.length();
int queryIndex = lookupPath.indexOf('?');
if (queryIndex > 0) {
suffixIndex = queryIndex;
}
int hashIndex = lookupPath.indexOf('#');
if (hashIndex > 0) {
suffixIndex = Math.min(suffixIndex, hashIndex);
}
return suffixIndex;
}
/**
* Compare the given path against configured resource handler mappings and
* if a match is found use the {@code ResourceResolver} chain of the matched
* {@code ResourceHttpRequestHandler} to resolve the URL path to expose for
* public use.
* <p>It is expected that the given path is what Spring MVC would use for
* request mapping purposes, i.e. excluding context and servlet path portions.
* <p>If several handler mappings match, the handler used will be the one
* configured with the most specific pattern.
* @param lookupPath the lookup path to check
* @return the resolved public URL path, or {@code null} if unresolved
*/
@Nullable
public final String getForLookupPath(String lookupPath) {
// Clean duplicate slashes or pathWithinPattern won't match lookupPath
String previous;
do {
previous = lookupPath;
lookupPath = StringUtils.replace(lookupPath, "//", "/");
} while (!lookupPath.equals(previous));
List<String> matchingPatterns = new ArrayList<>();
for (String pattern : this.handlerMap.keySet()) {
if (getPathMatcher().match(pattern, lookupPath)) {
matchingPatterns.add(pattern);
}
}
if (!matchingPatterns.isEmpty()) {
Comparator<String> patternComparator = getPathMatcher().getPatternComparator(lookupPath);
matchingPatterns.sort(patternComparator);
for (String pattern : matchingPatterns) {
String pathWithinMapping = getPathMatcher().extractPathWithinPattern(pattern, lookupPath);
String pathMapping = lookupPath.substring(0, lookupPath.indexOf(pathWithinMapping));
ResourceHttpRequestHandler handler = this.handlerMap.get(pattern);
ResourceResolverChain chain = new DefaultResourceResolverChain(handler.getResourceResolvers());
String resolved = chain.resolveUrlPath(pathWithinMapping, handler.getLocations());
if (resolved == null) {
continue;
}
return pathMapping + resolved;
}
}
if (logger.isTraceEnabled()) {
logger.trace("No match for \"" + lookupPath + "\"");
}
return null;
}
}
19
View Source File : WebContentInterceptor.java
License : MIT License
Project Creator : mindcarver
License : MIT License
Project Creator : mindcarver
/**
* Handler interceptor that checks the request and prepares the response.
* Checks for supported methods and a required session, and applies the
* specified {@link org.springframework.http.CacheControl} builder.
* See superclreplaced bean properties for configuration options.
*
* <p>All the settings supported by this interceptor can also be set on
* {@link AbstractController}. This interceptor is mainly intended for applying
* checks and preparations to a set of controllers mapped by a HandlerMapping.
*
* @author Juergen Hoeller
* @author Brian Clozel
* @since 27.11.2003
* @see AbstractController
*/
public clreplaced WebContentInterceptor extends WebContentGenerator implements HandlerInterceptor {
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private Map<String, Integer> cacheMappings = new HashMap<>();
private Map<String, CacheControl> cacheControlMappings = new HashMap<>();
public WebContentInterceptor() {
// No restriction of HTTP methods by default,
// in particular for use with annotated controllers...
super(false);
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
*/
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
*/
public void setUrlDecode(boolean urlDecode) {
this.urlPathHelper.setUrlDecode(urlDecode);
}
/**
* Set the UrlPathHelper to use for resolution of lookup paths.
* <p>Use this to override the default UrlPathHelper with a custom subclreplaced,
* or to share common UrlPathHelper settings across multiple HandlerMappings
* and MethodNameResolvers.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#setUrlPathHelper
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
replacedert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
}
/**
* Map specific URL paths to specific cache seconds.
* <p>Overrides the default cache seconds setting of this interceptor.
* Can specify "-1" to exclude a URL path from default caching.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and a various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher javadoc.
* <p><b>NOTE:</b> Path patterns are not supposed to overlap. If a request
* matches several mappings, it is effectively undefined which one will apply
* (due to the lack of key ordering in {@code java.util.Properties}).
* @param cacheMappings a mapping between URL paths (as keys) and
* cache seconds (as values, need to be integer-parsable)
* @see #setCacheSeconds
* @see org.springframework.util.AntPathMatcher
*/
public void setCacheMappings(Properties cacheMappings) {
this.cacheMappings.clear();
Enumeration<?> propNames = cacheMappings.propertyNames();
while (propNames.hasMoreElements()) {
String path = (String) propNames.nextElement();
int cacheSeconds = Integer.parseInt(cacheMappings.getProperty(path));
this.cacheMappings.put(path, cacheSeconds);
}
}
/**
* Map specific URL paths to a specific {@link org.springframework.http.CacheControl}.
* <p>Overrides the default cache seconds setting of this interceptor.
* Can specify a empty {@link org.springframework.http.CacheControl} instance
* to exclude a URL path from default caching.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and a various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher javadoc.
* <p><b>NOTE:</b> Path patterns are not supposed to overlap. If a request
* matches several mappings, it is effectively undefined which one will apply
* (due to the lack of key ordering in the underlying {@code java.util.HashMap}).
* @param cacheControl the {@code CacheControl} to use
* @param paths the URL paths that will map to the given {@code CacheControl}
* @since 4.2
* @see #setCacheSeconds
* @see org.springframework.util.AntPathMatcher
*/
public void addCacheMapping(CacheControl cacheControl, String... paths) {
for (String path : paths) {
this.cacheControlMappings.put(path, cacheControl);
}
}
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns, for determining cache mappings.
* Default is AntPathMatcher.
* @see #addCacheMapping
* @see #setCacheMappings
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException {
checkRequest(request);
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
CacheControl cacheControl = lookupCacheControl(lookupPath);
Integer cacheSeconds = lookupCacheSeconds(lookupPath);
if (cacheControl != null) {
if (logger.isTraceEnabled()) {
logger.trace("Applying " + cacheControl);
}
applyCacheControl(response, cacheControl);
} else if (cacheSeconds != null) {
if (logger.isTraceEnabled()) {
logger.trace("Applying cacheSeconds " + cacheSeconds);
}
applyCacheSeconds(response, cacheSeconds);
} else {
if (logger.isTraceEnabled()) {
logger.trace("Applying default cacheSeconds");
}
prepareResponse(response);
}
return true;
}
/**
* Look up a {@link org.springframework.http.CacheControl} instance for the given URL path.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher clreplaced.
* @param urlPath the URL the bean is mapped to
* @return the replacedociated {@code CacheControl}, or {@code null} if not found
* @see org.springframework.util.AntPathMatcher
*/
@Nullable
protected CacheControl lookupCacheControl(String urlPath) {
// Direct match?
CacheControl cacheControl = this.cacheControlMappings.get(urlPath);
if (cacheControl != null) {
return cacheControl;
}
// Pattern match?
for (String registeredPath : this.cacheControlMappings.keySet()) {
if (this.pathMatcher.match(registeredPath, urlPath)) {
return this.cacheControlMappings.get(registeredPath);
}
}
return null;
}
/**
* Look up a cacheSeconds integer value for the given URL path.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher clreplaced.
* @param urlPath the URL the bean is mapped to
* @return the cacheSeconds integer value, or {@code null} if not found
* @see org.springframework.util.AntPathMatcher
*/
@Nullable
protected Integer lookupCacheSeconds(String urlPath) {
// Direct match?
Integer cacheSeconds = this.cacheMappings.get(urlPath);
if (cacheSeconds != null) {
return cacheSeconds;
}
// Pattern match?
for (String registeredPath : this.cacheMappings.keySet()) {
if (this.pathMatcher.match(registeredPath, urlPath)) {
return this.cacheMappings.get(registeredPath);
}
}
return null;
}
/**
* This implementation is empty.
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
19
View Source File : UrlBasedCorsConfigurationSource.java
License : MIT License
Project Creator : mindcarver
License : MIT License
Project Creator : mindcarver
/**
* Provide a per request {@link CorsConfiguration} instance based on a
* collection of {@link CorsConfiguration} mapped on path patterns.
*
* <p>Exact path mapping URIs (such as {@code "/admin"}) are supported
* as well as Ant-style path patterns (such as {@code "/admin/**"}).
*
* @author Sebastien Deleuze
* @since 4.2
*/
public clreplaced UrlBasedCorsConfigurationSource implements CorsConfigurationSource {
private final Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<>();
private PathMatcher pathMatcher = new AntPathMatcher();
private UrlPathHelper urlPathHelper = new UrlPathHelper();
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns. Default is AntPathMatcher.
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
*/
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
*/
public void setUrlDecode(boolean urlDecode) {
this.urlPathHelper.setUrlDecode(urlDecode);
}
/**
* Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}.
* @see org.springframework.web.util.UrlPathHelper#setRemoveSemicolonContent(boolean)
*/
public void setRemoveSemicolonContent(boolean removeSemicolonContent) {
this.urlPathHelper.setRemoveSemicolonContent(removeSemicolonContent);
}
/**
* Set the UrlPathHelper to use for resolution of lookup paths.
* <p>Use this to override the default UrlPathHelper with a custom subclreplaced.
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
replacedert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
}
/**
* Set CORS configuration based on URL patterns.
*/
public void setCorsConfigurations(@Nullable Map<String, CorsConfiguration> corsConfigurations) {
this.corsConfigurations.clear();
if (corsConfigurations != null) {
this.corsConfigurations.putAll(corsConfigurations);
}
}
/**
* Get the CORS configuration.
*/
public Map<String, CorsConfiguration> getCorsConfigurations() {
return Collections.unmodifiableMap(this.corsConfigurations);
}
/**
* Register a {@link CorsConfiguration} for the specified path pattern.
*/
public void registerCorsConfiguration(String path, CorsConfiguration config) {
this.corsConfigurations.put(path, config);
}
@Override
@Nullable
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
for (Map.Entry<String, CorsConfiguration> entry : this.corsConfigurations.entrySet()) {
if (this.pathMatcher.match(entry.getKey(), lookupPath)) {
return entry.getValue();
}
}
return null;
}
}
19
View Source File : PathMatchInterceptorAdapter.java
License : MIT License
Project Creator : liuxx-u
License : MIT License
Project Creator : liuxx-u
private PathMatcher getPathMatcher() {
PathMatcher pathMatcher;
try {
pathMatcher = SpringContextHolder.getBean(PathMatcher.clreplaced);
} catch (Exception ex) {
pathMatcher = new AntPathMatcher();
}
return pathMatcher;
}
19
View Source File : BasePathMatchInterceptor.java
License : Apache License 2.0
Project Creator : LianjiaTech
License : Apache License 2.0
Project Creator : LianjiaTech
/**
* 路径匹配拦截器, 如果使用spring-bean方式,使用原型模式
*
* @author 陈添明
*/
public abstract clreplaced BasePathMatchInterceptor implements PrototypeInterceptor {
private String[] include;
private String[] exclude;
private PathMatcher pathMatcher = new AntPathMatcher();
public void setInclude(String[] include) {
this.include = include;
}
public void setExclude(String[] exclude) {
this.exclude = exclude;
}
@Override
public final Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String path = request.url().encodedPath();
if (isMatch(exclude, path)) {
return chain.proceed(request);
}
if (!isMatch(include, path)) {
return chain.proceed(request);
}
return doIntercept(chain);
}
/**
* do intercept
*
* @param chain interceptor chain
* @return http Response
* @throws IOException IOException
*/
protected abstract Response doIntercept(Chain chain) throws IOException;
/**
* <p>
* 当前http的url路径是否与指定的patterns匹配
* Whether the current http URL path matches the specified patterns
* </p>
*
* @param patterns the specified patterns
* @param path http URL path
* @return 匹配结果
*/
private boolean isMatch(String[] patterns, String path) {
if (patterns == null || patterns.length == 0) {
return false;
}
for (String pattern : patterns) {
boolean match = pathMatcher.match(pattern, path);
if (match) {
return true;
}
}
return false;
}
}
19
View Source File : UrlFilenameViewControllerTests.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* @author Juergen Hoeller
* @author Rick Evans
* @since 14.09.2005
*/
public clreplaced UrlFilenameViewControllerTests {
private PathMatcher pathMatcher = new AntPathMatcher();
@Test
public void withPlainFilename() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withFilenamePlusExtension() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withFilenameAndMatrixVariables() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index;a=A;b=B");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withPrefixAndSuffix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix("mypre_");
ctrl.setSuffix("_mysuf");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("mypre_index_mysuf", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withPrefix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix("mypre_");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("mypre_index", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withSuffix() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setSuffix("_mysuf");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index_mysuf", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void multiLevel() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("docs/cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void multiLevelWithMapping() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
exposePathInMapping(request, "/docs/**");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void multiLevelMappingWithFallback() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/docs/cvs/commit.html");
exposePathInMapping(request, "/docs/cvs/commit.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("docs/cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withContextMapping() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/docs/cvs/commit.html");
request.setContextPath("/myapp");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("docs/cvs/commit", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void settingPrefixToNullCausesEmptyStringToBeUsed() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setPrefix(null);
replacedertNotNull("When setPrefix(..) is called with a null argument, the empty string value must be used instead.", ctrl.getPrefix());
replacedertEquals("When setPrefix(..) is called with a null argument, the empty string value must be used instead.", "", ctrl.getPrefix());
}
@Test
public void settingSuffixToNullCausesEmptyStringToBeUsed() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
ctrl.setSuffix(null);
replacedertNotNull("When setSuffix(..) is called with a null argument, the empty string value must be used instead.", ctrl.getSuffix());
replacedertEquals("When setSuffix(..) is called with a null argument, the empty string value must be used instead.", "", ctrl.getSuffix());
}
/**
* This is the expected behavior, and it now has a test to prove it.
* http://opensource.atlreplacedian.com/projects/spring/browse/SPR-2789
*/
@Test
public void nestedPathisUsedAsViewName_InBreakingChangeFromSpring12Line() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/products/view.html");
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("products/view", mv.getViewName());
replacedertTrue(mv.getModel().isEmpty());
}
@Test
public void withFlashAttributes() throws Exception {
UrlFilenameViewController ctrl = new UrlFilenameViewController();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
request.setAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE, new ModelMap("name", "value"));
MockHttpServletResponse response = new MockHttpServletResponse();
ModelAndView mv = ctrl.handleRequest(request, response);
replacedertEquals("index", mv.getViewName());
replacedertEquals(1, mv.getModel().size());
replacedertEquals("value", mv.getModel().get("name"));
}
private void exposePathInMapping(MockHttpServletRequest request, String mapping) {
String pathInMapping = this.pathMatcher.extractPathWithinPattern(mapping, request.getRequestURI());
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathInMapping);
}
}
19
View Source File : ResourceServlet.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Simple servlet that can expose an internal resource, including a
* default URL if the specified resource is not found. An alternative,
* for example, to trying and catching exceptions when using JSP include.
*
* <p>A further usage of this servlet is the ability to apply last-modified
* timestamps to quasi-static resources (typically JSPs). This can happen
* as bridge to parameter-specified resources, or as proxy for a specific
* target resource (or a list of specific target resources to combine).
*
* <p>A typical usage would map a URL like "/ResourceServlet" onto an instance
* of this servlet, and use the "JSP include" action to include this URL,
* with the "resource" parameter indicating the actual target path in the WAR.
*
* <p>The {@code defaultUrl} property can be set to the internal
* resource path of a default URL, to be rendered when the target resource
* is not found or not specified in the first place.
*
* <p>The "resource" parameter and the {@code defaultUrl} property can
* also specify a list of target resources to combine. Those resources will be
* included one by one to build the response. If last-modified determination
* is active, the newest timestamp among those files will be used.
*
* <p>The {@code allowedResources} property can be set to a URL
* pattern of resources that should be available via this servlet.
* If not set, any target resource can be requested, including resources
* in the WEB-INF directory!
*
* <p>If using this servlet for direct access rather than via includes,
* the {@code contentType} property should be specified to apply a
* proper content type. Note that a content type header in the target JSP will
* be ignored when including the resource via a RequestDispatcher include.
*
* <p>To apply last-modified timestamps for the target resource, set the
* {@code applyLastModified} property to true. This servlet will then
* return the file timestamp of the target resource as last-modified value,
* falling back to the startup time of this servlet if not retrievable.
*
* <p>Note that applying the last-modified timestamp in the above fashion
* just makes sense if the target resource does not generate content that
* depends on the HttpSession or cookies; it is just allowed to evaluate
* request parameters.
*
* <p>A typical case for such last-modified usage is a JSP that just makes
* minimal usage of basic means like includes or message resolution to
* build quasi-static content. Regenerating such content on every request
* is unnecessary; it can be cached as long as the file hasn't changed.
*
* <p>Note that this servlet will apply the last-modified timestamp if you
* tell it to do so: It's your decision whether the content of the target
* resource can be cached in such a fashion. Typical use cases are helper
* resources that are not fronted by a controller, like JavaScript files
* that are generated by a JSP (without depending on the HttpSession).
*
* @author Juergen Hoeller
* @author Rod Johnson
* @see #setDefaultUrl
* @see #setAllowedResources
* @see #setApplyLastModified
*/
@SuppressWarnings("serial")
public clreplaced ResourceServlet extends HttpServletBean {
/**
* Any number of these characters are considered delimiters
* between multiple resource paths in a single String value.
*/
public static final String RESOURCE_URL_DELIMITERS = ",; \t\n";
/**
* Name of the parameter that must contain the actual resource path.
*/
public static final String RESOURCE_PARAM_NAME = "resource";
private String defaultUrl;
private String allowedResources;
private String contentType;
private boolean applyLastModified = false;
private PathMatcher pathMatcher;
private long startupTime;
/**
* Set the URL within the current web application from which to
* include content if the requested path isn't found, or if none
* is specified in the first place.
* <p>If specifying multiple URLs, they will be included one by one
* to build the response. If last-modified determination is active,
* the newest timestamp among those files will be used.
* @see #setApplyLastModified
*/
public void setDefaultUrl(String defaultUrl) {
this.defaultUrl = defaultUrl;
}
/**
* Set allowed resources as URL pattern, e.g. "/WEB-INF/res/*.jsp",
* The parameter can be any Ant-style pattern parsable by AntPathMatcher.
* @see org.springframework.util.AntPathMatcher
*/
public void setAllowedResources(String allowedResources) {
this.allowedResources = allowedResources;
}
/**
* Set the content type of the target resource (typically a JSP).
* Default is none, which is appropriate when including resources.
* <p>For directly accessing resources, for example to leverage this
* servlet's last-modified support, specify a content type here.
* Note that a content type header in the target JSP will be ignored
* when including the resource via a RequestDispatcher include.
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* Set whether to apply the file timestamp of the target resource
* as last-modified value. Default is "false".
* <p>This is mainly intended for JSP targets that don't generate
* session-specific or database-driven content: Such files can be
* cached by the browser as long as the last-modified timestamp
* of the JSP file doesn't change.
* <p>This will only work correctly with expanded WAR files that
* allow access to the file timestamps. Else, the startup time
* of this servlet is returned.
*/
public void setApplyLastModified(boolean applyLastModified) {
this.applyLastModified = applyLastModified;
}
/**
* Remember the startup time, using no last-modified time before it.
*/
@Override
protected void initServletBean() {
this.pathMatcher = getPathMatcher();
this.startupTime = System.currentTimeMillis();
}
/**
* Return a PathMatcher to use for matching the "allowedResources" URL pattern.
* Default is AntPathMatcher.
* @see #setAllowedResources
* @see org.springframework.util.AntPathMatcher
*/
protected PathMatcher getPathMatcher() {
return new AntPathMatcher();
}
/**
* Determine the URL of the target resource and include it.
* @see #determineResourceUrl
*/
@Override
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// determine URL of resource to include
String resourceUrl = determineResourceUrl(request);
if (resourceUrl != null) {
try {
doInclude(request, response, resourceUrl);
} catch (ServletException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to include content of resource [" + resourceUrl + "]", ex);
}
// Try including default URL if appropriate.
if (!includeDefaultUrl(request, response)) {
throw ex;
}
} catch (IOException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to include content of resource [" + resourceUrl + "]", ex);
}
// Try including default URL if appropriate.
if (!includeDefaultUrl(request, response)) {
throw ex;
}
}
} else // no resource URL specified -> try to include default URL.
if (!includeDefaultUrl(request, response)) {
throw new ServletException("No target resource URL found for request");
}
}
/**
* Determine the URL of the target resource of this request.
* <p>Default implementation returns the value of the "resource" parameter.
* Can be overridden in subclreplacedes.
* @param request current HTTP request
* @return the URL of the target resource, or {@code null} if none found
* @see #RESOURCE_PARAM_NAME
*/
protected String determineResourceUrl(HttpServletRequest request) {
return request.getParameter(RESOURCE_PARAM_NAME);
}
/**
* Include the specified default URL, if appropriate.
* @param request current HTTP request
* @param response current HTTP response
* @return whether a default URL was included
* @throws ServletException if thrown by the RequestDispatcher
* @throws IOException if thrown by the RequestDispatcher
*/
private boolean includeDefaultUrl(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (this.defaultUrl == null) {
return false;
}
doInclude(request, response, this.defaultUrl);
return true;
}
/**
* Include the specified resource via the RequestDispatcher.
* @param request current HTTP request
* @param response current HTTP response
* @param resourceUrl the URL of the target resource
* @throws ServletException if thrown by the RequestDispatcher
* @throws IOException if thrown by the RequestDispatcher
*/
private void doInclude(HttpServletRequest request, HttpServletResponse response, String resourceUrl) throws ServletException, IOException {
if (this.contentType != null) {
response.setContentType(this.contentType);
}
String[] resourceUrls = StringUtils.tokenizeToStringArray(resourceUrl, RESOURCE_URL_DELIMITERS);
for (int i = 0; i < resourceUrls.length; i++) {
// check whether URL matches allowed resources
if (this.allowedResources != null && !this.pathMatcher.match(this.allowedResources, resourceUrls[i])) {
throw new ServletException("Resource [" + resourceUrls[i] + "] does not match allowed pattern [" + this.allowedResources + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Including resource [" + resourceUrls[i] + "]");
}
RequestDispatcher rd = request.getRequestDispatcher(resourceUrls[i]);
rd.include(request, response);
}
}
/**
* Return the last-modified timestamp of the file that corresponds
* to the target resource URL (i.e. typically the request ".jsp" file).
* Will simply return -1 if "applyLastModified" is false (the default).
* <p>Returns no last-modified date before the startup time of this servlet,
* to allow for message resolution etc that influences JSP contents,
* replaceduming that those background resources might have changed on restart.
* <p>Returns the startup time of this servlet if the file that corresponds
* to the target resource URL couldn't be resolved (for example, because
* the WAR is not expanded).
* @see #determineResourceUrl
* @see #getFileTimestamp
*/
@Override
protected final long getLastModified(HttpServletRequest request) {
if (this.applyLastModified) {
String resourceUrl = determineResourceUrl(request);
if (resourceUrl == null) {
resourceUrl = this.defaultUrl;
}
if (resourceUrl != null) {
String[] resourceUrls = StringUtils.tokenizeToStringArray(resourceUrl, RESOURCE_URL_DELIMITERS);
long latestTimestamp = -1;
for (int i = 0; i < resourceUrls.length; i++) {
long timestamp = getFileTimestamp(resourceUrls[i]);
if (timestamp > latestTimestamp) {
latestTimestamp = timestamp;
}
}
return (latestTimestamp > this.startupTime ? latestTimestamp : this.startupTime);
}
}
return -1;
}
/**
* Return the file timestamp for the given resource.
* @param resourceUrl the URL of the resource
* @return the file timestamp in milliseconds, or -1 if not determinable
*/
protected long getFileTimestamp(String resourceUrl) {
ServletContextResource resource = new ServletContextResource(getServletContext(), resourceUrl);
try {
long lastModifiedTime = resource.lastModified();
if (logger.isDebugEnabled()) {
logger.debug("Last-modified timestamp of " + resource + " is " + lastModifiedTime);
}
return lastModifiedTime;
} catch (IOException ex) {
logger.warn("Couldn't retrieve last-modified timestamp of [" + resource + "] - using ResourceServlet startup time");
return -1;
}
}
}
19
View Source File : ResourceUrlProvider.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* A central component to use to obtain the public URL path that clients should
* use to access a static resource.
*
* <p>This clreplaced is aware of Spring MVC handler mappings used to serve static
* resources and uses the {@code ResourceResolver} chains of the configured
* {@code ResourceHttpRequestHandler}s to make its decisions.
*
* @author Rossen Stoyanchev
* @since 4.1
*/
public clreplaced ResourceUrlProvider implements ApplicationListener<ContextRefreshedEvent> {
protected final Log logger = LogFactory.getLog(getClreplaced());
private UrlPathHelper pathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private final Map<String, ResourceHttpRequestHandler> handlerMap = new LinkedHashMap<String, ResourceHttpRequestHandler>();
private boolean autodetect = true;
/**
* Configure a {@code UrlPathHelper} to use in
* {@link #getForRequestUrl(javax.servlet.http.HttpServletRequest, String)}
* in order to derive the lookup path for a target request URL path.
*/
public void setUrlPathHelper(UrlPathHelper pathHelper) {
this.pathHelper = pathHelper;
}
/**
* Return the configured {@code UrlPathHelper}.
*/
public UrlPathHelper getPathHelper() {
return this.pathHelper;
}
/**
* Configure a {@code PathMatcher} to use when comparing target lookup path
* against resource mappings.
*/
public void setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
/**
* Return the configured {@code PathMatcher}.
*/
public PathMatcher getPathMatcher() {
return this.pathMatcher;
}
/**
* Manually configure the resource mappings.
* <p><strong>Note:</strong> by default resource mappings are auto-detected
* from the Spring {@code ApplicationContext}. However if this property is
* used, the auto-detection is turned off.
*/
public void setHandlerMap(Map<String, ResourceHttpRequestHandler> handlerMap) {
if (handlerMap != null) {
this.handlerMap.clear();
this.handlerMap.putAll(handlerMap);
this.autodetect = false;
}
}
/**
* Return the resource mappings, either manually configured or auto-detected
* when the Spring {@code ApplicationContext} is refreshed.
*/
public Map<String, ResourceHttpRequestHandler> getHandlerMap() {
return this.handlerMap;
}
/**
* Return {@code false} if resource mappings were manually configured,
* {@code true} otherwise.
*/
public boolean isAutodetect() {
return this.autodetect;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (isAutodetect()) {
this.handlerMap.clear();
detectResourceHandlers(event.getApplicationContext());
if (this.handlerMap.isEmpty() && logger.isDebugEnabled()) {
logger.debug("No resource handling mappings found");
}
if (!this.handlerMap.isEmpty()) {
this.autodetect = false;
}
}
}
protected void detectResourceHandlers(ApplicationContext appContext) {
logger.debug("Looking for resource handler mappings");
Map<String, SimpleUrlHandlerMapping> map = appContext.getBeansOfType(SimpleUrlHandlerMapping.clreplaced);
List<SimpleUrlHandlerMapping> handlerMappings = new ArrayList<SimpleUrlHandlerMapping>(map.values());
AnnotationAwareOrderComparator.sort(handlerMappings);
for (SimpleUrlHandlerMapping hm : handlerMappings) {
for (String pattern : hm.getHandlerMap().keySet()) {
Object handler = hm.getHandlerMap().get(pattern);
if (handler instanceof ResourceHttpRequestHandler) {
ResourceHttpRequestHandler resourceHandler = (ResourceHttpRequestHandler) handler;
if (logger.isDebugEnabled()) {
logger.debug("Found resource handler mapping: URL pattern=\"" + pattern + "\", " + "locations=" + resourceHandler.getLocations() + ", " + "resolvers=" + resourceHandler.getResourceResolvers());
}
this.handlerMap.put(pattern, resourceHandler);
}
}
}
}
/**
* A variation on {@link #getForLookupPath(String)} that accepts a full request
* URL path (i.e. including context and servlet path) and returns the full request
* URL path to expose for public use.
* @param request the current request
* @param requestUrl the request URL path to resolve
* @return the resolved public URL path, or {@code null} if unresolved
*/
public final String getForRequestUrl(HttpServletRequest request, String requestUrl) {
if (logger.isTraceEnabled()) {
logger.trace("Getting resource URL for request URL \"" + requestUrl + "\"");
}
int prefixIndex = getLookupPathIndex(request);
int suffixIndex = getQueryParamsIndex(requestUrl);
String prefix = requestUrl.substring(0, prefixIndex);
String suffix = requestUrl.substring(suffixIndex);
String lookupPath = requestUrl.substring(prefixIndex, suffixIndex);
String resolvedLookupPath = getForLookupPath(lookupPath);
return (resolvedLookupPath != null ? prefix + resolvedLookupPath + suffix : null);
}
private int getLookupPathIndex(HttpServletRequest request) {
String requestUri = getPathHelper().getRequestUri(request);
String lookupPath = getPathHelper().getLookupPathForRequest(request);
return requestUri.indexOf(lookupPath);
}
private int getQueryParamsIndex(String lookupPath) {
int index = lookupPath.indexOf("?");
return index > 0 ? index : lookupPath.length();
}
/**
* Compare the given path against configured resource handler mappings and
* if a match is found use the {@code ResourceResolver} chain of the matched
* {@code ResourceHttpRequestHandler} to resolve the URL path to expose for
* public use.
* <p>It is expected that the given path is what Spring MVC would use for
* request mapping purposes, i.e. excluding context and servlet path portions.
* <p>If several handler mappings match, the handler used will be the one
* configured with the most specific pattern.
* @param lookupPath the lookup path to check
* @return the resolved public URL path, or {@code null} if unresolved
*/
public final String getForLookupPath(String lookupPath) {
if (logger.isTraceEnabled()) {
logger.trace("Getting resource URL for lookup path \"" + lookupPath + "\"");
}
List<String> matchingPatterns = new ArrayList<String>();
for (String pattern : this.handlerMap.keySet()) {
if (getPathMatcher().match(pattern, lookupPath)) {
matchingPatterns.add(pattern);
}
}
if (!matchingPatterns.isEmpty()) {
Comparator<String> patternComparator = getPathMatcher().getPatternComparator(lookupPath);
Collections.sort(matchingPatterns, patternComparator);
for (String pattern : matchingPatterns) {
String pathWithinMapping = getPathMatcher().extractPathWithinPattern(pattern, lookupPath);
String pathMapping = lookupPath.substring(0, lookupPath.indexOf(pathWithinMapping));
if (logger.isTraceEnabled()) {
logger.trace("Invoking ResourceResolverChain for URL pattern \"" + pattern + "\"");
}
ResourceHttpRequestHandler handler = this.handlerMap.get(pattern);
ResourceResolverChain chain = new DefaultResourceResolverChain(handler.getResourceResolvers());
String resolved = chain.resolveUrlPath(pathWithinMapping, handler.getLocations());
if (resolved == null) {
continue;
}
if (logger.isTraceEnabled()) {
logger.trace("Resolved public resource URL path \"" + resolved + "\"");
}
return pathMapping + resolved;
}
}
if (logger.isDebugEnabled()) {
logger.debug("No matching resource mapping for lookup path \"" + lookupPath + "\"");
}
return null;
}
}
19
View Source File : WebContentInterceptor.java
License : Apache License 2.0
Project Creator : langtianya
License : Apache License 2.0
Project Creator : langtianya
/**
* Handler interceptor that checks the request and prepares the response.
* Checks for supported methods and a required session, and applies the
* specified {@link org.springframework.http.CacheControl} builder.
* See superclreplaced bean properties for configuration options.
*
* <p>All the settings supported by this interceptor can also be set on
* {@link AbstractController}. This interceptor is mainly intended for applying
* checks and preparations to a set of controllers mapped by a HandlerMapping.
*
* @author Juergen Hoeller
* @author Brian Clozel
* @since 27.11.2003
* @see AbstractController
*/
public clreplaced WebContentInterceptor extends WebContentGenerator implements HandlerInterceptor {
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private Map<String, Integer> cacheMappings = new HashMap<String, Integer>();
private Map<String, CacheControl> cacheControlMappings = new HashMap<String, CacheControl>();
public WebContentInterceptor() {
// No restriction of HTTP methods by default,
// in particular for use with annotated controllers...
super(false);
}
/**
* Set if URL lookup should always use full path within current servlet
* context. Else, the path within the current servlet mapping is used
* if applicable (i.e. in the case of a ".../*" servlet mapping in web.xml).
* Default is "false".
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
*/
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
}
/**
* Set if context path and request URI should be URL-decoded.
* Both are returned <i>undecoded</i> by the Servlet API,
* in contrast to the servlet path.
* <p>Uses either the request encoding or the default encoding according
* to the Servlet spec (ISO-8859-1).
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
*/
public void setUrlDecode(boolean urlDecode) {
this.urlPathHelper.setUrlDecode(urlDecode);
}
/**
* Set the UrlPathHelper to use for resolution of lookup paths.
* <p>Use this to override the default UrlPathHelper with a custom subclreplaced,
* or to share common UrlPathHelper settings across multiple HandlerMappings
* and MethodNameResolvers.
* <p>Only relevant for the "cacheMappings" setting.
* @see #setCacheMappings
* @see org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#setUrlPathHelper
* @see org.springframework.web.servlet.mvc.multiaction.AbstractUrlMethodNameResolver#setUrlPathHelper
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
replacedert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
}
/**
* Map specific URL paths to specific cache seconds.
* <p>Overrides the default cache seconds setting of this interceptor.
* Can specify "-1" to exclude a URL path from default caching.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and a various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher javadoc.
* @param cacheMappings a mapping between URL paths (as keys) and
* cache seconds (as values, need to be integer-parsable)
* @see #setCacheSeconds
* @see org.springframework.util.AntPathMatcher
*/
public void setCacheMappings(Properties cacheMappings) {
this.cacheMappings.clear();
Enumeration<?> propNames = cacheMappings.propertyNames();
while (propNames.hasMoreElements()) {
String path = (String) propNames.nextElement();
int cacheSeconds = Integer.valueOf(cacheMappings.getProperty(path));
this.cacheMappings.put(path, cacheSeconds);
}
}
/**
* Map specific URL paths to a specific {@link org.springframework.http.CacheControl}.
* <p>Overrides the default cache seconds setting of this interceptor.
* Can specify a empty {@link org.springframework.http.CacheControl} instance
* to exclude a URL path from default caching.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and a various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher javadoc.
* @param cacheControl the {@code CacheControl} to use
* @param paths URL paths that will map to the given {@code CacheControl}
* @see #setCacheSeconds
* @see org.springframework.util.AntPathMatcher
* @since 4.2
*/
public void addCacheMapping(CacheControl cacheControl, String... paths) {
for (String path : paths) {
this.cacheControlMappings.put(path, cacheControl);
}
}
/**
* Set the PathMatcher implementation to use for matching URL paths
* against registered URL patterns, for determining cache mappings.
* Default is AntPathMatcher.
* @see #addCacheMapping
* @see #setCacheMappings
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
replacedert.notNull(pathMatcher, "PathMatcher must not be null");
this.pathMatcher = pathMatcher;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException {
checkRequest(request);
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
if (logger.isDebugEnabled()) {
logger.debug("Looking up cache seconds for [" + lookupPath + "]");
}
CacheControl cacheControl = lookupCacheControl(lookupPath);
Integer cacheSeconds = lookupCacheSeconds(lookupPath);
if (cacheControl != null) {
if (logger.isDebugEnabled()) {
logger.debug("Applying CacheControl to [" + lookupPath + "]");
}
applyCacheControl(response, cacheControl);
} else if (cacheSeconds != null) {
if (logger.isDebugEnabled()) {
logger.debug("Applying CacheControl to [" + lookupPath + "]");
}
applyCacheSeconds(response, cacheSeconds);
} else {
if (logger.isDebugEnabled()) {
logger.debug("Applying default cache seconds to [" + lookupPath + "]");
}
prepareResponse(response);
}
return true;
}
/**
* Look up a {@link org.springframework.http.CacheControl} instance for the given URL path.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher clreplaced.
* @param urlPath URL the bean is mapped to
* @return the replacedociated {@code CacheControl}, or {@code null} if not found
* @see org.springframework.util.AntPathMatcher
*/
protected CacheControl lookupCacheControl(String urlPath) {
// Direct match?
CacheControl cacheControl = this.cacheControlMappings.get(urlPath);
if (cacheControl == null) {
// Pattern match?
for (String registeredPath : this.cacheControlMappings.keySet()) {
if (this.pathMatcher.match(registeredPath, urlPath)) {
cacheControl = this.cacheControlMappings.get(registeredPath);
}
}
}
return cacheControl;
}
/**
* Look up a cacheSeconds integer value for the given URL path.
* <p>Supports direct matches, e.g. a registered "/test" matches "/test",
* and various Ant-style pattern matches, e.g. a registered "/t*" matches
* both "/test" and "/team". For details, see the AntPathMatcher clreplaced.
* @param urlPath URL the bean is mapped to
* @return the cacheSeconds integer value, or {@code null} if not found
* @see org.springframework.util.AntPathMatcher
*/
protected Integer lookupCacheSeconds(String urlPath) {
// Direct match?
Integer cacheSeconds = this.cacheMappings.get(urlPath);
if (cacheSeconds == null) {
// Pattern match?
for (String registeredPath : this.cacheMappings.keySet()) {
if (this.pathMatcher.match(registeredPath, urlPath)) {
cacheSeconds = this.cacheMappings.get(registeredPath);
}
}
}
return cacheSeconds;
}
/**
* This implementation is empty.
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
See More Examples