To jest kontynuacja pytania Spring MVC @PathVariable zostanie obcięta
Wiosenne forum stwierdza, że zostało naprawione (wersja 3.2) jako część ContentNegotiationManager. patrz poniższy link.
https://jira.springsource.org/browse/SPR-6164
https://jira.springsource.org/browse/SPR-7632
W mojej aplikacji requestParameter with .com jest obcięty.
Czy ktoś mógłby mi wyjaśnić, jak korzystać z tej nowej funkcji? jak można to skonfigurować w xml?
Uwaga: wiosenne forum - # 1 Spring MVC @PathVariable with dot (.) Jest obcinane
spring
rest
spring-mvc
spring-annotations
Kanagavelu Sugumar
źródło
źródło
<!-- Spring Configuration needed to avoid URI using dots to be truncated --> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="useDefaultSuffixPattern" value="false" /> </bean>
{variable_name:regular_expression}
, więc tutaj mamy zmienną o nazwievariable
, której wartość zostanie dopasowana za pomocą wyrażenia regularnego.+
(gdzie.
oznacza „dowolny znak” i+
„raz lub więcej razy”).variable
regularnie, Spring używa funkcji wykrywania sufiksów i obcina wszystko po kropce. Gdy używasz dopasowania wyrażenia regularnego, te funkcje nie są używane - zmienna jest dopasowywana tylko do wyrażenia regularnego, które udostępniasz."variable:.+"
nie działa, gdy w zmiennej występuje więcej niż jedna kropka. np. umieszczanie wiadomości e-mail na końcu spokojnych ścieżek, takich jak/path/[email protected]
. Kontroler nawet nie zostaje wywołany, ale działa, gdy jest tylko jedna kropka/path/[email protected]
. Masz pomysł, dlaczego i / lub obejście?Spring uważa, że cokolwiek za ostatnią kropką jest rozszerzeniem pliku, takim jak
.json
lub.xml
i obciąć je, aby pobrać parametr.Więc jeśli masz
/somepath/{variable}
:/somepath/param
,/somepath/param.json
,/somepath/param.xml
Lub/somepath/param.anything
spowoduje param z wartościąparam
/somepath/param.value.json
,/somepath/param.value.xml
lub/somepath/param.value.anything
spowoduje parametr o wartościparam.value
jeśli zmienisz mapowanie na
/somepath/{variable:.+}
sugerowane, dowolna kropka, w tym ostatnia, będzie brana pod uwagę jako część parametru:/somepath/param
spowoduje parametr z wartościąparam
/somepath/param.json
spowoduje parametr z wartościąparam.json
/somepath/param.xml
spowoduje parametr z wartościąparam.xml
/somepath/param.anything
spowoduje parametr z wartościąparam.anything
/somepath/param.value.json
spowoduje parametr z wartościąparam.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 ponownie, jeśli masz
/somepath/{variable}
:/somepath/param
,/somepath/param.json
,/somepath/param.xml
Lub/somepath/param.anything
spowoduje param z wartościąparam
/somepath/param.value.json
,/somepath/param.value.xml
lub/somepath/param.value.anything
spowoduje parametr o wartościparam.value
Uwaga: różnica w stosunku do domyślnej konfiguracji jest widoczna tylko wtedy, gdy masz podobne mapowanie
somepath/something.{variable}
. patrz problem z projektem Resthubjeśli chcesz zachować zarządzanie rozszerzeniami, od wersji 3.2 możesz również ustawić właściwość useRegisteredSuffixPatternMatch komponentu Bean RequestMappingHandlerMapping, aby aktywować rozpoznawanie sufiksuPattern, ale ograniczone do zarejestrowanego rozszerzenia.
Tutaj definiujesz tylko rozszerzenia json i xml:
Zauważ, że mvc: oparty na adnotacjach 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 przesłonić konfigurację opartą na wszystkich mvc: adnotacjach. Otworzyłem bilet do Spring z prośbą o niestandardowe RequestMappingHandlerMapping: https://jira.springsource.org/browse/SPR-11253 . Głosuj, jeśli jesteś zainteresowany.
Podczas nadpisywania pamiętaj o rozważeniu nadpisania niestandardowego zarządzania wykonywaniem. W przeciwnym razie wszystkie niestandardowe odwzorowania wyjątków zakończą się niepowodzeniem. Będziesz musiał ponownie użyć programu MessageCoverters z komponentem bean list:
Wdrożyłem, w projekcie Resthub projektu open source , którego jestem częścią, zestaw testów na te tematy: patrz https://github.com/resthub/resthub-spring-stack/pull/219/files & https: // github.com/resthub/resthub-spring-stack/issues/217
źródło
Aktualizacja do wiosny 4: od 4.0.1 możesz używać
PathMatchConfigurer
(za pośrednictwem swojegoWebMvcConfigurer
), npW xml byłoby to ( https://jira.spring.io/browse/SPR-10163 ):
źródło
matcher.setUseSuffixPatternMatch(false)
aby całkowicie wyłączyć dopasowanie sufiksu.Oprócz odpowiedzi Martina Freya można to naprawić, dodając ukośnik końcowy w wartości RequestMapping:
Należy pamiętać, że ta poprawka nie obsługuje możliwości konserwacji. Teraz wymaga, aby wszystkie identyfikatory URI miały końcowy ukośnik - coś, co może nie być widoczne dla użytkowników interfejsu API / nowych programistów. Ponieważ prawdopodobnie nie wszystkie parametry mogą
.
w nich zawierać , może również powodować sporadyczne błędyźródło
W Spring Boot Rest Controller rozwiązałem je, wykonując następujące kroki:
RestController:
I od klienta Rest:
źródło
dodanie „:. +” zadziałało dla mnie, ale dopiero po usunięciu zewnętrznych nawiasów klamrowych.
wartość = { "/username/{id:.+}" } nie działa
wartość = "/username/{id:.+}" działa
Mam nadzieję, że komuś pomogłem :)
źródło
id
/somepath/{variable:.+}
działa wrequestMapping
znaczniku Java .źródło
"/{code:.+}"
działa dla wielu kropek, a nie jedna, tj61.12.7
. Działa również na np.[email protected]
Oto podejście oparte wyłącznie na konfiguracji Java:
źródło
Jednym dość łatwym sposobem obejścia tego problemu jest dodanie ukośnika końcowego ...
na przykład:
posługiwać się :
zamiast:
źródło
W Spring Boot wyrażenie regularne rozwiązuje problem jak
źródło
"/{code:.+}"
działa dla wielu kropek, nie jedna, tj61.12.7
. Działa również dla np.[email protected]
Kompletne rozwiązanie obejmujące adresy e-mail w nazwach ścieżek na wiosnę 4.2 to
Dodaj to do xml aplikacji
źródło
Jeśli używasz wersji Spring 3.2.xi
<mvc:annotation-driven />
, utwórz toBeanPostProcessor
:Następnie umieść to w pliku XML konfiguracji MVC:
źródło
BeanPostProcessor
do tego. Jeśli używaszWebMvcConfigurationSupport
, możesz zastąpićrequestMappingHandlerMapping
@Bean
metodę. Jeśli używasz konfiguracji XML, możesz po prostu zadeklarować własnąRequestMappingHandlerMapping
fasolę i zadeklarować tę właściwość.Wreszcie znalazłem rozwiązanie w Spring Docs :
Dodanie tego do mojej
WebMvcConfigurerAdapter
implementacji rozwiązało problem:źródło
Dla mnie
działa, ale tylko jeśli zakodujesz również „kropkę” w adresie URL żądania jako „% 2E”, to działa. Wymaga jednak, aby wszystkie adresy URL były…, co nie jest „standardowym” kodowaniem, chociaż jest prawidłowe. Czuje się jak błąd: |
Drugi sposób obejścia, podobny do „końcowego ukośnika”, to przesunięcie zmiennej, która będzie miała kropkę „inline”, np .:
@GetMapping (ścieżka = "/ {nazwa_zmiennej} / a")
teraz wszystkie kropki zostaną zachowane, nie będą potrzebne żadne modyfikacje ani wyrażenia regularne.
źródło
Od wiosny 5.2.4 (Spring Boot v2.2.6.RELEASE)
PathMatchConfigurer.setUseSuffixPatternMatch
iContentNegotiationConfigurer.favorPathExtension
zostały wycofane ( https://spring.io/blog/2020/03/24/spring-framework-5-2-5-available-now i https://github.com/spring-projects/spring-framework/issues/24179 ).Prawdziwy problem polega na tym, że klient żąda określonego typu nośnika (np. .Com), a Spring domyślnie dodał wszystkie te typy nośników. W większości przypadków kontroler REST będzie produkował tylko JSON, więc nie będzie obsługiwał żądanego formatu wyjściowego (.com). Aby rozwiązać ten problem, powinieneś być dobry, aktualizując kontroler spoczynkowy (lub określoną metodę) w celu obsługi formatu „ouput” (
@RequestMapping(produces = MediaType.ALL_VALUE
)) i oczywiście zezwalaj na znaki takie jak kropka ({username:.+}
).Przykład:
Wiosna 5.3 i nowsze będą pasować tylko do zarejestrowanych sufiksów (typy mediów).
źródło