Saya menggunakan Spring MVC untuk API JSON sederhana, dengan @ResponseBody
pendekatan berbasis seperti berikut. (Saya sudah memiliki lapisan layanan yang memproduksi JSON secara langsung.)
@RequestMapping(value = "/matches/{matchId}", produces = "application/json")
@ResponseBody
public String match(@PathVariable String matchId) {
String json = matchService.getMatchJson(matchId);
if (json == null) {
// TODO: how to respond with e.g. 400 "bad request"?
}
return json;
}
Pertanyaannya adalah, dalam skenario yang diberikan, apa cara paling sederhana, paling bersih untuk merespons dengan kesalahan HTTP 400 ?
Saya menemukan beberapa pendekatan seperti:
return new ResponseEntity(HttpStatus.BAD_REQUEST);
... tapi saya tidak bisa menggunakannya di sini karena tipe pengembalian metode saya adalah String, bukan ResponseEntity.
java
spring
spring-mvc
http-error
Jonik
sumber
sumber
ResponseEntity
seperti ini juga. Ini berfungsi dengan baik dan hanya perubahan sederhana ke kode asli — terima kasih!Sesuatu seperti ini seharusnya bekerja, saya tidak yakin apakah ada cara yang lebih sederhana:
sumber
body
danrequest
params.)Tidak harus cara paling ringkas untuk melakukan ini, tetapi IMO cukup bersih
Sunting Anda dapat menggunakan @ResponseBody dalam metode handler pengecualian jika menggunakan Spring 3.1+, jika tidak gunakan a
ModelAndView
atau sesuatu.https://jira.springsource.org/browse/SPR-6902
sumber
ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: public controller.TestController$MyError controller.TestController.handleException(controller.TestController$BadThingException) org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
Apakah ada sesuatu yang hilang dari jawabannya?javax.validation.ValidationException
sebagai gantinya. (Musim semi 3.1.4)Saya akan sedikit mengubah implementasinya:
Pertama, saya membuat
UnknownMatchException
:Perhatikan penggunaan @ResponseStatus , yang akan dikenali oleh Spring's
ResponseStatusExceptionResolver
. Jika pengecualian dilemparkan, itu akan membuat respons dengan status respons yang sesuai. (Saya juga mengambil kebebasan untuk mengubah kode status404 - Not Found
yang menurut saya lebih sesuai untuk kasus penggunaan ini, tetapi Anda dapat tetap melakukannyaHttpStatus.BAD_REQUEST
jika Anda mau.)Selanjutnya, saya akan mengubah
MatchService
untuk memiliki tanda tangan berikut:Akhirnya, saya akan memperbarui controller dan mendelegasikan ke Spring
MappingJackson2HttpMessageConverter
untuk menangani serialisasi JSON secara otomatis (ditambahkan secara default jika Anda menambahkan Jackson ke classpath dan menambahkan salah satu@EnableWebMvc
atau<mvc:annotation-driven />
ke konfigurasi Anda, lihat dokumen referensi ):Catatan, sangat umum untuk memisahkan objek domain dari objek tampilan atau objek DTO. Ini dapat dengan mudah dicapai dengan menambahkan pabrik DTO kecil yang mengembalikan objek JSON berseri:
sumber
Match
dan beberapa objek lainnya.Ini pendekatan yang berbeda. Buat custom
Exception
beranotasi dengan@ResponseStatus
, seperti yang berikut.Dan membuangnya saat dibutuhkan.
Lihat dokumentasi Spring di sini: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-ann-ann-annotated-exceptions .
sumber
Seperti disebutkan dalam beberapa jawaban, ada kemampuan untuk membuat kelas pengecualian untuk setiap status HTTP yang ingin Anda kembalikan. Saya tidak suka gagasan harus membuat kelas per status untuk setiap proyek. Inilah yang saya pikirkan sebagai gantinya.
Mari kita menuju kodenya
Kemudian saya membuat kelas saran pengontrol
Untuk menggunakannya
http://javaninja.net/2016/06/membuang-exceptions-messages-spring-mvc-controller/
sumber
Saya menggunakan ini dalam aplikasi boot musim semi saya
sumber
Cara termudah adalah dengan melempar a
ResponseStatusException
sumber
Dengan Spring Boot, saya tidak sepenuhnya yakin mengapa ini diperlukan (saya mendapatkan
/error
fallback meskipun@ResponseBody
didefinisikan pada a@ExceptionHandler
), tetapi berikut ini dengan sendirinya tidak berfungsi:Itu masih melemparkan pengecualian, tampaknya karena tidak ada jenis media yang dapat diproduksi didefinisikan sebagai atribut permintaan:
Jadi saya menambahkannya.
Dan ini membuat saya memiliki "tipe media yang kompatibel yang didukung", tetapi kemudian masih tidak berfungsi, karena saya
ErrorMessage
salah:JacksonMapper tidak menanganinya sebagai "convertable", jadi saya harus menambahkan getter / setter, dan saya juga menambahkan
@JsonProperty
anotasiKemudian saya menerima pesan saya sebagaimana dimaksud
sumber
Anda juga bisa
throw new HttpMessageNotReadableException("error description")
mendapatkan manfaat dari penanganan kesalahan default Spring .Namun, seperti halnya dengan kesalahan standar tersebut, tidak ada badan respons yang akan ditetapkan.
Saya menemukan ini berguna ketika menolak permintaan yang hanya bisa dibuat dengan tangan, berpotensi menunjukkan niat jahat, karena mereka mengaburkan fakta bahwa permintaan tersebut ditolak berdasarkan pada validasi khusus dan validasinya menurut kriteria.
Hth, dtk
sumber
HttpMessageNotReadableException("error description")
sudah ditinggalkan.Pendekatan lain adalah dengan menggunakan
@ExceptionHandler
dengan@ControllerAdvice
untuk memusatkan semua penangan Anda di kelas yang sama, jika tidak Anda harus menempatkan metode handler di setiap kontroler Anda ingin mengelola pengecualian.Kelas penangan Anda:
Pengecualian khusus Anda:
Sekarang Anda dapat melempar pengecualian dari salah satu pengendali Anda, dan Anda dapat menentukan penangan lain di dalam kelas saran Anda.
sumber
Saya pikir utas ini sebenarnya memiliki solusi termudah dan terbersih, yang tidak mengorbankan alat bela diri JSON yang disediakan oleh Spring:
https://stackoverflow.com/a/16986372/1278921
sumber