Bahar MVC - Bahar denetleyicisi bir haritadaki tüm istek params nasıl alınır?


183

Örnek URL:

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

Attr1, att2 ve attr4 adlarını bilmiyorum.

Böyle bir şey yapabilmek istiyorum (ya da benzer, umurumda değil, sürece ben istek param adı Haritası erişim var -> değer:

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

Bunu Spring MVC ile nasıl başarabilirim?

Yanıtlar:


311

Diğer cevaplar doğru olsa da, doğrudan HttpServletRequest nesnesini kullanmak kesinlikle "Bahar yolu" değildir. Bu sorunun cevabı aslında oldukça basit ve Spring MVC hakkında bilginiz varsa ne beklenir .

@RequestMapping(value = {"/search/", "/search"}, method = RequestMethod.GET)
public String search(
@RequestParam Map<String,String> allRequestParams, ModelMap model) {
   return "viewName";
}

41
Aynı ada sahip bir grup onay kutusundan olduğu gibi liste değerlerini işlemek istiyorsanız şunu kullanın: @RequestParam MultiValueMap<String, String>
IcedDante

1
Bunun için teşekkürler. Aynı şeyi başlıklar için de yapabilirsiniz: stackoverflow.com/a/19556291/2599745
Rob Worsnop

3
Bu yalnızca istek yöntemi GET veya POST olduğunda çalışır. PUT, DELETE vb istek yöntemleri için çalışmıyor.
George Siggouroglou

Eklemeyi de unutmayın import org.springframework.ui.ModelMap;.
truthadjustr

@typelogic ModelMaptüm harita parametrelerini harita olarak almak için gerekli değildir; bu sadece OP koduna özgü bir detay.
xlm

34

Düzenle

Bu verilerin elde edilebileceği saf bir Spring MVC mekanizması ( en azından 3.0 itibariyle ) olduğu belirtilmiştir. Burada detaylandırmayacağım, çünkü başka bir kullanıcının cevabı. Ayrıntılar için @ AdamGent'in cevabına bakın ve oyunuzu yükseltmeyi unutmayın.

Bahar 3.2 belgelerinde bu mekanizma hem RequestMappingJavaDoc sayfasında hem de JavaDoc sayfasında belirtilmiştir RequestParam, ancak daha önce yalnızca RequestMappingsayfada belirtilmiştir . 2.5 dokümantasyonunda bu mekanizmadan bahsedilmemiştir.

HttpServletRequestServlet-api jar tarafından tanımlanan nesneye bağlanmayı (en azından bu) kaldırdığı için, bu muhtemelen çoğu geliştirici için tercih edilen yaklaşımdır .

/Düzenle

İstekler sorgu dizesine yoluyla erişebilmeniz gerekir request.getQueryString().

GetQueryString öğesine ek olarak, sorgu parametreleri de Map olarak request.getParameterMap () öğesinden alınabilir .


12
Birisi sadece getQueryString bir dize değil bir harita döndürür çünkü bu cevabı indirdi şüpheli. Operatör bir parametre haritası arıyordu. Daha doğru yapmak için cevabınıza getParameterMap ekledim :) +1
jmort253

Hayır ben bunu reddetti çünkü bunu yapmak için Bahar MVC yolu değil. @RequestParammemnuniyetle Mapbir parametre olarak alacaktır (cevabım bakınız).
Adam Gent

@AdamGent Soru, Bahar 3.2'nin henüz yayınlanmadığı bir zamanda soruldu. Geri dönün ve 3.1 JavaDoc bir göz atın ve tüm sorgu dizesi parametrelerini almak @RequestParamiçin bir kullanmanın böyle bir söz olduğunu fark edeceksiniz Map<String,String>. Ve lütfen, burada gördüğünüz cevaplar hakkında çok üzülmeyin ... o kadar da kötü değiller :) static.springsource.org/spring/docs/3.1.x/javadoc-api/org/…
nicholas. hauschild

Ben 3.1 yılında var olduğunu düşünüyorum ama JavaDoced değildi. Ben nefret edildiğimi söylemedim ama @RequestParam Map<>yolun yapılmadığı için şok oldum . Spring MVC (bahar 3.1 ve üstü) gördüğüm birçok modern projede HttpServletRequest ve HttpServletResponse'yi her yönteme koyacakları konusunda biraz can sıkıyorum. Görünüşe göre, genç geliştiriciler dokümana bakmak yerine StackOverflow ve google kullanıyor. Bu, Spring projesinin servlet api'den Netty API'sine geçmesini zorlaştırır. JAX-RS benzer istismar sorunlarına sahiptir ancak çok daha az derecede.
Adam Gent

Ve JavaDoced 3.1 sadece doğru yerlerde değil: " Ek olarak, @RequestParam tüm istek parametrelerine erişmek için bir Map <String, String> veya MultiValueMap <String, String> yöntem parametresinde kullanılabilir. ". Infact, 3.0 sürümüne kadar geri dönüyor (3.1'den önce kullandığımı biliyordum). Rahatsızlığım hala insanların araştırma yapma zahmetine girmediği anlamına geliyor :)
Adam Gent

14

HttpServletRequest nesnesi zaten parametrelerin bir haritasını sağlar. Daha fazla bilgi için request.getParameterMap () işlevine bakın .


1
Parametre eşlemesini al ayrıca bir POST isteğindeki form verilerini içerir. Kullanıcı sorgu dizesindeki anahtarları bilmiyorsa, o zaman sorgu dizesinden gelen ile POST gövdesindeki veriler arasında ne gibi bir ayrım yapabilir?
nicholas.hauschild

Bana bir form gönderisini işleyeceğinizi mi söylüyorsunuz, ancak gerçek form parametrelerinin ne olduğu hakkında hiçbir fikriniz yok mu?
Kevin

2
Soru, parametre adlarının ne olduğunu bilmediğini belirtir. Ayrıca, ne olduklarını da bilmiyorum. ;)
nicholas.hauschild

Üzgünüm öncülleri biraz saçma buluyorum.
Kevin

11
Veri odaklı bir uygulamada mantıklıdır. İstemci tarafından istek yollarının ve sorgu dizelerinin oluşturulabildiği ve uygulama sunucusunun, bu yolları ve sorgu dizelerini anahtar olarak kullanarak karşılık gelen değeri (her türlü veri kaynağından) arayacağı bir yer.
nicholas.hauschild

12

sadece bunu kullanabilirsiniz:

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

Güzel çalışmalı


10

İşte bir haritadaki istek parametrelerini almanın basit bir örneği .

 @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 );
       }

Bu durumda, studentName ve studentEmail'in değerini sırasıyla ad ve e-posta değişkenleriyle bağlar.


8

org.springframework.web.context.request.WebRequestDenetleyici yönteminizde bir parametre olarak kullanın , yöntem sağlar getParameterMap(), avantajı uygulamanızı Servlet API'sine sıkılaştırmamanızdır, WebRequest bir JavaEE desen Bağlam Nesnesi örneğidir.


6

İki arayüz var

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

Yerel Servlet / Portlet API'siyle bağları olmadan genel istek parametresi erişiminin yanı sıra request/sessionözellik erişimine de izin verir .

Ör .:

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

PS vardır Kontrolör params olarak kullanılabilecek argümanlar hakkında Dokümanlar.


Teşekkürler işe yarıyor. Sorabilir miyim String[], değer olarak anlamı nedir? Ben sadece değeri almak için 0 dizin.
truthadjustr

key=val1,val2Veya gibi bir dizi değer olabilir key=val1&key=val2(eğer bu yayların her ikisini de doğru şekilde desteklediğini hatırlıyorsam), böylece 2 elemanlı dizi elde edersiniz
katoquro

6

Partiye geç kalabilirim, ama anlayışım gereği böyle bir şey arıyorsunuz:

for(String params : Collections.list(httpServletRequest.getParameterNames())) {
    // Whatever you want to do with your map
    // Key : params
    // Value : httpServletRequest.getParameter(params)                
}

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]);
}

Tüm parametreler içinde depolanacaktır jsonObject.


1

Sorgu parametreleri ile yol parametreleri arasında temel fark vardır. Şu şekilde gider: www.your_domain?queryparam1=1&queryparam2=2- sorgu parametreleri. www.your_domain/path_param1/entity/path_param2- yol parametreleri.

Şaşırtıcı bulduğum şey, Bahar MVC dünyasında birçok insanın diğerini karıştırması. Sorgu parametreleri bir arama için ölçütlere benzemekle birlikte, yol parametreleri büyük olasılıkla bir kaynağı benzersiz olarak tanımlar. Bunu söyledikten sonra, URI'nizde birden fazla yol parametresine sahip olamayacağınız anlamına gelmez, çünkü kaynak yapısı yuvalanabilir. Örneğin, belirli bir kişinin belirli bir araba kaynağına ihtiyacınız olduğunu varsayalım:

www.my_site/customer/15/car/2 - 15. müşterinin ikinci bir arabasını aramak.

Tüm yol parametrelerini haritaya yerleştirmek için bir kullanıcı tabanı ne olurdu? Bir URI'nin kendisine baktığınızda yol parametrelerinin "anahtarı" yoktur, haritanın içindeki bu anahtarlar @Harita ek açıklamalarınızdan alınır, örneğin:

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

HTTP / REST perspektifinden yol parametreleri gerçekten bir haritaya yansıtılamaz. Her şey Spring'in esnekliği ve bence herhangi bir geliştiricinin kaprisine uyum sağlama arzusuyla ilgili.

Asla yol parametreleri için bir harita kullanmak istiyorum, ama sorgu parametreleri için oldukça yararlı olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.