2017-02-13 6 views
0

У меня возникла проблема с Spring mvc для загрузки файлов, содержащих пробелы в названии. Что я пытаюсь сделать, так это использовать встроенный Spring MVC для преобразования ресурсов с помощью удаленного ресурса.Spring mvc - ошибка с пробелом в имени файла для скачивания

Я использую Spring безопасности наряду с Spring MVC, но для испытания без применения каких-либо безопасности на определенной схеме

конфигурации

Spring Security:

<http> 
.... 
    <intercept-url pattern="/test download/**" access="permitAll" requires-channel="https" /> 
... 
</http> 

Тогда просьба прибыть на MVC, где сконфигурирован резольвер ресурса как таковой:

Спр. ИНГ конфигурация MVC:

<mvc:resources mapping="/test download/**" location="http://localhost:10089/test/" /> 

Конфигурация прекрасно работает для файлов, которые не имеют места в имени. Включение журнала отладки в модулях Spring. Я вижу, что оба запроса (с пространством в имени файла или без него) обрабатываются одним и тем же способом. Ниже журнала сервлета диспетчера весов при разрешении обоих вызовов.

первый тестовый путь:/тест загрузки/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=[[email protected]6eb843]]] 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

второй тест путь:/тест загрузки/тест 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=[[email protected]6eb843]]] 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

Любая идея, почему это происходит?

UPDATE

После Фредерика намека я настроил, что кот, я использую для тестирования в качестве удаленного хоста для управления UTF-8, и я обнаружил, что, когда он обрабатывает запрос, исходящий весной он возвращается 505.

Простой вызов из браузера удаленного хоста:

"GET /test/test%20file.txt HTTP/1.1" 200 15

вызовов, полученных с помощью Spring:

"HEAD/test/test file.txt HTTP/1.1" 505 -

Я попытался создать файл с% 20 в названии, прежде чем даже настроить коннектор, и он не сработал, возможно, даже до того, как работала кодировка.

ответ

0

Проблема была решена путем создания специального обработчика ресурсов.

То, что мы делали в деталях было создание класса загружается при запуске в конфигурации

@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); 
    } 
} 

ЗАМЕНИТЬ не самое элегантное решение :), вероятно, но для наших простых потребностей сейчас достаточно.

0

Обработчик, ответственный за поиск ресурсов на основе URL-адреса, использует HandlerMapping .PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, что соответствует значению /**, которое вы настроили при сопоставлении.

https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java#L407

Я совершенно уверен, что путь, используемый для получения файла содержит спусковые символы. Поэтому он будет искать файл с именем test%20file.txt. Вы можете проверить, так ли это, добавив файл в папку test download с этим именем.

Весна на самом деле декодирует URL-адрес - можете ли вы проверить, действительно ли ваш файл tomcat/container содержит фильтр символов UTF-8?

+0

Как вы показываете URL-адрес в браузере? Возможно, вы можете попробовать кодировать URL-адрес перед его отображением в браузере: 'java.net.URLEncoder.encode (url,« UTF-8 »)' –

+1

Проблема здесь кажется, что после того, как URL-адрес декодируется с уровня Spring Security не перекодируется обработчиком ресурсов. Отладка обработчика ресурсов по умолчанию (используется в классе, который вы опубликовали), пробелы не перекодированы. В отладке я перезаписывал значение во время выполнения (спасибо eclipse для этого) с% 20, и файл был найден без проблем. Поэтому я думаю, что единственным решением на данный момент является расширение обработчика ресурса по умолчанию, добавляющего в резольверу шаг «перекодировать» для определенного пути »/ test download/**. – Stefano

 Смежные вопросы

  • Нет связанных вопросов^_^