Spring MVC - การขอ params ทั้งหมดในแผนที่ใน Spring controller ได้อย่างไร


183

URL ตัวอย่าง:

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

ฉันไม่รู้จักชื่อของ attr1, att2 และ attr4

ฉันต้องการที่จะสามารถทำอะไรเช่นนั้น (หรือคล้ายกันไม่สนใจตราบใดที่ฉันสามารถเข้าถึงแผนที่ชื่อพารามิเตอร์ขอ - มูลค่า>:

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

ฉันจะบรรลุสิ่งนี้ด้วย Spring MVC ได้อย่างไร

คำตอบ:


310

ในขณะที่คำตอบอื่น ๆ นั้นถูกต้องแน่นอนว่าไม่ใช่ "Spring way" ในการใช้วัตถุ HttpServletRequest โดยตรง คำตอบนั้นง่ายมากและสิ่งที่คุณคาดหวังหากคุณคุ้นเคยกับ Spring MVC

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

41
หากคุณกำลังมองหาการประมวลผลรายการค่าเช่นจากกลุ่มของช่องทำเครื่องหมายที่มีชื่อเดียวกันใช้: @RequestParam MultiValueMap<String, String>
IcedDante

1
ขอบคุณสำหรับสิ่งนี้. คุณสามารถทำสิ่งเดียวกันกับส่วนหัวได้เช่น: stackoverflow.com/a/19556291/2599745
Rob Worsnop

3
สิ่งนี้ใช้ได้เฉพาะเมื่อวิธีการร้องขอเป็น GET หรือ POST มันไม่ทำงานสำหรับวิธีการร้องขอการลบลบ ฯลฯ
George Siggouroglou

อย่าลืมที่จะเพิ่มimport org.springframework.ui.ModelMap;เช่นกัน
trueadjustr

@typelogic ModelMapไม่จำเป็นต้องขอ params ตามแผนที่ทั้งหมด นั่นเป็นเพียงรายละเอียดเฉพาะของรหัสของ OP
xlm

34

แก้ไข

มันชี้ให้เห็นว่ามีอยู่ ( อย่างน้อยที่สุด 3.0 ) กลไกสปริง MVC ล้วนๆที่ใครจะได้รับข้อมูลนี้ ฉันจะไม่ให้รายละเอียดได้ที่นี่เนื่องจากเป็นคำตอบของผู้ใช้รายอื่น ดูคำตอบของ @ AdamGentสำหรับรายละเอียดและอย่าลืม upvote

ในเอกสาร Spring 3.2 กลไกนี้ถูกกล่าวถึงในRequestMappingหน้า JavaDoc และRequestParamหน้า JavaDoc แต่ก่อนหน้าจะกล่าวถึงเฉพาะในRequestMappingหน้า ในเอกสาร 2.5 ไม่มีการกล่าวถึงกลไกนี้

นี่น่าจะเป็นแนวทางที่เหมาะสมสำหรับนักพัฒนาส่วนใหญ่เนื่องจากเป็นการลบ (อย่างน้อยที่สุด) เข้ากับHttpServletRequestวัตถุที่กำหนดโดย servlet-api jar

/ แก้ไข

request.getQueryString()คุณควรจะมีการเข้าถึงสตริงร้องขอแบบสอบถามผ่านทาง

นอกเหนือจาก getQueryString พารามิเตอร์เคียวรียังสามารถดึงจากrequest.getParameterMap ()เป็น Map


12
ฉันสงสัยว่ามีคน downvote คำตอบนี้เพียงเพราะ getQueryString ส่งกลับสตริงและไม่ใช่แผนที่ op กำลังค้นหา Map of parameters ฉันได้เพิ่ม getParameterMap ให้กับคำตอบของคุณเพื่อช่วยแก้ไขให้ถูกต้องมากขึ้น :) +1
jmort253

ไม่ฉันลงคะแนนเพราะไม่ใช่วิธี Spring MVC ที่จะทำ @RequestParamจะยินดีMapเป็นพารามิเตอร์ (ดูคำตอบของฉัน)
Adam Gent

@ AdamGent คำถามถูกถามในเวลาที่ Spring 3.2 ยังไม่ออก ย้อนกลับไปดู JavaDoc สำหรับ 3.1 และคุณจะสังเกตเห็นว่าไม่มีการกล่าวถึงการใช้@RequestParama Map<String,String>เพื่อดึงพารามิเตอร์สตริงการสืบค้นทั้งหมด และโปรดอย่ารู้สึกเพื่อให้เกลียดชังมากกว่าคำตอบที่คุณดูที่นี่ ... พวกเขาไม่ได้ว่าไม่ดี :) static.springsource.org/spring/docs/3.1.x/javadoc-api/org/...
นิโคลัส hauschild

ฉันคิดว่ามันมีอยู่ใน 3.1 แต่ไม่ใช่ JavaDoced ฉันไม่ได้บอกว่าฉันถูกรังเกียจแต่ตกใจว่า@RequestParam Map<>วิธีการไม่ได้ทำ ฉันมีความรำคาญเล็กน้อยในโครงการสมัยใหม่หลายแห่งที่ฉันเห็น Spring MVC (ฤดูใบไม้ผลิ 3.1 และสูงกว่า) พวกเขาจะใส่ HttpServletRequest และ HttpServletResponse ในทุกวิธี และดูเหมือนว่าเป็นเพราะนักพัฒนารุ่นน้องใช้ StackOverflow และ google แทนที่จะดูเอกสาร สิ่งนี้ทำให้เป็นการยากสำหรับโครงการ Spring ที่จะเปลี่ยนจาก servlet api เพื่อบอก Netty API JAX-RS มีปัญหาการละเมิดที่คล้ายกัน แต่ในระดับที่น้อยกว่ามาก
Adam Gent

และมันก็เป็นJavaDoced ใน 3.1 ที่ไม่ได้อยู่ในตำแหน่งที่ถูกต้องทั้งหมด: " นอกจากนี้ @RequestParam สามารถใช้กับ Map <String, String> หรือ MultiValueMap <String, String> พารามิเตอร์วิธีการเพื่อเข้าถึงพารามิเตอร์การร้องขอทั้งหมด " Infact มันจะย้อนกลับไปสู่เวอร์ชั่น 3.0 (ฉันรู้ว่าฉันใช้ก่อนหน้า 3.1) ความรำคาญของฉันยังคงอยู่ในที่ที่ผู้คนไม่ได้สนใจที่จะทำวิจัย :)
อดัม Gent

14

วัตถุ HttpServletRequest มีแผนที่ของพารามิเตอร์อยู่แล้ว ดูที่request.getParameterMap ()สำหรับรายละเอียดเพิ่มเติม


1
รับการแมปพารามิเตอร์จะมีข้อมูลแบบฟอร์มจากคำขอ POST หากผู้ใช้ไม่ทราบคีย์ในสตริงการสืบค้นดังนั้นพวกเขาจะสามารถแยกความแตกต่างระหว่างสิ่งที่มาจากสตริงการสืบค้นและสิ่งที่มาจากข้อมูลจากเนื้อความ POST ได้อย่างไร
nicholas.hauschild

คุณกำลังบอกฉันว่าคุณกำลังจะประมวลผลโพสต์ฟอร์ม แต่คุณไม่รู้ว่าพารามิเตอร์ฟอร์มจริงคืออะไร
เควิน

2
คำถามระบุว่าเขาไม่ทราบว่าชื่อพารามิเตอร์คืออะไร นอกจากนี้ฉันไม่ทราบว่าพวกเขาเป็นอย่างไร ;)
nicholas.hauschild

ขออภัยฉันพบหลักฐานที่ไร้สาระเล็กน้อย
เควิน

11
มันสมเหตุสมผลในแอพพลิเคชั่นที่ขับเคลื่อนด้วยข้อมูล ที่หนึ่งที่คำขอเส้นทางและสตริงแบบสอบถามสามารถสร้างขึ้นโดยไคลเอนต์และแอปพลิเคชันเซิร์ฟเวอร์จะค้นหาค่าที่สอดคล้องกัน (จากแหล่งข้อมูลประเภทใด ๆ ) โดยใช้เส้นทางและสตริงแบบสอบถามเหล่านี้เป็นคีย์
nicholas.hauschild

12

คุณสามารถใช้สิ่งนี้:

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

ที่ควรจะทำงานได้ดี


10

นี่คือตัวอย่างง่ายๆของการขอพารามิเตอร์ในแผนที่

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

ในกรณีนี้มันจะผูกค่า studentName และ studentEmail ด้วยชื่อและตัวแปรอีเมลตามลำดับ


8

ใช้org.springframework.web.context.request.WebRequestเป็นพารามิเตอร์ในวิธีการควบคุมของคุณมันให้วิธีgetParameterMap()การข้อดีคือคุณไม่แน่นแอปพลิเคชันของคุณกับ Servlet API, WebRequest เป็นตัวอย่างของวัตถุบริบทรูปแบบ JavaEE


6

มีสองอินเตอร์เฟส

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

อนุญาตสำหรับการเข้าถึงพารามิเตอร์คำขอทั่วไปรวมถึงrequest/sessionการเข้าถึงแอททริบิวโดยไม่เชื่อมโยงกับ Servlet / Portlet APIดั้งเดิม

อดีต .:

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

PS มีเอกสารเกี่ยวกับข้อโต้แย้งที่สามารถใช้เป็นตัวควบคุมพารามิเตอร์


ขอบคุณมันได้ผล ฉันขอถามได้ว่าอะไรคือString[]คุณค่าของคุณค่า? ฉันต้องทำดัชนีให้เป็น 0 เพียงเพื่อให้ได้ค่า
trueadjustr

อาจมีอาร์เรย์ของค่าเช่นkey=val1,val2หรือkey=val1&key=val2(ถ้าฉันจำสปริงรองรับการแสดงทั้งสองอย่างถูกต้อง) ดังนั้นคุณจะได้อาร์เรย์ที่มี 2 องค์ประกอบ
katoquro

6

ฉันอาจไปงานปาร์ตี้สาย แต่ตามความเข้าใจของฉันคุณกำลังมองหาบางสิ่งเช่นนี้:

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

params jsonObjectทั้งหมดจะถูกเก็บไว้ใน


1

มีความแตกต่างพื้นฐานระหว่างพารามิเตอร์แบบสอบถามและพารามิเตอร์เส้นทาง มันจะเป็นเช่นนี้: www.your_domain?queryparam1=1&queryparam2=2- พารามิเตอร์การสืบค้น www.your_domain/path_param1/entity/path_param2- พารามิเตอร์พา ธ

สิ่งที่ฉันพบที่น่าประหลาดใจคือใน Spring MVC โลกผู้คนมากมายสับสนกัน ในขณะที่พารามิเตอร์เคียวรีเป็นเหมือนเกณฑ์สำหรับการค้นหาพารามิเตอร์พา ธ ส่วนใหญ่จะระบุทรัพยากรโดยไม่ซ้ำกัน ต้องบอกว่านั่นไม่ได้หมายความว่าคุณไม่สามารถมีพารามิเตอร์หลายพา ธ ใน URI ของคุณได้เนื่องจากโครงสร้างทรัพยากรสามารถซ้อนกันได้ ตัวอย่างเช่นสมมติว่าคุณต้องการทรัพยากรรถยนต์เฉพาะของบุคคลที่ระบุ:

www.my_site/customer/15/car/2 - กำลังมองหารถยนต์คันที่สองของลูกค้ารายที่ 15

สิ่งที่จะเป็น usecase ที่จะนำพารามิเตอร์เส้นทางทั้งหมดลงในแผนที่? พารามิเตอร์พา ธ ไม่มี "คีย์" เมื่อคุณดู URI เองคีย์เหล่านั้นในแผนที่จะถูกนำมาจากคำอธิบายประกอบ @Mapping ของคุณตัวอย่างเช่น:

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

จากพารามิเตอร์พา ธ มุมมอง HTTP / REST ไม่สามารถฉายลงบนแผนที่ได้จริงๆ มันเป็นเรื่องของความยืดหยุ่นของสปริงและความปรารถนาของพวกเขาในการรองรับนักพัฒนาใด ๆ ในความคิดของฉัน

ฉันจะไม่ใช้แผนที่สำหรับพารามิเตอร์พา ธ แต่มันมีประโยชน์มากสำหรับพารามิเตอร์เคียวรี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.