Ini adalah kelanjutan dari pertanyaan Spring MVC @PathVariable yang terpotong
Forum musim semi menyatakan bahwa ia telah memperbaiki (versi 3.2) sebagai bagian dari ContentNegotiationManager. lihat tautan di bawah ini.
https://jira.springsource.org/browse/SPR-6164
https://jira.springsource.org/browse/SPR-7632
Dalam aplikasi saya requestParameter dengan .com terpotong.
Adakah yang bisa menjelaskan kepada saya bagaimana cara menggunakan fitur baru ini? bagaimana ini dapat dikonfigurasi di xml?
Catatan: spring forum- # 1 Spring MVC @PathVariable dengan dot (.) Semakin terpotong
sumber
<!-- 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}
, jadi di sini kita memiliki variabel bernamavariable
, nilai mana yang akan dicocokkan menggunakan regex.+
(di mana.
berarti 'karakter apa pun' dan+
berarti 'satu atau lebih kali').variable
dengan cara biasa, Spring menggunakan fitur deteksi sufiks dan memotong semuanya setelah titik. Saat Anda menggunakan pencocokan regexp, fitur-fitur itu tidak digunakan - variabel hanya cocok dengan regexp yang Anda berikan."variable:.+"
tidak berfungsi ketika ada lebih dari satu titik di variabel. misalnya meletakkan email di akhir jalur yang sepi seperti/path/[email protected]
. Kontroler itu bahkan tidak dipanggil, tetapi berfungsi ketika hanya ada satu titik/path/[email protected]
. Adakah yang tahu mengapa dan / atau solusinya?Spring menganggap bahwa apa pun di belakang titik terakhir adalah ekstensi file seperti
.json
atau.xml
dan buatkan itu untuk mengambil parameter Anda.Jadi, jika Anda memiliki
/somepath/{variable}
:/somepath/param
,/somepath/param.json
,/somepath/param.xml
Atau/somepath/param.anything
akan menghasilkan param dengan nilaiparam
/somepath/param.value.json
,/somepath/param.value.xml
atau/somepath/param.value.anything
akan menghasilkan param dengan nilaiparam.value
jika Anda mengubah pemetaan menjadi
/somepath/{variable:.+}
seperti yang disarankan, sembarang titik, termasuk yang terakhir akan dianggap sebagai bagian dari parameter Anda:/somepath/param
akan menghasilkan param dengan nilaiparam
/somepath/param.json
akan menghasilkan param dengan nilaiparam.json
/somepath/param.xml
akan menghasilkan param dengan nilaiparam.xml
/somepath/param.anything
akan menghasilkan param dengan nilaiparam.anything
/somepath/param.value.json
akan menghasilkan param dengan nilaiparam.value.json
Jika Anda tidak peduli dengan pengenalan ekstensi, Anda dapat menonaktifkannya dengan menimpa
mvc:annotation-driven
automagic:Jadi, sekali lagi, jika Anda memiliki
/somepath/{variable}
:/somepath/param
,/somepath/param.json
,/somepath/param.xml
Atau/somepath/param.anything
akan menghasilkan param dengan nilaiparam
/somepath/param.value.json
,/somepath/param.value.xml
atau/somepath/param.value.anything
akan menghasilkan param dengan nilaiparam.value
Catatan: perbedaan dari konfigurasi default hanya terlihat jika Anda memiliki pemetaan seperti
somepath/something.{variable}
. lihat masalah proyek Resthubjika Anda ingin mempertahankan manajemen ekstensi, sejak Spring 3.2 Anda juga dapat mengatur properti useRegisteredSuffixPatternMatch dari RequestMappingHandlerMapping bean untuk menjaga suffixPengenalan pola makan diaktifkan tetapi terbatas pada ekstensi yang terdaftar.
Di sini Anda hanya mendefinisikan ekstensi json dan xml:
Perhatikan bahwa mvc: annotation-driven menerima sekarang opsi contentNegotiation untuk menyediakan kacang kustom tetapi properti dari RequestMappingHandlerMapping harus diubah menjadi true (default false) (lih. Https://jira.springsource.org/browse/SPR-7632 ).
Untuk alasan itu, Anda masih harus mengganti semua konfigurasi mvc: annotation-driven. Saya membuka tiket ke Spring untuk meminta RequestMappingHandlerMapping kustom: https://jira.springsource.org/browse/SPR-11253 . Berikan suara jika Anda diinteret masuk.
Sementara mengesampingkan, berhati-hatilah untuk mempertimbangkan juga menimpa manajemen Eksekusi kustom. Jika tidak, semua pemetaan Pengecualian khusus Anda akan gagal. Anda harus menggunakan kembali messageCoverters dengan daftar kacang:
Saya menerapkan, dalam proyek open source Resthub yang menjadi bagian saya, serangkaian tes pada subjek ini: lihat https://github.com/resthub/resthub-spring-stack/pull/219/files & https: // github.com/resthub/resthub-spring-stack/issues/217
sumber
Pembaruan untuk Spring 4: sejak 4.0.1 Anda dapat menggunakan
PathMatchConfigurer
(via AndaWebMvcConfigurer
), misDalam xml, itu akan menjadi ( https://jira.spring.io/browse/SPR-10163 ):
sumber
matcher.setUseSuffixPatternMatch(false)
untuk sepenuhnya menonaktifkan kecocokan sufiks.Selain jawaban Martin Frey, ini juga dapat diperbaiki dengan menambahkan garis miring pada nilai RequestMapping:
Perlu diingat bahwa perbaikan ini tidak mendukung perawatan. Sekarang mengharuskan semua URI untuk memiliki garis miring - sesuatu yang mungkin tidak terlihat oleh pengguna API / pengembang baru. Karena kemungkinan tidak semua parameter memiliki
.
di dalamnya, itu juga dapat membuat bug berselangsumber
Di Spring Boot Rest Controller, saya telah menyelesaikan ini dengan Langkah-langkah berikut:
RestController:
Dan Dari Istirahat Klien:
sumber
menambahkan ":. +" bekerja untuk saya, tetapi tidak sampai saya menghapus kurung keriting luar.
value = { "/username/{id:.+}" } tidak berfungsi
value = "/username/{id:.+}" berfungsi
Semoga saya membantu seseorang :)
sumber
id
/somepath/{variable:.+}
bekerja direquestMapping
tag Java .sumber
"/{code:.+}"
bekerja untuk banyak titik bukan satu yaitu61.12.7
juga berfungsi untuk yaitu[email protected]
Berikut ini pendekatan yang sepenuhnya bergantung pada konfigurasi java:
sumber
Salah satu cara yang cukup mudah untuk mengatasi masalah ini adalah menambahkan garis miring ...
misalnya:
gunakan:
dari pada:
sumber
Di Spring Boot, Ekspresi Reguler menyelesaikan masalah seperti
sumber
"/{code:.+}"
bekerja untuk banyak titik bukan satu yaitu61.12.7
juga berfungsi untuk yaitu[email protected]
Solusi lengkap termasuk alamat email dalam nama jalur untuk pegas 4.2 adalah
Tambahkan ini ke aplikasi-xml
sumber
Jika Anda menggunakan Spring 3.2.x dan
<mvc:annotation-driven />
, buat ini sedikitBeanPostProcessor
:Kemudian taruh ini di xml konfigurasi MVC Anda:
sumber
BeanPostProcessor
untuk ini. Jika Anda menggunakan,WebMvcConfigurationSupport
Anda dapat menggantirequestMappingHandlerMapping
@Bean
metode. Jika Anda menggunakan konfigurasi XML, Anda bisa mendeklarasikanRequestMappingHandlerMapping
kacang Anda sendiri dan mendeklarasikan properti itu.Akhirnya saya menemukan solusi di Spring Docs :
Menambahkan ini ke
WebMvcConfigurerAdapter
implementasi saya memecahkan masalah:sumber
Bagi saya itu
tidak berfungsi tetapi hanya jika Anda juga menyandikan "titik" di url permintaan Anda sebagai "% 2E" maka itu berfungsi. Tetapi mengharuskan URL untuk semua itu ... yang bukan pengkodean "standar", meskipun valid. Terasa seperti bug: |
Pekerjaan lain di sekitar, mirip dengan cara "trailing slash" adalah dengan memindahkan variabel yang akan memiliki titik "inline" ex:
@GetMapping (path = "/ {variableName} / a")
sekarang semua titik akan dilestarikan, tidak ada modifikasi atau diperlukan regex.
sumber
Pada Spring 5.2.4 (Spring Boot v2.2.6.RELEASE)
PathMatchConfigurer.setUseSuffixPatternMatch
danContentNegotiationConfigurer.favorPathExtension
telah ditinggalkan ( https://spring.io/blog/2020/03/24/spring-framework-5-2-5-available-now and https://github.com/spring-projects/spring-framework/issues/24179 ).Masalah sebenarnya adalah bahwa klien meminta jenis media tertentu (seperti .com) dan Spring menambahkan semua jenis media secara default. Dalam kebanyakan kasus, kontroler REST Anda hanya akan menghasilkan JSON sehingga tidak akan mendukung format output yang diminta (.com). Untuk mengatasi masalah ini, Anda harus baik-baik saja dengan memperbarui pengontrol istirahat Anda (atau metode tertentu) untuk mendukung format 'ouput' (
@RequestMapping(produces = MediaType.ALL_VALUE
)) dan tentu saja mengizinkan karakter seperti titik ({username:.+}
).Contoh:
Pegas 5.3 dan di atasnya hanya akan cocok dengan sufiks yang terdaftar (tipe media).
sumber