Spring MVC - Bagaimana cara mendapatkan semua params permintaan di peta di Spring controller?

183

URL contoh:

../search/?attr1=value1&attr2=value2&attr4=value4

Saya tidak tahu nama attr1, att2, dan attr4.

Saya ingin dapat melakukan sesuatu seperti itu (atau serupa, tidak peduli, asalkan saya memiliki akses ke Peta nama parameter permintaan -> nilai:

@RequestMapping(value = "/search/{parameters}", method = RequestMethod.GET)
public void search(HttpServletRequest request, 
@PathVariable Map<String,String> allRequestParams, ModelMap model)
throws Exception {//TODO: implement}

Bagaimana saya bisa mencapai ini dengan Spring MVC?

MDb
sumber

Jawaban:

311

Sementara jawaban lain sudah benar itu tentu bukan "cara Spring" untuk menggunakan objek HttpServletRequest secara langsung. Jawabannya sebenarnya cukup sederhana dan apa yang Anda harapkan jika Anda terbiasa dengan Spring MVC.

@RequestMapping(value = {"/search/", "/search"}, method = RequestMethod.GET)
public String search(
@RequestParam Map<String,String> allRequestParams, ModelMap model) {
   return "viewName";
}
Adam Gent
sumber
41
Jika Anda mencari untuk memproses nilai daftar, seperti dari sekelompok kotak centang dengan nama yang sama, gunakan: @RequestParam MultiValueMap<String, String>
IcedDante
1
Terima kasih untuk ini. Anda dapat melakukan hal yang sama dengan tajuk juga: stackoverflow.com/a/19556291/2599745
Rob Worsnop
3
Ini hanya berfungsi ketika metode permintaan GET atau POST. Ini tidak berfungsi untuk metode permintaan PUT, DELETE dll.
George Siggouroglou
Jangan lupa untuk menambahkan import org.springframework.ui.ModelMap;juga.
truthadjustr
@typelogic ModelMaptidak diperlukan untuk mendapatkan semua params permintaan sebagai peta; itu hanya detail khusus untuk kode OP.
xlm
34

Edit

Telah ditunjukkan bahwa ada ( setidaknya pada 3.0 ) mekanisme Spring MVC murni dimana seseorang bisa mendapatkan data ini. Saya tidak akan menjelaskannya di sini, karena ini adalah jawaban dari pengguna lain. Lihat jawaban @ AdamGent untuk detailnya, dan jangan lupa untuk membatalkannya.

Dalam dokumentasi Spring 3.2 mekanisme ini disebutkan di RequestMappinghalaman JavaDoc dan RequestParamhalaman JavaDoc, tetapi sebelumnya, itu hanya disebutkan di RequestMappinghalaman. Dalam 2.5 dokumentasi tidak disebutkan mekanisme ini.

Ini kemungkinan merupakan pendekatan yang disukai untuk sebagian besar pengembang karena menghilangkan (setidaknya ini) mengikat ke HttpServletRequestobjek yang ditentukan oleh jar servlet-api.

/ Edit

Anda harus memiliki akses ke string kueri permintaan via request.getQueryString().

Selain getQueryString, parameter kueri juga dapat diambil dari request.getParameterMap () sebagai Peta.

nicholas.hauschild
sumber
12
Saya mencurigai seseorang menurunkan jawaban ini hanya karena getQueryString mengembalikan sebuah String dan bukan Peta. Op sedang mencari Peta parameter. Saya menambahkan getParameterMap ke jawaban Anda untuk membantu membuatnya lebih benar :) +1
jmort253
Tidak, saya downvoted karena ini bukan cara Spring MVC untuk melakukannya. @RequestParamakan dengan senang hati mengambil Mapsebagai parameter (lihat jawaban saya).
Adam Gent
@AdamGent Pertanyaan itu ditanyakan pada saat Spring 3.2 belum dirilis. Kembali dan lihat JavaDoc untuk 3.1, dan Anda akan melihat tidak ada yang menyebutkan penggunaan @RequestParampada Map<String,String>untuk mengambil semua parameter string kueri. Dan tolong, jangan merasa begitu dibenci atas jawaban yang Anda lihat di sini ... mereka tidak yang buruk :) static.springsource.org/spring/docs/3.1.x/javadoc-api/org/...
nicholas. hauschild
Saya pikir itu ada di 3.1 tetapi tidak JavaDoced. Saya tidak mengatakan saya dibenci tetapi terkejut bahwa @RequestParam Map<>jalan itu tidak dilakukan. Saya memiliki sedikit gangguan dalam banyak proyek modern yang saya lihat Spring MVC (semi 3.1 dan lebih tinggi) mereka akan menempatkan HttpServletRequest dan HttpServletResponse pada setiap metode. Dan sepertinya ini karena pengembang junior menggunakan StackOverflow dan google alih-alih melihat dokumen. Ini menyulitkan proyek Spring untuk beralih dari servlet api untuk mengucapkan Netty API. JAX-RS memiliki masalah penyalahgunaan yang serupa tetapi pada tingkat yang jauh lebih rendah.
Adam Gent
Dan itu JavaDoced di 3.1 tidak hanya di semua tempat yang tepat: " Selain itu, @RequestParam dapat digunakan pada parameter metode Map <String, String> atau MultiValueMap <String, String> untuk mendapatkan akses ke semua parameter permintaan. ". Infact itu kembali ke versi 3.0 (saya tahu saya menggunakannya sebelum 3.1). Kekesalan saya masih ada pada orang-orang yang tidak repot melakukan penelitian :)
Adam Gent
14

Objek HttpServletRequest menyediakan peta parameter sudah. Lihat request.getParameterMap () untuk detail lebih lanjut.

Kevin
sumber
1
Dapatkan parameter peta juga akan berisi data formulir dari permintaan POST. Jika pengguna tidak tahu kunci dalam string kueri, lalu bagaimana mereka dapat membedakan antara apa yang berasal dari string kueri dan apa yang dari data dari badan POST?
nicholas.hauschild
Apakah Anda memberi tahu saya bahwa Anda akan memproses kiriman formulir tetapi Anda tidak tahu apa parameter formulir yang sebenarnya?
Kevin
2
Pertanyaannya menyatakan bahwa dia tidak tahu apa nama parameternya. Saya juga tidak tahu apa itu. ;)
nicholas.hauschild
Maaf saya menemukan premis agak konyol.
Kevin
11
Masuk akal dalam aplikasi berbasis data. Di mana jalur permintaan dan string kueri dapat dibuat oleh klien, dan server aplikasi kemudian akan mencari nilai yang sesuai (dari segala jenis sumber data) dengan menggunakan jalur ini dan string kueri sebagai kunci.
nicholas.hauschild
12

Anda cukup menggunakan ini:

Map<String, String[]> parameters = request.getParameterMap();

Itu seharusnya bekerja dengan baik

Biggy_java
sumber
10

Ini adalah contoh sederhana dari mendapatkan permintaan params di Peta.

 @RequestMapping(value="submitForm.html", method=RequestMethod.POST)
     public ModelAndView submitForm(@RequestParam Map<String, String> reqParam) 
       {
          String name  = reqParam.get("studentName");
          String email = reqParam.get("studentEmail");

          ModelAndView model = new ModelAndView("AdmissionSuccess");
          model.addObject("msg", "Details submitted by you::
          Name: " + name + ", Email: " + email );
       }

Dalam hal ini, itu akan mengikat nilai studentName dan studentEmail dengan variabel nama dan email masing-masing.

Shrirang Kadale
sumber
8

Gunakan org.springframework.web.context.request.WebRequestsebagai parameter dalam metode controller Anda, itu menyediakan metode getParameterMap(), keuntungannya adalah Anda tidak mengencangkan aplikasi Anda ke Servlet API, WebRequest adalah contoh objek JavaEE Object Konteks.

Diego Lins de Freitas
sumber
6

Ada dua antarmuka

  1. org.springframework.web.context.request.WebRequest
  2. org.springframework.web.context.request.NativeWebRequest

Mengizinkan akses parameter permintaan umum serta request/sessionakses atribut, tanpa ikatan dengan API Servlet / Portlet asli .

Ex.:

@RequestMapping(value = "/", method = GET)
public List<T> getAll(WebRequest webRequest){
    Map<String, String[]> params = webRequest.getParameterMap();
    //...
}

PS Ada Documents tentang argumen yang dapat digunakan sebagai params Kontroler.

katoquro
sumber
Terima kasih itu berhasil. Bolehkah saya bertanya, apa gunanya String[]nilainya? Saya harus mengindeksnya ke 0 hanya untuk mendapatkan nilai.
truthadjustr
Mungkin ada array nilai seperti key=val1,val2atau key=val1&key=val2(jika saya ingat dengan benar pegas mendukung kedua notasi ini) sehingga Anda akan mendapatkan array dengan 2 elemen
katoquro
6

Saya mungkin terlambat ke pesta, tetapi sesuai pemahaman saya, Anda mencari sesuatu seperti ini:

for(String params : Collections.list(httpServletRequest.getParameterNames())) {
    // Whatever you want to do with your map
    // Key : params
    // Value : httpServletRequest.getParameter(params)                
}
goelanshul
sumber
2
@SuppressWarnings("unchecked")
Map<String,String[]> requestMapper=request.getParameterMap();
JsonObject jsonObject=new JsonObject();
for(String key:requestMapper.keySet()){
    jsonObject.addProperty(key, requestMapper.get(key)[0]);
}

Semua params akan disimpan di jsonObject.

Agyaey Tiwari
sumber
1

Ada perbedaan mendasar antara parameter kueri dan parameter jalur. Bunyinya seperti ini: www.your_domain?queryparam1=1&queryparam2=2- parameter kueri. www.your_domain/path_param1/entity/path_param2- parameter jalur.

Apa yang saya temukan mengejutkan adalah bahwa di dunia Spring MVC banyak orang bingung satu sama lain. Sementara parameter kueri lebih seperti kriteria untuk pencarian, params jalur kemungkinan besar akan secara unik mengidentifikasi sumber daya. Karena itu, itu tidak berarti bahwa Anda tidak dapat memiliki beberapa parameter lintasan di URI Anda, karena struktur sumber daya dapat disarangkan. Sebagai contoh, katakanlah Anda membutuhkan sumber daya mobil spesifik dari orang tertentu:

www.my_site/customer/15/car/2 - Mencari mobil kedua dari pelanggan ke-15.

Apa yang akan menjadi usecase untuk menempatkan semua parameter jalur ke peta? Parameter jalur tidak memiliki "kunci" ketika Anda melihat URI itu sendiri, kunci-kunci di dalam peta akan diambil dari penjelasan @ Pemetaan Anda, misalnya:

@GetMapping("/booking/{param1}/{param2}")

Dari HTTP / REST, parameter jalur perspektif tidak dapat diproyeksikan ke peta. Ini semua tentang fleksibilitas Spring dan keinginan mereka untuk mengakomodasi keinginan pengembang, menurut pendapat saya.

Saya tidak akan pernah menggunakan peta untuk parameter jalur, tetapi ini bisa sangat berguna untuk parameter kueri.

yuranos
sumber