Spring MVC @PathVariable становится усеченным - PullRequest
132 голосов
/ 20 августа 2010

У меня есть контроллер, который обеспечивает RESTful доступ к информации:

@RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName}")
public ModelAndView getBlah(@PathVariable String blahName, HttpServletRequest request,
                            HttpServletResponse response) {

Проблема, с которой я сталкиваюсь, заключается в том, что, если я попадаю на сервер с переменной пути специальными символами, он усекается.Например: http://localhost:8080/blah-server/blah/get/blah2010.08.19-02:25:47

Параметр blahName будет blah2010.08

Однако вызов request.getRequestURI () содержит всю передаваемую информацию.

ЛюбойИдея, как запретить Spring усекать @PathVariable?

Ответы [ 16 ]

3 голосов
/ 12 июля 2013

Проблема с расширением файла существует, только если параметр находится в последней части URL. Изменить

@RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName}")

до

@RequestMapping(
   method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName}/safe")

и все будет хорошо снова *

3 голосов
/ 27 июля 2011

Я только что натолкнулся на это, и решения здесь, как правило, не работали, как я ожидал.

Я предлагаю использовать выражение SpEL и несколько отображений, например

@RequestMapping(method = RequestMethod.GET, 
    value = {Routes.BLAH_GET + "/{blahName:.+}", 
             Routes.BLAH_GET + "/{blahName}/"})
2 голосов
/ 29 сентября 2015

, если вы уверены, что ваш текст не будет соответствовать ни одному из расширений по умолчанию, вы можете использовать следующий код:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setUseRegisteredSuffixPatternMatch(true);
    }
}
2 голосов
/ 05 марта 2015

Решение для конфигурирования на основе Java для предотвращения усечения (с использованием не устаревшего класса):

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@Configuration
public class PolRepWebConfig extends WebMvcConfigurationSupport {

    @Override
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        final RequestMappingHandlerMapping handlerMapping = super
                .requestMappingHandlerMapping();
        // disable the truncation after .
        handlerMapping.setUseSuffixPatternMatch(false);
        // disable the truncation after ;
        handlerMapping.setRemoveSemicolonContent(false);
        return handlerMapping;
    }
}

Источник: http://www.javacodegeeks.com/2013/01/spring-mvc-customizing-requestmappinghandlermapping.html

UPDATE:

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

Вместо этого я начал использовать подход BeanPostProcessor. Казалось, работает лучше.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {
    private static final Logger logger = LoggerFactory
            .getLogger(MyBeanPostProcessor.class);

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        if (bean instanceof RequestMappingHandlerMapping) {
            setRemoveSemicolonContent((RequestMappingHandlerMapping) bean,
                    beanName);
            setUseSuffixPatternMatch((RequestMappingHandlerMapping) bean,
                    beanName);
        }
        return bean;
    }

    private void setRemoveSemicolonContent(
            RequestMappingHandlerMapping requestMappingHandlerMapping,
            String beanName) {
        logger.info(
                "Setting 'RemoveSemicolonContent' on 'RequestMappingHandlerMapping'-bean to false. Bean name: {}",
                beanName);
        requestMappingHandlerMapping.setRemoveSemicolonContent(false);
    }

    private void setUseSuffixPatternMatch(
            RequestMappingHandlerMapping requestMappingHandlerMapping,
            String beanName) {
        logger.info(
                "Setting 'UseSuffixPatternMatch' on 'RequestMappingHandlerMapping'-bean to false. Bean name: {}",
                beanName);
        requestMappingHandlerMapping.setUseSuffixPatternMatch(false);
    }
}

По мотивам: http://ronaldxq.blogspot.com/2014/10/spring-mvc-setting-alwaysusefullpath-on.html

1 голос
/ 07 февраля 2017

Моим предпочтительным решением для предотвращения усечения Spring MVC @PathVariable является добавление косой черты в конце переменной пути.

Например:

@RequestMapping(value ="/email/{email}/")

Итак,запрос будет выглядеть так:

http://localhost:8080/api/email/test@test.com/
0 голосов
/ 03 апреля 2019

Проблема, с которой вы столкнулись, связана с тем, что spring интерпретирует last часть uri после точка (.) как расширение файла как .json или .xml. Поэтому, когда spring пытается разрешить переменную path, она просто обрезает остальные данные после того, как встретит точку (.) В конце URI. Примечание: также это происходит, только если вы сохраняете переменную пути в конце URI.

Например, рассмотрим uri: https://localhost/example/gallery.df/link.ar

@RestController
public class CustomController {
    @GetMapping("/example/{firstValue}/{secondValue}")
    public void example(@PathVariable("firstValue") String firstValue,
      @PathVariable("secondValue") String secondValue) {
        // ...  
    }
}

В приведенном выше URL firstValue = "gallery.df" и secondValue = "link", последний бит после. обрезается при интерпретации переменной пути.

Итак, для предотвращения этого есть два возможных пути:

1.) Использование сопоставления регулярных выражений

Используйте регулярное выражение в конечной части отображения

@GetMapping("/example/{firstValue}/{secondValue:.+}")   
public void example(
  @PathVariable("firstValue") String firstValue,
  @PathVariable("secondValue") String secondValue) {
    //...
}

Используя +, мы указываем любое значение после того, как точка также будет частью переменной пути.

2.) Добавление косой черты в конце нашего @ PathVariable

@GetMapping("/example/{firstValue}/{secondValue}/")
public void example(
  @PathVariable("firstValue") String firstValue,
  @PathVariable("secondValue") String secondValue) {
    //...
}

Это будет заключать нашу вторую переменную, защищая ее от поведения Spring по умолчанию.

3) Переопределив стандартную конфигурацию webmvc в Spring

Spring предоставляет способы переопределения конфигураций по умолчанию, импортируемых с помощью аннотаций @EnableWebMvc. Мы можем настроить конфигурацию Spring MVC, объявив нашу собственную DefaultAnnotationHandlerMapping bean в контексте приложения и для его свойства useDefaultSuffixPattern установлено значение false. Пример:

@Configuration
public class CustomWebConfiguration extends WebMvcConfigurationSupport {

    @Bean
    public RequestMappingHandlerMapping 
      requestMappingHandlerMapping() {

        RequestMappingHandlerMapping handlerMapping
          = super.requestMappingHandlerMapping();
        handlerMapping.setUseSuffixPatternMatch(false);
        return handlerMapping;
    }
}

Имейте в виду, что переопределение этой конфигурации по умолчанию влияет на все URL.

Примечание: здесь мы расширяем класс WebMvcConfigurationSupport для переопределения методов по умолчанию. Есть еще один способ переопределить конфигурации по умолчанию, реализуя интерфейс WebMvcConfigurer. Подробнее об этом читайте: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/EnableWebMvc.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...