Saya memiliki pengontrol yang menyediakan akses tenang ke informasi:
@RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName}")
public ModelAndView getBlah(@PathVariable String blahName, HttpServletRequest request,
HttpServletResponse response) {
Masalah yang saya alami adalah bahwa jika saya menekan server dengan variabel path dengan karakter khusus itu akan terpotong. Misalnya: http: // localhost: 8080 / blah-server / blah / get / blah2010.08.19-02: 25: 47
Parameter blahName akan menjadi blah2010.08
Namun, panggilan untuk meminta.getRequestURI () berisi semua informasi yang disampaikan.
Tahu cara mencegah Spring memotong @PathVariable?
Jawaban:
Coba ekspresi reguler untuk
@RequestMapping
argumen:sumber
Ini mungkin terkait erat dengan SPR-6164 . Secara singkat, kerangka kerja mencoba menerapkan beberapa kecerdasan ke interpretasi URI, menghapus apa yang dianggapnya sebagai ekstensi file. Ini akan memiliki efek berubah
blah2010.08.19-02:25:47
menjadiblah2010.08
, karena dianggap.19-02:25:47
ekstensi file.Seperti dijelaskan dalam masalah yang ditautkan, Anda dapat menonaktifkan perilaku ini dengan mendeklarasikan
DefaultAnnotationHandlerMapping
bean Anda sendiri dalam konteks aplikasi, dan menyeteluseDefaultSuffixPattern
propertinya kefalse
. Ini akan mengesampingkan perilaku default, dan menghentikannya mencabuli data Anda.sumber
RequestMappingHandlerMapping
, properti yang akan diatur adalahuseSuffixPatternMatch
(juga kefalse
). @Ted: masalah terkait menyebutkan bahwa dalam 3.2 mereka berharap untuk menambahkan sedikit lebih banyak kontrol sehingga tidak harus semuanya atau tidak sama sekali.WebMvcConfigurationSupport
yang menyediakan pengait sederhana:public void configurePathMatch(PathMatchConfigurer configurer)
- cukup timpa itu dan atur jalur yang sesuai dengan keinginan Anda.Spring menganggap bahwa apa pun di belakang titik terakhir adalah ekstensi file seperti
.json
atau.xml
dan memotongnya untuk mengambil parameter Anda.Jadi, jika Anda memiliki
/{blahName}
:/param
,/param.json
,/param.xml
Atau/param.anything
akan menghasilkan param dengan nilaiparam
/param.value.json
,/param.value.xml
atau/param.value.anything
akan menghasilkan param dengan nilaiparam.value
Jika Anda mengubah pemetaan menjadi
/{blahName:.+}
seperti yang disarankan, titik apa pun, termasuk yang terakhir, akan dianggap sebagai bagian dari parameter Anda:/param
akan menghasilkan param dengan nilaiparam
/param.json
akan menghasilkan param dengan nilaiparam.json
/param.xml
akan menghasilkan param dengan nilaiparam.xml
/param.anything
akan menghasilkan param dengan nilaiparam.anything
/param.value.json
akan menghasilkan param dengan nilaiparam.value.json
Jika Anda tidak peduli dengan pengenalan ekstensi, Anda dapat menonaktifkannya dengan mengesampingkan
mvc:annotation-driven
automagic:Jadi, sekali lagi, jika Anda memiliki
/{blahName}
:/param
,/param.json
,/param.xml
Atau/param.anything
akan menghasilkan param dengan nilaiparam
/param.value.json
,/param.value.xml
atau/param.value.anything
akan menghasilkan param dengan nilaiparam.value
Catatan: perbedaan dari konfigurasi default hanya terlihat jika Anda memiliki pemetaan seperti
/something.{blahName}
. Lihat masalah proyek Resthub .Jika Anda ingin mempertahankan manajemen ekstensi, sejak Spring 3.2 Anda juga dapat mengatur properti useRegisteredSuffixPatternMatch dari RequestMappingHandlerMapping bean untuk menjaga suffixPattern pengenalan diaktifkan tetapi terbatas pada ekstensi 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 ).
Karena 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 tertarik.
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 dan https: // github.com/resthub/resthub-spring-stack/issues/217
sumber
Semuanya setelah titik terakhir ditafsirkan sebagai ekstensi file dan terpotong secara default.
Dalam pegas konfigurasi xml Anda, Anda dapat menambah
DefaultAnnotationHandlerMapping
dan mengaturuseDefaultSuffixPattern
kefalse
(default adalahtrue
).Jadi buka xml pegas Anda
mvc-config.xml
(atau bagaimanapun disebut) dan tambahkanSekarang
@PathVariable
blahName
(dan semua yang lain juga) harus berisi nama lengkap termasuk semua titik.EDIT: Berikut ini tautan ke api musim semi
sumber
<mvc:annotation-driven />
jika berlaku.Saya juga mengalami masalah yang sama, dan mengatur properti ke false juga tidak membantu saya. Namun, API mengatakan :
Saya mencoba menambahkan "/ akhiri" ke URL TETAP saya, dan masalahnya hilang. Saya tidak senang dengan solusinya, tetapi itu berhasil.
BTW, saya tidak tahu apa yang dipikirkan desainer Spring ketika mereka menambahkan "fitur" ini dan kemudian menyalakannya secara default. IMHO, itu harus dihapus.
sumber
Menggunakan kelas konfigurasi Java yang benar:
sumber
Saya diselesaikan dengan hack ini
1) Menambahkan HttpServletRequest di @PathVariable seperti di bawah ini
2) Dapatkan URL secara langsung (Pada tingkat ini tidak ada pemotongan) dalam permintaan
Spring MVC @PathVariable dengan dot (.) Semakin terpotong
sumber
Saya hanya mengalami ini dan solusi di sini umumnya tidak berfungsi seperti yang saya harapkan.
Saya sarankan menggunakan ekspresi SpEL dan beberapa pemetaan, misalnya
sumber
Masalah ekstensi file hanya ada jika parameternya ada di bagian terakhir URL. Perubahan
untuk
dan semua akan baik-baik saja-
sumber
Jika Anda dapat mengedit alamat yang dikirimi permintaan, perbaikan sederhana adalah dengan menambahkan garis miring padanya (dan juga dalam
@RequestMapping
nilainya):sehingga pemetaan akan terlihat seperti:
Lihat juga Spring MVC @PathVariable dengan dot (.) Semakin terpotong .
sumber
sumber
menambahkan ":. +" bekerja untuk saya, tetapi tidak sampai saya menghapus kurung keriting luar.
value = {"/username/{id:.+}"}
tidak bekerjavalue = "/username/{id:.+}"
bekerjaSemoga saya membantu seseorang:]
sumber
Solusi konfigurasi berbasis Java untuk mencegah pemotongan (menggunakan kelas yang tidak usang):
Sumber: http://www.javacodegeeks.com/2013/01/spring-mvc-customizing-requestmappinghandlermapping.html
MEMPERBARUI:
Saya menyadari ada beberapa masalah dengan konfigurasi otomatis Boot Musim Semi ketika saya menggunakan pendekatan di atas (beberapa konfigurasi otomatis tidak menjadi efektif).
Sebaliknya, saya mulai menggunakan
BeanPostProcessor
pendekatan itu. Tampaknya bekerja lebih baik.Terinspirasi dari: http://ronaldxq.blogspot.com/2014/10/spring-mvc-setting-alwaysusefullpath-on.html
sumber
jika Anda yakin teks Anda tidak akan cocok dengan ekstensi default apa pun, Anda dapat menggunakan kode di bawah ini:
sumber
Solusi saya yang lebih disukai untuk mencegah Spring MVC @PathVariable untuk terpotong adalah dengan menambahkan trailing slash di akhir variabel path.
Sebagai contoh:
Jadi, permintaan akan terlihat seperti:
sumber
Masalah yang Anda hadapi adalah karena menafsirkan pegas itu terakhir bagian dari uri setelah itu titik (.) Sebagai ekstensi file seperti .json atau .xml. Jadi ketika pegas mencoba untuk menyelesaikan variabel path, ia hanya memotong sisa data setelah menemukan titik (.) Di akhir uri. catatan: ini juga terjadi hanya jika Anda menyimpan variabel path di akhir uri.
Misalnya pertimbangkan uri: https: //localhost/example/gallery.df/link.ar
Dalam url di atas firstValue = "gallery.df" dan secondValue = "tautan", bit terakhir setelah. akan terpotong ketika variabel path ditafsirkan.
Jadi, untuk mencegahnya ada dua cara yang mungkin:
1.) Menggunakan pemetaan regexp
Gunakan regex di bagian akhir pemetaan
Dengan menggunakan +, kami menunjukkan nilai apa pun setelah titik juga akan menjadi bagian dari variabel path.
2.) Menambahkan garis miring di akhir @PathVariable kami
Ini akan menyertakan variabel kedua kami yang melindunginya dari perilaku default Spring.
3) Dengan mengesampingkan konfigurasi webmvc default Spring
Spring menyediakan cara untuk mengesampingkan konfigurasi default yang diimpor dengan menggunakan anotasi @EnableWebMvc . Kita dapat menyesuaikan konfigurasi Spring MVC dengan mendeklarasikan kacang DefaultAnnotationHandlerMapping kita sendiri dalam konteks aplikasi dan menyetel properti useDefaultSuffixPattern menjadi false. Contoh:
Perlu diingat bahwa mengesampingkan konfigurasi default ini, memengaruhi semua url.
Catatan: di sini kita memperluas kelas WebMvcConfigurationSupport untuk mengganti metode default. Ada satu cara lagi untuk mengganti konfigurasi deault dengan mengimplementasikan antarmuka WebMvcConfigurer. Untuk detail lebih lanjut tentang ini, baca: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/EnableWebMvc.html
sumber