一尘不染

尝试创建“文件名”部分带有多个点的REST-ful URL-Spring 3.0 MVC

spring

我正在将Spring MVC(3.0)与注释驱动的控制器一起使用。我想为资源创建REST-FUL网址,而且能够不要求(但仍可选允许)的URL的末尾文件扩展名(但如果没有扩展假设HTML内容类型)。只要文件名部分中没有点(句点/句号),它就可以与Spring MVC一起使用。

但是,我的某些URL要求名称中带有点的标识符。例如:

http://company.com/widgets/123.456.789.500

在这种情况下,Spring寻找扩展的内容类型,但.500没有找到错误。我可以使用诸如添加.html到末尾,对标识符进行编码或添加斜杠之类的变通方法。我对这些都不满意,但可能会加入.html。

我一直未找到在Spring中覆盖默认文件扩展名检测的方法。

是否可以针对给定的控制器方法或URL模式等自定义或禁用文件扩展名检测?


阅读 390

收藏
2020-04-18

共2个答案

一尘不染

@PathVariable模式匹配是有点不稳定,当涉及到的URL点(见SPR-5778)。你可以把它少抖动(但更挑剔),并获得过点沉重的URL更好的控制,通过设置useDefaultSuffixPattern的属性DefaultAnnotationHandlerMappingfalse

如果尚未DefaultAnnotationHandlerMapping在上下文中显式声明a (并且大多数人没有为你隐式声明它),则可以显式添加它并设置该属性。

2020-04-18
一尘不染

我只是想探索Spring @MVC的可扩展性。这是定制的PathMatcher。它$在模式中用作结束标记-如果模式以其结尾,则标记会被删除,并且模式将由默认匹配器进行匹配,但是如果模式$在中间(例如...$.*),则该模式将不匹配。

public class CustomPathMatcher implements PathMatcher {
    private PathMatcher target;

    public CustomPathMatcher() {
        target = new AntPathMatcher();
    }

    public String combine(String pattern1, String pattern2) {
        return target.combine(pattern1, pattern2); 
    }

    public String extractPathWithinPattern(String pattern, String path) {
        if (isEncoded(pattern)) {
            pattern = resolvePattern(pattern);
            if (pattern == null) return "";
        }
        return target.extractPathWithinPattern(pattern, path);
    }

    public Map<String, String> extractUriTemplateVariables(String pattern,
            String path) {
        if (isEncoded(pattern)) {
            pattern = resolvePattern(pattern);
            if (pattern == null) return Collections.emptyMap();
        }
        return target.extractUriTemplateVariables(pattern, path);
    }

    public Comparator<String> getPatternComparator(String pattern) {
        final Comparator<String> targetComparator = target.getPatternComparator(pattern);
        return new Comparator<String>() {
            public int compare(String o1, String o2) {
                if (isEncoded(o1)) {
                    if (isEncoded(o2)) {
                        return 0;
                    } else {
                        return -1;
                    }
                } else if (isEncoded(o2)) {
                    return 1;
                }
                return targetComparator.compare(o1, o2);
            }        
        };
    }

    public boolean isPattern(String pattern) {
        if (isEncoded(pattern)) {
            pattern = resolvePattern(pattern);
            if (pattern == null) return true;
        }
        return target.isPattern(pattern);
    }

    public boolean match(String pattern, String path) {
        if (isEncoded(pattern)) {
            pattern = resolvePattern(pattern);
            if (pattern == null) return false;
        }
        return target.match(pattern, path);
    }

    public boolean matchStart(String pattern, String path) {
        if (isEncoded(pattern)) {
            pattern = resolvePattern(pattern);
            if (pattern == null) return false;
        }
        return target.match(pattern, path);
    }

    private boolean isEncoded(String pattern) {
        return pattern != null && pattern.contains("$");
    }

    private String resolvePattern(String pattern) {
        int i = pattern.indexOf('$');
        if (i < 0) return pattern;
        else if (i == pattern.length() - 1) {
            return pattern.substring(0, i);
        } else {
            String tail = pattern.substring(i + 1);
            if (tail.startsWith(".")) return null;
            else return pattern.substring(0, i) + tail;
        }
    }
}

配置:

<bean id = "pathMatcher" class = "sample.CustomPathMatcher" />

<bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name = "pathMatcher" ref="pathMatcher" />
</bean>

<bean class = "org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name = "pathMatcher" ref="pathMatcher" />
</bean>

和用法(给定为“ /hello/1.2.3” value为“ 1.2.3”):

@RequestMapping(value = "/hello/{value}$", method = RequestMethod.GET)
public String hello(@PathVariable("value") String value, ModelMap model)

编辑::现在不中断“斜杠无关紧要”规则

2020-04-18