Trả về cái gì nếu phương thức bộ điều khiển Spring MVC không trả về giá trị?


135

Tôi đang sử dụng jQuery $.getJSON()để thực hiện các cuộc gọi không đồng bộ đến phần phụ trợ Spring MVC đơn giản của mình. Hầu hết các phương thức điều khiển Spring trông như thế này:

@RequestMapping(value = "/someURL", method = RequestMethod.POST)
public @ResponseBody SomePOJO getSomeData(@ModelAttribute Widget widget,
    @RequestParam("type") String type) {
    return someDAO.getSomeData(widget, type);
}   

Tôi có những thứ được thiết lập để mỗi bộ điều khiển trả về @ResponseBodydưới dạng JSON, đó là điều mà phía khách hàng mong đợi.

Nhưng điều gì xảy ra khi một yêu cầu không được yêu cầu trả lại bất kỳ nội dung nào cho phía khách hàng? Tôi co thể co:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public @ResponseBody void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Nếu không, cú pháp thích hợp để sử dụng ở đây là gì?


Tôi cho rằng nếu bạn không trả lại bất cứ điều gì, sẽ không có bất kỳ nội dung nào được gửi lại?
A la hán

1
Tôi nghĩ rằng tôi vẫn sẽ trả lại một POJO nào đó, ngay cả khi trong Phiên bản 1 của giải pháp của bạn, nó chỉ gói gọn một boolean "thành công" hoặc một cái gì đó tương tự. Sau đó, bạn đã có một mẫu nhất quán trong tất cả các phương pháp AJAX của bạn, và cái gì đó là dễ dàng hơn để xây dựng trên khi nó quay ra bạn làm cần phải trả lại một cái gì đó!
máy

Trái với những gì câu trả lời là gợi ý, những gì bạn có trong đoạn trích thứ hai là hoàn toàn tốt và cách xử lý POSTdữ liệu chính xác .
Brett Ryan

Trong trường hợp này, nó sẽ trả về null. @RestControll lớp công khai RESTControllExample {@RequestMapping (value = "/ staff", method = RequestMethod.GET) public void getEmployeeNames () {EmployeeSource.getEmprocod (); System.out.println ("Tôi đã hoàn thành"); }}
spandey

Câu trả lời:


256

bạn có thể trả về void, sau đó bạn phải đánh dấu phương thức bằng @ResponseStatus (value = HttpStatus.OK) mà bạn không cần @ResponseBody

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Chỉ nhận các phương thức trả về 200 mã trạng thái, tất cả các phương thức khác bạn đã thực hiện một trong ba điều sau:

  • Trả về void và đánh dấu phương thức với @ResponseStatus(value = HttpStatus.OK)
  • Trả về một đối tượng và đánh dấu nó bằng @ResponseBody
  • Trả lại một HttpEntityví dụ

2
Trong trường hợp ngoại lệ thời gian chạy xảy ra ở giữa, HTTP 500 sẽ được trả về chứ không phải 200. Vì vậy, nếu xử lý giao diện người dùng của bạn không thành công, thông báo ngoại lệ / lỗi sẽ được hiển thị chính xác.
Lee Chee Kiam

27
Trên thực tế, bạn không cần phải thiết lập @ResponseStatusvà không nên. Đơn giản chỉ cần có @ResponseBodymột voidxử lý là đủ tốt.
Brett Ryan

11
Tôi nghĩ sẽ tốt hơn nếu trả lại 204 No Content thay vì 200 cho các phương thức void
raspacorp

1
@raspacorp 200 là chính xác cho POST vì nó không có nghĩa là có một cơ thể.
Brett Ryan

8
@BrettRyan chỉ là một nhận xét, ít nhất là đối với API REST, một thông lệ phổ biến là POST sẽ được sử dụng để tạo nội dung trong trường hợp nó thường trả về id của (các) thực thể được tạo, các thực thể được tạo đầy đủ hoặc liên kết đến thao tác đọc. Trả về 200 trạng thái không có nội dung có thể gây nhầm lẫn từ phối cảnh API REST.
raspacorp

43

Bạn chỉ có thể trả về một FeedbackEntity với tiêu đề thích hợp:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...){
....
return new ResponseEntity(HttpStatus.OK)
}

Trong trường hợp bất kỳ ai gặp phải vấn đề tương tự tôi đã làm, điều này không hoạt động trên phiên bản cũ hơn của mùa xuân (4.1.1) Tôi sẽ nhận được 500 lỗi. Tôi đã nâng cấp lên 4.2.0 và điều này hoạt động rất tốt
nước sốt

Đó là cách ưa thích của tôi để trả lại 200 trống. Vì Spring 4.1 sử dụng mẫu trình xây dựng thay thế: return FeedbackEntity.ok (). Build ();
GreenTurtle

3
Mặc dù dường như biên dịch, nó đưa ra cảnh báo sauResponseEntity is a raw type. References to generic type ResponseEntity<T> should be parameterized
Gonzalo.-

8

Bạn có thể trả về đối tượng "FeedbackEntity". Sử dụng đối tượng "FeedbackEntity" rất thuận tiện cả tại thời điểm xây dựng đối tượng phản hồi (có chứa Mã phản hồi và Mã trạng thái HTTP) và tại thời điểm lấy thông tin ra khỏi đối tượng phản hồi.

Các phương thức như getHeaders (), getBody (), getContentType (), getStatusCode () v.v ... làm cho công việc đọc đối tượng FeedbackEntity rất dễ dàng.

Bạn nên sử dụng đối tượng FeedbackEntity với mã trạng thái http là 204 (Không có nội dung), đặc biệt để xác định rằng yêu cầu đã được xử lý đúng cách và phần thân phản hồi trống. Sử dụng Mã trạng thái phù hợp để truyền tải thông tin phù hợp là rất quan trọng, đặc biệt nếu bạn đang tạo một API sẽ được sử dụng bởi nhiều ứng dụng khách.


3
thiết lập @ResponseStatus(HttpStatus.NO_CONTENT)giải quyết XML Parsing Error: no root element foundcho tôi trong trình duyệt
aliopi

3

Có, bạn có thể sử dụng @ResponseBody với voidloại trả về:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseBody
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

1
Vì vậy, kiểu trả về sẽ là gì .. có phải là mã trạng thái HTTP không?
spandey

@techBeginner Trong trường hợp này 200 (OK).
Lakatos Gyula

2

Không có gì sai khi trả lại một khoảng trống @ResponseBodyvà bạn nên choPOST yêu cầu.

Sử dụng mã trạng thái HTTP để xác định lỗi trong các quy trình xử lý ngoại lệ thay vì các mã khác đang đề cập đến trạng thái thành công. Một phương thức bình thường như bạn có sẽ trả về mã phản hồi 200là những gì bạn muốn, bất kỳ trình xử lý ngoại lệ nào sau đó có thể trả về một đối tượng lỗi và một mã khác (ví dụ 500).


1

Nhưng khi hệ thống của bạn phát triển về kích thước và chức năng ... tôi nghĩ rằng việc trở lại luôn luôn là một ý tưởng không tồi chút nào. Là một vấn đề kiến ​​trúc / "thiết kế quy mô lớn".

Bạn có thể nghĩ về việc giữ lại luôn một JSON với hai trường biết: mã và dữ liệu. Trong đó mã là một mã số chỉ định sự thành công của hoạt động sẽ được thực hiện và dữ liệu là bất kỳ dữ liệu quảng cáo nào liên quan đến hoạt động / dịch vụ được yêu cầu.

Thôi nào, khi chúng tôi sử dụng phụ trợ nhà cung cấp dịch vụ, bất kỳ dịch vụ nào cũng có thể được kiểm tra để xem nó có hoạt động tốt không.

Vì vậy, tôi chắc chắn, không để mùa xuân quản lý điều này, phơi bày các hoạt động trả về kết hợp lai (Một số trả về dữ liệu khác không có gì ...) .. đảm bảo rằng máy chủ của bạn hiển thị giao diện đồng nhất hơn. Đơn giản hơn vào cuối ngày.


0

Dưới đây là mã ví dụ những gì tôi đã làm cho một phương thức không đồng bộ

@RequestMapping(value = "/import", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void importDataFromFile(@RequestParam("file") MultipartFile file) 
{
    accountingSystemHandler.importData(file, assignChargeCodes);
}

Bạn không cần trả lại bất kỳ điều gì từ phương thức của mình, tất cả những gì bạn cần để sử dụng chú thích này để phương thức của bạn sẽ trả về OK trong mọi trường hợp

@ResponseStatus(value = HttpStatus.OK)
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.