我遇到Spring mvc的问题,要下载名称中包含空格的文件。 我想要做的是使用资源解析器内置的Spring MVC从远程主机下载文件。
我使用Spring安全性和Spring MVC但是在没有对特定模式应用任何安全性的情况下进行测试
Spring Security配置:
<http>
....
<intercept-url pattern="/test download/**" access="permitAll" requires-channel="https" />
...
</http>
然后请求到达MVC调度程序,在那里配置资源解析器:
Spring MVC配置:
<mvc:resources mapping="/test download/**" location="http://localhost:10089/test/" />
配置适用于名称中没有空格的文件。在Spring模块上启用调试日志我看到两个请求(文件名中有或没有空格)都以相同的方式处理。 解析两个调用时,在Spring调度程序servlet的日志下面。
第一个测试路径:/ test download / file.txt
... after security filters ..
DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'mvc-dispatcher' processing GET request for [/portal/test%20download/file.txt]
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /test download/file.txt
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Did not find handler method for [/test download/file.txt]
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /test download/file.txt
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Did not find handler method for [/test download/file.txt]
DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Matching patterns for request [/test download/file.txt] are [/test download/**]
DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - URI Template variables for request [/test download/file.txt] are {}
DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapping [/test download/file.txt] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[URL [http://localhost:10089/test/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@2a6eb843]]] and 1 interceptor
DEBUG org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/portal/test%20download/file.txt] is: -1
DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'mvc-dispatcher': assuming HandlerAdapter completed request handling
DEBUG org.springframework.web.servlet.DispatcherServlet - Successfully completed request
DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Chain processed normally
DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
结果:
Content of the file is shown in the browser as expected
第二个测试路径:/ test download / test file.txt
... after security filters ..
DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'mvc-dispatcher' processing GET request for [/portal/test%20download/test%20file.txt]
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /test download/test file.txt
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Did not find handler method for [/test download/test file.txt]
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /test download/test file.txt
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Did not find handler method for [/test download/test file.txt]
DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Matching patterns for request [/test download/test file.txt] are [/test download/**]
DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - URI Template variables for request [/test download/test file.txt] are {}
DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapping [/test download/test file.txt] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[URL [http://localhost:10089/test/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@2a6eb843]]] and 1 interceptor
DEBUG org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/portal/test%20download/test%20file.txt] is: -1
DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'mvc-dispatcher': assuming HandlerAdapter completed request handling
DEBUG org.springframework.web.servlet.DispatcherServlet - Successfully completed request
DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Chain processed normally
DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
结果:
Http 404 is returned
这2个文件位于主机的同一个文件夹中,我使用本地服务器测试文件和具有相同结果的远程服务器。
我试图仅使用Spring配置来解决我的需求,因为我需要的基本上类似于代理,但是应用了安全规则。
Spring MVC版本:4.1.6.RELEASE
Spring Security版本:3.2.5.RELEASE
知道为什么会这样吗?
更新
在Frederik提示之后,我将我用作测试的tomcat配置为管理utf-8的远程主机,并且我发现当它处理来自Spring的请求时它返回505.
从浏览器到远程主机的简单调用:
&#34; GET /test/test%20file.txt HTTP / 1.1&#34; 200 15
通过Spring收到的电话:
&#34; HEAD / test / test file.txt HTTP / 1.1&#34; 505 -
我确实尝试在配置连接器之前使用名称中的%20创建文件,但它不起作用,所以甚至可能在编码工作之前。
答案 0 :(得分:1)
通过创建自定义资源处理程序解决了该问题。
我们在细节方面所做的是创建一个在启动时加载的类作为配置
@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
/**
*
* Add ResourceResolver that fix the whitespace problem in filename url.
* resources that needs this fix must be configured here instead of inside xml
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/test download/**")
.addResourceLocations("http://localhost:10089/test/")
.resourceChain(true)
.addResolver(new CustomPathResourceResolver())
;
}
}
CustomPathResourceResolver是
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.resource.ResourceResolver;
import java.io.IOException;
public class CustomPathResourceResolver extends PathResourceResolver implements ResourceResolver {
@Override
protected Resource getResource(String resourcePath, Resource location) throws IOException {
//fixes problems with whitespaces in url
resourcePath = resourcePath.replace(" ","%20");
return super.getResource(resourcePath, location);
}
}
替换不是最优雅的解决方案:)可能但是因为我们的简单需求现在已经足够了。
答案 1 :(得分:0)
负责根据URL查找资源的处理程序使用HandlerMapping .PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE
,它对应于您在映射中配置的/**
值。
我非常确定用于获取文件的路径包含转义字符。因此,它将查找名为test%20file.txt
的文件。您可以通过在test download
文件夹中添加具有该名称的文件来验证是否是这种情况。
Spring实际上解码了URL - 你可以检查你的tomcat /容器是否真的是UTF-8字符集过滤器?