Spring MVC - Làm thế nào để có được tất cả các thông số yêu cầu trong bản đồ trong bộ điều khiển Spring?


183

URL mẫu:

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

Tôi không biết tên của attr1, att2 và attr4.

Tôi muốn có thể làm một cái gì đó tương tự (hoặc tương tự, không quan tâm, miễn là tôi có quyền truy cập vào Bản đồ tên yêu cầu param -> value:

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

Làm thế nào tôi có thể đạt được điều này với Spring MVC?

Câu trả lời:


308

Mặc dù các câu trả lời khác đều đúng nhưng chắc chắn đây không phải là "cách mùa xuân" để sử dụng trực tiếp đối tượng HttpServletRequest. Câu trả lời thực sự khá đơn giản và những gì bạn mong đợi nếu bạn quen thuộc với Spring MVC.

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

41
Nếu bạn đang tìm cách xử lý các giá trị danh sách, như từ một nhóm các hộp kiểm có cùng tên, hãy sử dụng: @RequestParam MultiValueMap<String, String>
IcedDante

1
Cảm ơn vì điều đó. Bạn cũng có thể làm điều tương tự với các tiêu đề: stackoverflow.com/a/19556291/2599745
Rob Worsnop

3
Điều này chỉ hoạt động khi phương thức yêu cầu là GET hoặc POST. Nó không hoạt động đối với các phương thức yêu cầu PUT, DELETE, v.v.
George Siggouroglou

Đừng quên để thêm import org.springframework.ui.ModelMap;là tốt.
Truthadjustr

@typelogic ModelMapkhông cần thiết để lấy tất cả thông số yêu cầu làm bản đồ; đó đơn giản là một chi tiết cụ thể cho mã của OP.
xlm

34

Biên tập

Nó đã được chỉ ra rằng tồn tại ( ít nhất là từ 3.0 ) một cơ chế Spring MVC thuần túy mà người ta có thể lấy dữ liệu này. Tôi sẽ không nêu chi tiết ở đây, vì đó là câu trả lời của người dùng khác. Xem câu trả lời của @ AdamGent để biết chi tiết và đừng quên nâng cấp nó.

Trong tài liệu Spring 3.2, cơ chế này được đề cập trên cả RequestMappingtrang JavaDoc và RequestParamtrang JavaDoc, nhưng trước đó, nó chỉ được đề cập trong RequestMappingtrang. Trong tài liệu 2.5 không có đề cập đến cơ chế này.

Đây có thể là cách tiếp cận ưa thích đối với hầu hết các nhà phát triển vì nó loại bỏ (ít nhất là điều này) liên kết với HttpServletRequestđối tượng được xác định bởi jar servlet-api.

/Biên tập

Bạn nên có quyền truy cập vào chuỗi truy vấn yêu cầu thông qua request.getQueryString().

Ngoài getQueryString, các tham số truy vấn cũng có thể được truy xuất từ request.getParameterMap () dưới dạng Bản đồ.


12
Tôi nghi ngờ ai đó đã đánh giá thấp câu trả lời này chỉ vì getQueryString trả về một Chuỗi chứ không phải là Bản đồ. Các op đang tìm kiếm một Bản đồ các tham số. Tôi đã thêm getParameterMap vào câu trả lời của bạn để giúp làm cho chính xác hơn :) +1
jmort253

Không, tôi đánh giá thấp bởi vì đây không phải là cách Spring MVC để làm điều đó. @RequestParamsẽ sẵn sàng lấy một Maptham số (xem câu trả lời của tôi).
Adam Gent

@AdamGent Câu hỏi được đặt ra vào thời điểm Spring 3.2 chưa được phát hành. Quay trở lại và xem JavaDoc cho 3.1 và bạn sẽ nhận thấy không có đề cập nào về việc sử dụng @RequestParamtrên a Map<String,String>để lấy tất cả các tham số chuỗi truy vấn. Và làm ơn, đừng cảm thấy rất ghê tởm qua những câu trả lời mà bạn nhìn thấy ở đây ... họ không thấy xấu :) static.springsource.org/spring/docs/3.1.x/javadoc-api/org/...
Nicholas. hauschild

Tôi nghĩ rằng nó đã tồn tại trong 3.1 nhưng không phải là JavaDoced. Tôi đã không nói rằng tôi bị ghê tởm nhưng bị sốc vì @RequestParam Map<>cách đó không được thực hiện. Tôi có một chút khó chịu khi nhiều dự án hiện đại mà tôi đã thấy Spring MVC (mùa xuân 3.1 trở lên) họ sẽ đặt httpServletRequest và HttpServletResponse trên mọi phương thức. Và có vẻ như vì các nhà phát triển cơ sở sử dụng StackOverflow và google thay vì nhìn vào tài liệu. Điều này gây khó khăn cho dự án Spring khi chuyển từ aplet servlet sang nói Netty API. JAX-RS có các vấn đề lạm dụng tương tự nhưng ở mức độ thấp hơn nhiều.
Adam Gent

Và đó là JavaDoced trong 3.1, không phải ở tất cả các vị trí phù hợp: " Ngoài ra, @RequestParam có thể được sử dụng trên tham số phương thức Map <String, String> hoặc MultiValueMap <String, String> để có quyền truy cập vào tất cả các tham số yêu cầu. ". Nguyên vẹn nó quay trở lại phiên bản 3.0 (Tôi biết tôi đã sử dụng nó trước 3.1). Sự khó chịu của tôi vẫn còn ở chỗ mọi người không bận tâm thực hiện nghiên cứu :)
Adam Gent

14

Đối tượng HttpServletRequest đã cung cấp bản đồ các tham số. Xem request.getParameterMap () để biết thêm chi tiết.


1
Nhận bản đồ tham số cũng sẽ chứa dữ liệu biểu mẫu từ một yêu cầu POST. Nếu người dùng không biết các khóa trong chuỗi truy vấn, thì làm thế nào họ có thể phân biệt giữa những gì đến từ chuỗi truy vấn và những gì từ dữ liệu từ một cơ thể POST?
nicholas.hauschild

Bạn đang nói với tôi rằng bạn sẽ xử lý một bài đăng mẫu nhưng bạn không biết các tham số của mẫu thực tế là gì?
Kevin

2
Câu hỏi nói rằng anh ta không biết tên tham số là gì. Ngoài ra, tôi cũng không biết chúng là gì. ;)
nicholas.hauschild

Xin lỗi tôi thấy tiền đề hơi vô lý.
Kevin

11
Nó có ý nghĩa trong một ứng dụng điều khiển dữ liệu. Một trong đó các đường dẫn yêu cầu và chuỗi truy vấn có thể được tạo bởi máy khách và máy chủ ứng dụng sau đó sẽ tìm kiếm giá trị tương ứng (từ bất kỳ loại nguồn dữ liệu nào) bằng cách sử dụng các đường dẫn và chuỗi truy vấn này làm khóa.
nicholas.hauschild

12

bạn chỉ có thể sử dụng cái này:

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

Điều đó sẽ làm việc tốt


10

Dưới đây là ví dụ đơn giản về việc nhận thông số yêu cầu trong Bản đồ.

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

Trong trường hợp này, nó sẽ liên kết giá trị của studentName và studentEmail với các biến tên và email tương ứng.


8

Sử dụng org.springframework.web.context.request.WebRequestnhư một tham số trong phương thức điều khiển của bạn, nó cung cấp phương thức getParameterMap(), ưu điểm là bạn không thắt chặt ứng dụng của mình với API Servlet, WebRequest là một ví dụ về Đối tượng bối cảnh mẫu JavaEE.


6

Có hai giao diện

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

Cho phép truy cập tham số yêu cầu chung cũng như request/sessiontruy cập thuộc tính, mà không cần liên kết với API Servlet / Portlet gốc .

Ví dụ.:

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

PS Tài liệu về các đối số có thể được sử dụng làm Thông số điều khiển.


Cảm ơn bạn nó hoạt động. Tôi có thể hỏi, điểm quan trọng của String[]giá trị là gì? Tôi phải lập chỉ mục cho 0 chỉ để nhận giá trị.
Truthadjustr

Có thể có một mảng các giá trị như key=val1,val2hoặc key=val1&key=val2(nếu tôi nhớ chính xác là hỗ trợ cả hai ký hiệu này), do đó bạn sẽ nhận được mảng có 2 phần tử
katoquro

6

Tôi có thể đến bữa tiệc muộn, nhưng theo sự hiểu biết của tôi, bạn đang tìm kiếm một cái gì đó như thế này:

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ất cả các thông số sẽ được lưu trữ trong jsonObject.


1

Có sự khác biệt cơ bản giữa các tham số truy vấn và tham số đường dẫn. Nó như thế này: www.your_domain?queryparam1=1&queryparam2=2- tham số truy vấn. www.your_domain/path_param1/entity/path_param2- tham số đường dẫn.

Điều tôi ngạc nhiên là trong thế giới Spring MVC, rất nhiều người nhầm lẫn cái này với cái kia. Mặc dù các tham số truy vấn giống như tiêu chí cho tìm kiếm, nhưng thông số đường dẫn rất có thể sẽ xác định duy nhất một tài nguyên. Như đã nói, điều đó không có nghĩa là bạn không thể có nhiều tham số đường dẫn trong URI của mình, vì cấu trúc tài nguyên có thể được lồng vào nhau. Ví dụ: giả sử bạn cần một tài nguyên ô tô cụ thể của một người cụ thể:

www.my_site/customer/15/car/2 - tìm kiếm một chiếc xe thứ hai của khách hàng thứ 15.

Điều gì sẽ là một usecase để đặt tất cả các tham số đường dẫn vào bản đồ? Các tham số đường dẫn không có "khóa" khi bạn nhìn vào chính URI, các khóa đó trong bản đồ sẽ được lấy từ chú thích @Mapping của bạn, ví dụ:

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

Từ các tham số đường dẫn phối cảnh HTTP / REST thực sự không thể được chiếu lên bản đồ. Theo ý kiến ​​của tôi, đó là tất cả về sự linh hoạt của Spring và mong muốn của họ để phù hợp với bất kỳ nhà phát triển nào.

Tôi sẽ không bao giờ sử dụng bản đồ cho các tham số đường dẫn, nhưng nó có thể khá hữu ích cho các tham số truy vấn.

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.