记录一次spring url 访问不到的问题

问题

我在修改了程序中的登录请求连接之后,从 /login.do 修改成为了/login,发现我访问登录页面(/login.html)的时候 总会去请求/login

起初,我以为是新加的shiro造成的,因为设置的登录连接就是/login。但是我的/login.html设置的访问权限是anon,不 应该进行拦截啊。

通过网上查找资料,也没找到跟我一样的问题,看来只能靠自己了。

原因

通过对程序进行调试,发现spring在对url链接进行匹配的时候,如果没有直接匹配到对应的@RequestMapping,同时@RequestMapping 对应的url不包含字符.会在url(这里是指@RequestMapping对应的url)后面添加.*进行匹配。所以就悲剧了,/login.html匹配 到了/login.*,就去访问/login对应的Controller,没有去访问对应的页面。

对应的代码是在org.springframework.web.servlet.mvc.condition.PatternsRequestCondition这个类中,这个类是在spring-webmvc-4.3.3.RELEASE.jar 中。

相关的代码如下,在getMatchingPattern方法中进行了匹配的操作:


   /**
     * Checks if any of the patterns match the given request and returns an instance
     * that is guaranteed to contain matching patterns, sorted via
     * {@link PathMatcher#getPatternComparator(String)}.
     * <p>A matching pattern is obtained by making checks in the following order:
     * <ul>
     * <li>Direct match
     * <li>Pattern match with ".*" appended if the pattern doesn't already contain a "."
     * <li>Pattern match
     * <li>Pattern match with "/" appended if the pattern doesn't already end in "/"
     * </ul>
     * @param request the current request
     * @return the same instance if the condition contains no patterns;
     * or a new condition with sorted matching patterns;
     * or {@code null} if no patterns match.
     */
    @Override
    public PatternsRequestCondition getMatchingCondition(HttpServletRequest request) {

        if (this.patterns.isEmpty()) {
            return this;
        }

        String lookupPath = this.pathHelper.getLookupPathForRequest(request);
        List<String> matches = getMatchingPatterns(lookupPath);

        return matches.isEmpty() ? null :
            new PatternsRequestCondition(matches, this.pathHelper, this.pathMatcher, this.useSuffixPatternMatch,
                    this.useTrailingSlashMatch, this.fileExtensions);
    }

    /**
     * Find the patterns matching the given lookup path. Invoking this method should
     * yield results equivalent to those of calling
     * {@link #getMatchingCondition(javax.servlet.http.HttpServletRequest)}.
     * This method is provided as an alternative to be used if no request is available
     * (e.g. introspection, tooling, etc).
     * @param lookupPath the lookup path to match to existing patterns
     * @return a collection of matching patterns sorted with the closest match at the top
     */
    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;
    }
  /**
      *pattern  是使用注解`@RequestMapping`配置的url 比如:@RequestMapping("/login")
      *lookupPath 是请求的url 比如:"/login.html"
      */
    private String getMatchingPattern(String pattern, String lookupPath) {
        if (pattern.equals(lookupPath)) {
            return pattern;
        }
        if (this.useSuffixPatternMatch) {
            if (!this.fileExtensions.isEmpty() && lookupPath.indexOf('.') != -1) {
                for (String extension : this.fileExtensions) {
                    if (this.pathMatcher.match(pattern + extension, lookupPath)) {
                        return pattern + extension;
                    }
                }
            }
            else {
                boolean hasSuffix = pattern.indexOf('.') != -1;
                if (!hasSuffix && this.pathMatcher.match(pattern + ".*", lookupPath)) {
                    return pattern + ".*";
                }
            }
        }
        if (this.pathMatcher.match(pattern, lookupPath)) {
            return pattern;
        }
        if (this.useTrailingSlashMatch) {
            if (!pattern.endsWith("/") && this.pathMatcher.match(pattern + "/", lookupPath)) {
                return pattern +"/";
            }
        }
        return null;
    }

如有问题,欢迎留言交流

猜你喜欢

转载自my.oschina.net/u/2523704/blog/1608708