Apa yang harus dikembalikan jika metode pengendali Spring MVC tidak mengembalikan nilai?

135

Saya menggunakan jQuery $.getJSON()untuk melakukan panggilan asinkron ke backend Spring MVC sederhana saya. Sebagian besar metode pengontrol Spring terlihat seperti ini:

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

Saya memiliki hal-hal yang diatur sehingga setiap controller mengembalikan @ResponseBodyJSON, yang diharapkan oleh sisi klien.

Tetapi apa yang terjadi ketika permintaan tidak seharusnya mengembalikan konten apa pun ke sisi klien? Bolehkah saya mau:

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

Jika tidak, apa sintaksis yang tepat untuk digunakan di sini?

IAmYourFaja
sumber
Saya berasumsi jika Anda tidak mengembalikan apa-apa, tidak akan ada konten yang dikirim kembali?
Arahant
1
Saya pikir saya masih akan mengembalikan POJO semacam, bahkan jika dalam Versi 1 dari solusi Anda hanya membungkus "sukses" boolean atau yang serupa. Maka Anda punya pola yang konsisten di semua metode AJAX Anda, dan sesuatu yang lebih mudah untuk membangun ketika ternyata Anda lakukan perlu kembali sesuatu!
millhouse
Berlawanan dengan jawaban yang disarankan, apa yang pertama kali Anda miliki di cuplikan kedua baik-baik saja dan cara yang benar untuk menangani POSTdata.
Brett Ryan
Dalam hal ini akan mengembalikan nol. @RestController kelas publik RESTControllerExample {@RequestMapping (value = "/ karyawan", method = RequestMethod.GET) public void getEmployeeNames () {EmployeeSource.getEmployees (); System.out.println ("Saya sudah selesai"); }}
spandey

Jawaban:

256

Anda dapat mengembalikan void, maka Anda harus menandai metode dengan @ResponseStatus (value = HttpStatus.OK) Anda tidak perlu @ResponseBody

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

Hanya dapatkan metode mengembalikan implikasi kode status 200, semua yang Anda miliki melakukan salah satu dari tiga hal:

  • Kembalikan batal dan tandai metode dengan @ResponseStatus(value = HttpStatus.OK)
  • Kembalikan objek dan tandai dengan @ResponseBody
  • Kembalikan sebuah HttpEntityinstance
am
sumber
2
Dalam kasus pengecualian runtime terjadi di antara, HTTP 500 akan dikembalikan dan bukan 200. Jadi jika ujung depan Anda menangani kegagalan, pesan pengecualian / kesalahan akan ditampilkan dengan benar.
Lee Chee Kiam
27
Sebenarnya, Anda tidak perlu mengatur @ResponseStatusdan tidak seharusnya. Cukup memiliki @ResponseBodypada voidhandler baik-baik saja cukup.
Brett Ryan
11
Saya pikir akan lebih baik untuk mengembalikan 204 No Content daripada 200 untuk metode batal
raspacorp
1
@raspacorp 200 benar untuk POST karena tidak dimaksudkan untuk memiliki tubuh.
Brett Ryan
8
@BrettRyan hanya sebagai komentar, setidaknya untuk REST API itu adalah praktik umum bahwa POST akan digunakan untuk membuat konten yang biasanya mengembalikan id dari enity yang dibuat, entitas yang dibuat penuh atau tautan ke operasi baca. Pengembalian status 200 tanpa konten dapat membingungkan dari perspektif REST API.
raspacorp
43

Anda cukup mengembalikan ResponseEntity dengan tajuk yang sesuai:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...){
....
return new ResponseEntity(HttpStatus.OK)
}
Biju Kunjummen
sumber
Jika ada orang yang mengalami masalah yang sama dengan saya, ini tidak bekerja pada versi semi yang lebih lama (4.1.1) Saya akan mendapatkan 500 kesalahan. Saya memutakhirkan ke 4.2.0 dan ini berhasil
saus
Itu adalah cara yang saya sukai untuk mengembalikan 200 kosong juga. Karena Spring 4.1 gunakan pola builder sebagai gantinya: return ResponseEntity.ok (). Build ();
GreenTurtle
3
Meskipun tampaknya mengkompilasi, itu memberikan peringatan berikutResponseEntity is a raw type. References to generic type ResponseEntity<T> should be parameterized
Gonzalo.-
8

Anda dapat mengembalikan objek "ResponseEntity". Menggunakan objek "ResponseEntity" sangat nyaman baik pada saat membangun objek respons (yang berisi Badan Respon dan Kode Status HTTP) dan pada saat mendapatkan informasi dari objek respons.

Metode seperti getHeaders (), getBody (), getContentType (), getStatusCode () dll membuat pekerjaan membaca objek ResponseEntity sangat mudah.

Anda harus menggunakan objek ResponseEntity dengan kode status http 204 (Tidak Ada Konten), yang secara khusus untuk menentukan bahwa permintaan telah diproses dengan benar dan badan respons sengaja dikosongkan. Menggunakan Kode Status yang tepat untuk menyampaikan informasi yang benar sangat penting, terutama jika Anda membuat API yang akan digunakan oleh banyak aplikasi klien.

Harley
sumber
3
pengaturan @ResponseStatus(HttpStatus.NO_CONTENT)diselesaikan XML Parsing Error: no root element founduntuk saya di browser
aliopi
3

Ya, Anda dapat menggunakan @ResponseBody dengan voidtipe pengembalian:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseBody
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}
pengguna1338062
sumber
1
jadi apa yang akan menjadi tipe pengembalian .. apakah itu kode status HTTP?
Spandey
@ TechBeginner Dalam hal ini 200 (OK).
Lakatos Gyula
2

Tidak ada yang salah dengan mengembalikan kekosongan @ResponseBodydan Anda harus POSTmeminta.

Gunakan kode status HTTP untuk mendefinisikan kesalahan dalam rutinitas handler pengecualian sebagai gantinya orang lain menyebutkan status keberhasilan. Metode normal seperti yang Anda miliki akan mengembalikan kode respons 200yang mana yang Anda inginkan, penangan pengecualian apa pun dapat mengembalikan objek kesalahan dan kode yang berbeda (yaitu 500).

Brett Ryan
sumber
1

Tetapi ketika sistem Anda tumbuh dalam ukuran dan fungsionalitas ... saya pikir mengembalikan selalu json bukanlah ide yang buruk sama sekali. Lebih merupakan masalah arsitektur / "desain skala besar".

Anda dapat berpikir tentang mempertahankan selalu JSON dengan dua bidang pengetahuan: kode dan data. Di mana kode adalah kode numerik yang menentukan keberhasilan operasi yang harus dilakukan dan data adalah data tambahan yang terkait dengan operasi / layanan yang diminta.

Ayo, ketika kita menggunakan backend penyedia layanan, layanan apa pun dapat diperiksa untuk melihat apakah itu berfungsi dengan baik.

Jadi saya tetap, untuk tidak membiarkan musim semi mengelola ini, mengekspos operasi pengembalian hibrida (Beberapa mengembalikan data lain ...) .. instaed memastikan bahwa server Anda mengekspos antarmuka yang lebih homogen. Lebih sederhana di akhir hari.

Pemenang
sumber
0

Berikut ini contoh kode yang saya lakukan untuk metode asinkron

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

Anda tidak perlu mengembalikan apa pun dari metode Anda semua yang Anda butuhkan untuk menggunakan anotasi ini sehingga metode Anda harus kembali OK dalam setiap kasus

@ResponseStatus(value = HttpStatus.OK)
AbdusSalam
sumber