我希望有一个匹配file/
+任何路径的映射,例如file/image.jpg
或file/a/b/c/image.jpg
,我想在file/
我可以做之后收到完整路径如果我只有一个路径变量:
file/{file_name}
但我不知道如何为我的案子做这件事。我知道我可以只映射file/**
,然后检索这样的路径:
(String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
但我正在寻找更优雅的解决方案。
答案 0 :(得分:0)
这样做的一种方法是使用spring-mvc
拦截器
在创建HTTP请求之前,使用file_name
对URLEncoder
路径变量进行编码,这样您就可以使用斜杠发送它,并且请求由正确的处理程序处理。然后,您需要创建一个拦截器,其方法在控制器方法之前被调用。在拦截器中,您将使用URLDecoder
将路径变量解码回来,并将其设置为属性。属性名称由HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE
常量指定,它包含所有路径变量的映射。
如果您不想实现接口的所有方法,拦截器需要实现HandlerInterceptor
接口或扩展HandlerInterceptorAdapter
。
像这样的东西
public class UrlDecodeInterceptor extends HandlerInterceptorAdapter {
private static final String ATTRIBUTE_VARIBLE_PATH = "file_name";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
Map<String, String> pathVariables = (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
if (pathVariables.containsKey(ATTRIBUTE_VARIBLE_PATH)) {
String decoded = URLDecoder.decode(pathVariables.get(ATTRIBUTE_VARIBLE_PATH), "UTF-8");
pathVariables.put(ATTRIBUTE_VARIBLE_PATH, decoded);
}
return true;
}
}
默认情况下,spring-mvc
会自行解码网址。您需要在 spring-servlet.xml 或您的servlet配置文件中禁用它。
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="urlDecode" value="false" />
</bean>
然后你需要在同一个文件中注册UrlDecodeInterceptor
作为拦截器
<mvc:interceptors>
<bean id="urlDecodeInterceptor" class="path.to.your.package.UrlDecodeInterceptor" />
</mvc:interceptors>
最后,您的控制器处理程序将如下所示
@RequestMapping(value = "/file/{file_name}")
public String someMethodName(@PathVariable("file_name") String fileName) {
System.out.println(fileName); // should contain decoded file_name
return null
}