Posiadam kontroler zapewniający RESTful dostęp do informacji:
@RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName}")
public ModelAndView getBlah(@PathVariable String blahName, HttpServletRequest request,
HttpServletResponse response) {
Problem, którego doświadczam, polega na tym, że jeśli trafię na serwer ze zmienną ścieżki ze znakami specjalnymi, zostanie ona obcięta. Na przykład: http: // localhost: 8080 / blah-server / blah / get / blah2010.08.19-02: 25: 47
Parametr blahName będzie miał wartość blah2010.08
Jednak wywołanie request.getRequestURI () zawiera wszystkie przekazane informacje.
Masz pomysł, jak uniemożliwić Springowi obcięcie zmiennej @PathVariable?
Odpowiedzi:
Wypróbuj wyrażenie regularne dla
@RequestMapping
argumentu:źródło
Jest to prawdopodobnie blisko spokrewnione z SPR-6164 . Krótko mówiąc, framework próbuje zastosować pewne sprytne rozwiązania do interpretacji URI, usuwając to, co uważa za rozszerzenia plików. Spowodowałoby to przekształcenie się
blah2010.08.19-02:25:47
wblah2010.08
, ponieważ uważa, że.19-02:25:47
jest to rozszerzenie pliku.Jak opisano w powiązanym problemie, możesz wyłączyć to zachowanie, deklarując własny
DefaultAnnotationHandlerMapping
komponent bean w kontekście aplikacji i ustawiając jegouseDefaultSuffixPattern
właściwość nafalse
. Spowoduje to zastąpienie domyślnego zachowania i powstrzymanie go przed molestowaniem danych.źródło
RequestMappingHandlerMapping
zamiast tego używasz nowego , właściwość do ustawienia touseSuffixPatternMatch
(również dofalse
). @Ted: powiązany problem wspomina, że w 3.2 mają nadzieję na dodanie nieco większej kontroli, więc nie musi to być wszystko albo nic.WebMvcConfigurationSupport
które zapewniają prosty punkt zaczepienia:public void configurePathMatch(PathMatchConfigurer configurer)
- po prostu nadpisuj to i ustaw ścieżkę tak, jak chcesz.Spring uważa, że wszystko, co znajduje się za ostatnią kropką, to rozszerzenie pliku, takie jak
.json
lub.xml
i skraca je, aby pobrać parametr.Więc jeśli masz
/{blahName}
:/param
,/param.json
,/param.xml
Lub/param.anything
spowoduje param z wartościąparam
/param.value.json
,/param.value.xml
Lub/param.value.anything
spowoduje param z wartościąparam.value
Jeśli zmienisz mapowanie na
/{blahName:.+}
zgodnie z sugestią, każda kropka, w tym ostatnia, będzie traktowana jako część parametru:/param
da parametr o wartościparam
/param.json
da parametr o wartościparam.json
/param.xml
da parametr o wartościparam.xml
/param.anything
da parametr o wartościparam.anything
/param.value.json
da parametr o wartościparam.value.json
Jeśli nie zależy Ci na rozpoznawaniu rozszerzeń, możesz je wyłączyć, zastępując
mvc:annotation-driven
automagic:Więc znowu, jeśli masz
/{blahName}
:/param
,/param.json
,/param.xml
Lub/param.anything
spowoduje param z wartościąparam
/param.value.json
,/param.value.xml
Lub/param.value.anything
spowoduje param z wartościąparam.value
Uwaga: różnica w stosunku do domyślnej konfiguracji jest widoczna tylko wtedy, gdy masz mapowanie takie jak
/something.{blahName}
. Zobacz problem z projektem Resthub .Jeśli chcesz zachować zarządzanie rozszerzeniami, od Spring 3.2 możesz również ustawić właściwość useRegisteredSuffixPatternMatch komponentu bean RequestMappingHandlerMapping, aby funkcja rozpoznawania sufiksów była aktywna, ale ograniczona do zarejestrowanego rozszerzenia.
Tutaj definiujesz tylko rozszerzenia json i xml:
Zauważ, że mvc: annotation-based akceptuje teraz opcję contentNegotiation w celu zapewnienia niestandardowego komponentu bean, ale właściwość RequestMappingHandlerMapping musi zostać zmieniona na true (domyślnie false) (por. Https://jira.springsource.org/browse/SPR-7632 ).
Z tego powodu nadal musisz nadpisać całą konfigurację mvc: opartą na adnotacjach. Otworzyłem zgłoszenie do Springa, aby poprosić o niestandardowe RequestMappingHandlerMapping: https://jira.springsource.org/browse/SPR-11253 . Prosimy o głosowanie, jeśli jesteś zainteresowany.
Podczas zastępowania należy uważać, aby rozważyć również zastąpienie niestandardowego zarządzania wykonaniem. W przeciwnym razie wszystkie niestandardowe mapowania wyjątków zakończą się niepowodzeniem. Będziesz musiał ponownie użyć wiadomości Coverters z fasolą listy:
Zaimplementowałem w otwartym projekcie Resthub , którego jestem częścią, zestaw testów na te tematy: patrz https://github.com/resthub/resthub-spring-stack/pull/219/files i https: // github.com/resthub/resthub-spring-stack/issues/217
źródło
Wszystko po ostatniej kropce jest interpretowane jako rozszerzenie pliku i domyślnie obcięte.
W swoim spring config xml możesz dodać
DefaultAnnotationHandlerMapping
i ustawićuseDefaultSuffixPattern
nafalse
(domyślnietrue
).Więc otwórz swój spring xml
mvc-config.xml
(lub jak to się nazywa) i dodajTeraz Twój
@PathVariable
blahName
(i wszystkie inne) powinien zawierać pełne imię i nazwisko, w tym wszystkie kropki.EDYCJA: Oto link do wiosennego interfejsu API
źródło
<mvc:annotation-driven />
.Napotkałem również ten sam problem, a ustawienie właściwości na false też mi nie pomogło. Jednak API mówi :
Próbowałem dodać „/ end” do mojego RESTful URL i problem zniknął. Nie jestem zadowolony z rozwiązania, ale zadziałało.
Przy okazji, nie wiem, co myśleli projektanci Spring, kiedy dodali tę „funkcję”, a potem włączyli ją domyślnie. IMHO, należy go usunąć.
źródło
Korzystanie z poprawnej klasy konfiguracyjnej Java:
źródło
Rozwiązałem przez ten hack
1) Dodano HttpServletRequest w @PathVariable, jak poniżej
2) Uzyskaj adres URL bezpośrednio (na tym poziomie bez obcinania) w żądaniu
Spring MVC @PathVariable z kropką (.) Jest obcinany
źródło
Właśnie wpadłem na to, a rozwiązania tutaj generalnie nie działały tak, jak się spodziewałem.
Proponuję użyć wyrażenia SpEL i wielu mapowań np
źródło
Problem z rozszerzeniem pliku istnieje tylko wtedy, gdy parametr znajduje się w ostatniej części adresu URL. Zmiana
do
i wszystko będzie dobrze znowu-
źródło
Jeśli możesz edytować adres, na który wysyłane są żądania, prostą poprawką byłoby dodanie do nich końcowego ukośnika (a także
@RequestMapping
wartości):więc mapowanie wyglądałoby następująco:
Zobacz także Spring MVC @PathVariable z kropką (.) Jest obcięta .
źródło
źródło
dodanie „:. +” zadziałało, ale nie do momentu usunięcia zewnętrznych nawiasów klamrowych.
value = {"/username/{id:.+}"}
nie zadziałałovalue = "/username/{id:.+}"
PracujeMam nadzieję, że komuś pomogłem:]
źródło
Rozwiązanie konfiguracyjne oparte na języku Java, aby zapobiec obcięciu (przy użyciu klasy, która nie jest przestarzała):
Źródło: http://www.javacodegeeks.com/2013/01/spring-mvc-customizing-requestmappinghandlermapping.html
AKTUALIZACJA:
Zdałem sobie sprawę, że mam pewne problemy z automatyczną konfiguracją Spring Boot, gdy zastosowałem powyższe podejście (niektóre autokonfiguracje nie działają).
Zamiast tego zacząłem stosować to
BeanPostProcessor
podejście. Wydawało się, że działa lepiej.Zainspirowany: http://ronaldxq.blogspot.com/2014/10/spring-mvc-setting-alwaysusefullpath-on.html
źródło
jeśli masz pewność, że Twój tekst nie będzie pasował do żadnego z domyślnych rozszerzeń, możesz użyć poniższego kodu:
źródło
Moim preferowanym rozwiązaniem, aby zapobiec obcięciu Spring MVC @PathVariable, jest dodanie końcowego ukośnika na końcu zmiennej ścieżki.
Na przykład:
Tak więc żądanie będzie wyglądać następująco:
źródło
Problem, że masz do czynienia ze względu na wiosnę interpretacji ostatnią częścią URI po tej kropki (.) Jako rozszerzenia pliku jak .json lub .xml. Więc gdy spring próbuje rozwiązać zmienną ścieżki, po prostu obcina resztę danych po napotkaniu kropki (.) Na końcu uri. Uwaga: dzieje się tak również tylko wtedy, gdy zachowasz zmienną ścieżki na końcu uri.
Na przykład rozważmy uri: https: //localhost/example/gallery.df/link.ar
W powyższym adresie URL firstValue = "gallery.df" i secondValue = "link", ostatni bit po. zostaje obcięty, gdy zmienna ścieżki jest interpretowana.
Aby temu zapobiec, istnieją dwa możliwe sposoby:
1.) Korzystanie z mapowania regexp
Użyj wyrażenia regularnego na końcu mapowania
Używając +, wskazujemy, że każda wartość po kropce będzie również częścią zmiennej ścieżki.
2.) Dodanie ukośnika na końcu naszej @PathVariable
To otoczy naszą drugą zmienną chroniącą ją przed domyślnym zachowaniem Springa.
3) Zastępując domyślną konfigurację Webmvc Springa
Spring zapewnia sposoby nadpisania domyślnych konfiguracji, które są importowane za pomocą adnotacji @EnableWebMvc. Możemy dostosować konfigurację Spring MVC, deklarując naszą własną komponent bean DefaultAnnotationHandlerMapping w kontekście aplikacji i ustawiając jej właściwość useDefaultSuffixPattern na wartość false. Przykład:
Pamiętaj, że zastąpienie tej domyślnej konfiguracji ma wpływ na wszystkie adresy URL.
Uwaga: tutaj rozszerzamy klasę WebMvcConfigurationSupport, aby zastąpić metody domyślne. Istnieje jeszcze jeden sposób na zastąpienie domyślnych konfiguracji poprzez implementację interfejsu WebMvcConfigurer. Aby uzyskać więcej informacji na ten temat, przeczytaj: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/EnableWebMvc.html
źródło