Liên kết một danh sách trong @RequestParam


126

Tôi đang gửi một số tham số từ một biểu mẫu theo cách này:

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

Tôi biết tôi có thể nhận được tất cả các tham số trong phương thức điều khiển bằng cách thêm một tham số như

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

Tôi muốn liên kết các tham số myParam [] (không phải các tham số khác) vào một danh sách hoặc mảng (bất cứ thứ gì giữ thứ tự chỉ mục), vì vậy tôi đã thử với một cú pháp như:

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

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

nhưng không ai trong số họ ràng buộc myParams. Ngay cả khi tôi thêm một giá trị vào bản đồ, nó cũng không thể liên kết các thông số:

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

Có bất kỳ cú pháp nào để liên kết một số tham số vào một danh sách hoặc mảng mà không phải tạo một đối tượng là @ModelAttribution với một thuộc tính danh sách trong đó không?

Cảm ơn


Tôi không nghĩ rằng điều này là có thể. Mã HandlerMethodInvoker.resolveRequestParamchỉ bao giờ nhận được giá trị đầu tiên
skaffman

6
( Khởi động mùa xuân ): Là về method = RequestMethod.GEThay method = RequestMethod.POST? Nếu được .GET @RequestParam List<String> groupValthực hiện ?groupVal=kkk,ccc,mmmthành công ( Spring Boot )
húng quế

Câu trả lời:


76

Mảng trong @RequestParamđược sử dụng để liên kết một số tham số cùng tên:

myparam=myValue1&myparam=myValue2&myparam=myValue3

Nếu bạn cần liên kết @ModelAttributecác tham số được lập chỉ mục theo kiểu, tôi đoán @ModelAttributedù sao bạn cũng cần .


1
có thể có vấn đề với thứ tự (điều này rất quan trọng để giữ trong trường hợp của tôi) bởi vì tôi gửi các tham số bằng cách tuần tự hóa một biểu mẫu và gửi i với ajax. Tôi sẽ sử dụng cách "truyền thống" @ModelAttribution.
Javi

Bạn có biết làm thế nào để xây dựng một URI với ánh xạ sắp xếp này với UriTemplate hoặc một số phương tiện khác không? (đối với một khách hàng của loại tài nguyên này).
Chomeh

Trả lời câu hỏi của riêng tôi, nó apears mùa xuân UriTemplate không hỗ trợ RFC6570, sử dụng thực hiện damnhandy: stackoverflow.com/questions/14153036/...
Chomeh

110

Hoặc bạn có thể làm theo cách đó:

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

Đó là ví dụ cho các hình thức như thế này:

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

Đây là giải pháp đơn giản nhất :)


4
Điều đó có giữ gìn trật tự không?
kêu gọi

7
Do đó, tôi chỉ có thể sử dụng tên chứ không phải [] trong Spring 3.0: Chuỗi @RequestParam (value = "myParam") [] myParams
M Smith

3
Tuy nhiên, tôi không chia sẻ những phát hiện của @MSmith.
droope

2
Có thể có được List<String>thông qua này. Ngoài ra, có thể có được một java bean nhưList<MyBean>
Juzer Ali

3
Tôi nghĩ bạn có thể xóa dấu ngoặc khỏi tên param.
theblang

19

Chỉ cần bổ sung những gì Donal Fellows đã nói, bạn có thể sử dụng Danh sách với @RequestParam

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

Hy vọng nó giúp!


12

Đăng ký những gì húng quế nói trong một bình luận cho chính câu hỏi, nếu method = RequestMethod.GETbạn có thể sử dụng @RequestParam List<String> groupVal.

Sau đó, gọi dịch vụ với danh sách các thông số đơn giản như:

API_URL?groupVal=kkk,ccc,mmm

11

Một cách bạn có thể thực hiện điều này (theo cách hackish) là tạo một lớp bao bọc cho List. Như thế này:

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

Sau đó, chữ ký phương thức điều khiển của bạn sẽ trông như thế này:

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

Không cần sử dụng @RequestParamhoặc @ModelAttributechú thích nếu tên bộ sưu tập bạn chuyển trong yêu cầu khớp với tên trường bộ sưu tập của lớp trình bao bọc, trong ví dụ của tôi, các tham số yêu cầu của bạn sẽ giống như sau:

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

Chà, điều này gần giống như sử dụng @ModelAttribution, điểm khác biệt duy nhất là param không được chú thích. Tôi muốn tránh @ModelAttribution chỉ vì tôi không muốn tạo một trình bao bọc. Tôi đã đọc ở đâu đó trong stackoverflow (tôi không thể nhớ chính xác ở đâu) rằng nếu bạn thêm một tham số trong phương thức điều khiển mà không có chú thích @ModelAttribution (và nó không phải là một đối tượng đặc biệt như HttpRequest, HttpResponse ...) nếu nó được chú thích bằng @ModelAttribution. Vì vậy, nếu đó là sự thật thì đây chính xác là có @ModelAttribution. Nhưng cảm ơn câu trả lời của bạn.
Javi

4

Tôi không rõ ràng rằng mặc dù bạn có thể chấp nhận Bộ sưu tập dưới dạng thông số yêu cầu, nhưng về phía người tiêu dùng, bạn vẫn phải chuyển vào các mục bộ sưu tập dưới dạng các giá trị được phân tách bằng dấu phẩy .

Ví dụ: nếu api phía máy chủ trông như thế này:

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

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

Chuyển trực tiếp trong bộ sưu tập tới RestTemplate dưới dạng RequestParam như bên dưới sẽ dẫn đến hỏng dữ liệu

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

Thay vào đó bạn có thể sử dụng

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

Ví dụ đầy đủ có thể được tìm thấy ở đây , hy vọng nó sẽ cứu ai đó đau đầu :)


-7

Thay đổi giá trị trường ẩn với hộp kiểm chuyển đổi như bên dưới ...

HTML:

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

Kịch bản:

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

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

    } else {

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

    }

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.