nic*_*dos 15 java rest spring spring-mvc
我正在使用Spring MVC(3.0)和注释驱动的控制器.我想为资源创建REST-ful URL,并且不能要求(但仍然可选地允许)URL末尾的文件扩展名(但如果没有扩展名,则假定为HTML内容类型).只要文件名部分没有点(句点/句号),这就可以与Spring MVC一起开箱即用.
但是,我的某些网址需要名称中带有点的标识符.像这样:
http://company.com/widgets/123.456.789.500
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Spring会查找扩展的内容类型,.500
并找不到任何错误.我可以使用解决方法,如添加.html
到最后,编码标识符或添加尾部斜杠.我对这些不满意,但可能会加入.html
.
我没有成功地寻找一种覆盖Spring中默认文件扩展名检测的方法.
是否可以为给定的控制器方法或URL模式等自定义或禁用文件扩展名检测?
ska*_*man 12
该@PathVariable
模式匹配是有点颠簸,当涉及到的URL点(见SPR-5778).你可以通过将useDefaultSuffixPattern
属性设置为DefaultAnnotationHandlerMapping
来更轻松(但更挑剔),并通过设置属性来更好地控制点重URL false
.
如果你还没有DefaultAnnotationHandlerMapping
在你的上下文中明确声明a (并且大多数人没有,因为它是为你隐式声明的),那么你可以显式地添加它,并设置该属性.
axt*_*avt 12
可能,这是一个丑陋的黑客,我只是想探索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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
配置:
<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>
Run Code Online (Sandbox Code Playgroud)
和用法(给定"/hello/1.2.3",value
是"1.2.3"):
@RequestMapping(value = "/hello/{value}$", method = RequestMethod.GET)
public String hello(@PathVariable("value") String value, ModelMap model)
Run Code Online (Sandbox Code Playgroud)
编辑::现在不打破"尾随斜线无关紧要"的规则
小智 6
<!-- language: lang-java -->
Run Code Online (Sandbox Code Playgroud)
@Controller
public class MyController {
@RequestMapping(value="/widgets/{preDot}.{postDot}")
public void getResource(@PathVariable String preDot, @PathVariable String postDot) {
String fullPath = preDot + "." + postDot;
//...
}
}
//上面的代码应该匹配/widgets/111.222.333.444
Spring 3.2 已更改,建议您RequestMappingHandlerMapping
显式地(如果不使用 mvc 命名空间)或使用 BeanPostProcessor 来设置 bean 的属性,如下所示(您需要扫描或实例化它):
@Component
public class IncludeExtensionsInRequestParamPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof RequestMappingHandlerMapping) {
RequestMappingHandlerMapping mapping = (RequestMappingHandlerMapping)bean;
mapping.setUseRegisteredSuffixPatternMatch(false);
mapping.setUseSuffixPatternMatch(false);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) { return bean; }
}
Run Code Online (Sandbox Code Playgroud)
您也可以仅附加:.*
到您的@RequestMapping,例如"/{documentPath:.*}"
(请参阅JIRA评论)
归档时间: |
|
查看次数: |
12399 次 |
最近记录: |