org.springframework.util.PathMatcher

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 7

19 View Source File : SysBaseApiImpl.java
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

/**
 * 创建 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

/**
 * 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

/**
 * 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

public static void setMvcPathMatcher(PathMatcher mvcPathMatcher) {
    WebContext.mvcPathMatcher = mvcPathMatcher;
}

19 View Source File : MilkomedaContextConfig.java
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

@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

/**
 * @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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

/**
 * 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

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

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

/**
 * @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

public void setPathMatcher(PathMatcher pathMatcher) {
    this.pathMatcher = pathMatcher;
}

19 View Source File : UrlFilenameViewControllerTests.java
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

/**
 * 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

/**
 *  匹配前端传过来的地址 匹配成功返回正则地址
 *  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

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

/**
 * @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

public void setMatcher(PathMatcher matcher) {
    this.matcher = matcher;
}

19 View Source File : DefaultBusPathMatcher.java
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

/**
 * Описание метода обработки
 */
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

/**
 * @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

/**
 * 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

/**
 * 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

/**
 * 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

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

/**
 * 路径匹配拦截器, 如果使用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

/**
 * @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

/**
 * 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

/**
 * 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

/**
 * 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