การผูกรายการใน @RequestParam


127

ฉันกำลังส่งพารามิเตอร์จากแบบฟอร์มด้วยวิธีนี้:

myparam[0]     : 'myValue1'
myparam[1]     : 'myValue2'
myparam[2]     : 'myValue3'
otherParam     : 'otherValue'
anotherParam   : 'anotherValue' 
...

ฉันรู้ว่าฉันสามารถรับพารามิเตอร์ทั้งหมดในเมธอดคอนโทรลเลอร์ได้โดยการเพิ่มพารามิเตอร์เช่น

public String controllerMethod(@RequestParam Map<String, String> params){
    ....
}

ฉันต้องการผูกพารามิเตอร์ myParam [] (ไม่ใช่พารามิเตอร์อื่น ๆ ) กับรายการหรืออาร์เรย์ (อะไรก็ตามที่เก็บลำดับดัชนี) ดังนั้นฉันจึงลองใช้ไวยากรณ์เช่น:

public String controllerMethod(@RequestParam(value="myParam") List<String> myParams){
    ....
}

และ

public String controllerMethod(@RequestParam(value="myParam") String[] myParams){
    ....
}

แต่ไม่มีข้อใดผูกมัด myParams แม้ว่าฉันจะเพิ่มค่าให้กับแผนที่ แต่ก็ไม่สามารถผูกพารามิเตอร์ได้:

public String controllerMethod(@RequestParam(value="myParam") Map<String, String> params){
    ....
}

มีไวยากรณ์ใดบ้างที่จะผูกพารามิเตอร์บางตัวเข้ากับรายการหรืออาร์เรย์โดยไม่ต้องสร้างวัตถุเป็น @ModelAttribute โดยมีแอตทริบิวต์รายการอยู่

ขอบคุณ


ฉันไม่คิดว่าจะเป็นไปได้ รหัสในHandlerMethodInvoker.resolveRequestParamจะได้รับค่าแรกเท่านั้น
skaffman

6
( Spring Boot ): เกี่ยวกับmethod = RequestMethod.GETหรือmethod = RequestMethod.POST? หาก.GET @RequestParam List<String> groupValทำ?groupVal=kkk,ccc,mmmสำเร็จ ( Spring Boot )
โหระพา

คำตอบ:


77

อาร์เรย์@RequestParamใช้สำหรับการเชื่อมโยงหลายพารามิเตอร์ที่มีชื่อเดียวกัน:

myparam=myValue1&myparam=myValue2&myparam=myValue3

หากคุณต้องการผูก@ModelAttributeพารามิเตอร์ที่จัดทำดัชนีสไตล์ฉันเดาว่าคุณต้องการ@ModelAttributeอยู่ดี


1
อาจมีปัญหากับคำสั่งซื้อ (ซึ่งสำคัญมากที่จะต้องเก็บไว้ในกรณีของฉัน) เนื่องจากฉันส่งพารามิเตอร์โดยการทำให้เป็นอนุกรมแบบฟอร์มและส่งฉันด้วย ajax ฉันจะใช้วิธี @ModelAttribute "ดั้งเดิม"
Javi

คุณจะรู้วิธีสร้าง URI ด้วยการแมปการเรียงลำดับนี้ด้วย UriTemplate หรือวิธีอื่น ๆ หรือไม่? (สำหรับลูกค้าของทรัพยากรประเภทนี้)
Chomeh

เมื่อตอบคำถามของฉันเองมันรู้สึกว่าสปริง UriTemplate ไม่รองรับ RFC6570 ใช้การใช้งานที่น่ากลัว: stackoverflow.com/questions/14153036/…
Chomeh

110

หรือคุณสามารถทำได้ด้วยวิธีนี้:

public String controllerMethod(@RequestParam(value="myParam[]") String[] myParams){
    ....
}

ที่ใช้งานได้เช่นสำหรับรูปแบบเช่นนี้:

<input type="checkbox" name="myParam[]" value="myVal1" />
<input type="checkbox" name="myParam[]" value="myVal2" />

นี่เป็นทางออกที่ง่ายที่สุด :)


4
นั่นเป็นการรักษาคำสั่งหรือไม่?
andrew cooke

7
ฉันสามารถใช้แค่ชื่อแทน [] ใน Spring 3.0 ดังนั้น: @RequestParam (value = "myParam") String [] myParams
M Smith

3
ฉันไม่แบ่งปันสิ่งที่ค้นพบของ @MSmith
น้ำลายไหล

2
เป็นไปได้ไหมที่จะได้รับList<String>ผ่านทางนี้ นอกจากนี้ยังสามารถรับ java bean เช่นList<MyBean>
Juzer Ali

3
ฉันคิดว่าคุณสามารถลบวงเล็บออกจากชื่อพารามิเตอร์ได้
theblang

19

เพียงเติมเต็มสิ่งที่ Donal Fellows กล่าวคุณสามารถใช้ List กับ @RequestParam ได้

public String controllerMethod(@RequestParam(value="myParam") List<ObjectToParse> myParam){
....
}

หวังว่าจะช่วยได้!


12

สมัครสมาชิกสิ่งที่ใบโหระพาพูดในความคิดเห็นของคำถามนั้นหากmethod = RequestMethod.GETคุณสามารถ@RequestParam List<String> groupValใช้ได้

จากนั้นการเรียกใช้บริการด้วยรายการพารามิเตอร์นั้นง่ายมากดังนี้:

API_URL?groupVal=kkk,ccc,mmm

10

วิธีหนึ่งที่คุณสามารถทำสิ่งนี้ให้สำเร็จได้ (ด้วยวิธีแฮ็ก) คือการสร้างคลาส Wrapper สำหรับไฟล์List. แบบนี้:

class ListWrapper {
     List<String> myList; 
     // getters and setters
}

ลายเซ็นวิธีควบคุมของคุณจะมีลักษณะดังนี้:

public String controllerMethod(ListWrapper wrapper) {
    ....
}

ไม่จำเป็นต้องใช้@RequestParamหรือ@ModelAttributeคำอธิบายประกอบหากชื่อคอลเล็กชันที่คุณส่งในคำขอตรงกับชื่อฟิลด์คอลเลกชันของคลาส wrapper ในตัวอย่างของฉันพารามิเตอร์คำขอของคุณควรมีลักษณะดังนี้:

myList[0]     : 'myValue1'
myList[1]     : 'myValue2'
myList[2]     : 'myValue3'
otherParam    : 'otherValue'
anotherParam  : 'anotherValue'

นี่เกือบจะเหมือนกับการใช้ @ModelAttribute ข้อแตกต่างเพียงอย่างเดียวคือพารามิเตอร์ไม่ได้ใส่คำอธิบายประกอบ ฉันต้องการหลีกเลี่ยง @ModelAttribute เพียงเพราะฉันไม่ต้องการสร้าง Wrapper ฉันอ่านที่ไหนสักแห่งใน stackoverflow (ฉันจำไม่ได้ว่าอยู่ที่ไหน) ว่าถ้าคุณเพิ่มพารามิเตอร์ในวิธีการควบคุมโดยไม่มีคำอธิบายประกอบ @ModelAttribute (และไม่ใช่วัตถุพิเศษเช่น HttpRequest, HttpResponse ... ) เฟรมเวิร์กจะถือว่าเป็น หากมีการใส่คำอธิบายประกอบด้วย @ModelAttribute ดังนั้นถ้าเป็นจริงนี่เท่ากับว่ามี @ModelAttribute แต่ขอบคุณสำหรับคำตอบ
Javi

4

มันไม่ได้เป็นที่เห็นได้ชัดกับผมว่าถึงแม้ว่าคุณสามารถยอมรับการเก็บเป็นพารามิเตอร์การร้องขอ แต่ในด้านของผู้บริโภคคุณยังคงต้องผ่านในรายการคอลเลกชันเป็นคั่นด้วยเครื่องหมายจุลภาค

ตัวอย่างเช่นถ้า api ฝั่งเซิร์ฟเวอร์มีลักษณะดังนี้:

@PostMapping("/post-topics")
public void handleSubscriptions(@RequestParam("topics") Collection<String> topicStrings) {

    topicStrings.forEach(topic -> System.out.println(topic));
}

การส่งผ่านคอลเลกชันไปยัง RestTemplate โดยตรงเป็น RequestParam ดังต่อไปนี้จะทำให้ข้อมูลเสียหาย

public void subscribeToTopics() {

    List<String> topics = Arrays.asList("first-topic", "second-topic", "third-topic");

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.postForEntity(
            "http://localhost:8088/post-topics?topics={topics}",
            null,
            ResponseEntity.class,
            topics);
}

แต่คุณสามารถใช้

public void subscribeToTopics() {

    List<String> topicStrings = Arrays.asList("first-topic", "second-topic", "third-topic");
    String topics = String.join(",",topicStrings);

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.postForEntity(
            "http://localhost:8088/post-topics?topics={topics}",
            null,
            ResponseEntity.class,
            topics);
}

ตัวอย่างที่สมบูรณ์สามารถพบได้ที่นี่หวังว่าจะช่วยให้ใครบางคนปวดหัว :)


-7

เปลี่ยนค่าฟิลด์ที่ซ่อนด้วยการสลับช่องทำเครื่องหมายด้านล่าง ...

HTML:

<input type='hidden' value='Unchecked' id="deleteAll" name='anyName'>
<input type="checkbox"  onclick="toggle(this)"/> Delete All

สคริปต์:

function toggle(obj) {`var $input = $(obj);
    if ($input.prop('checked')) {

    $('#deleteAll').attr( 'value','Checked');

    } else {

    $('#deleteAll').attr( 'value','Unchecked');

    }

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