JAX-RS — Cara mengembalikan JSON dan kode status HTTP bersama-sama?
I'm menulis REST web app (NetBeans 6.9, JAX-RS, TopLink Essentials) dan mencoba untuk kembali JSON dan kode status HTTP. Saya memiliki kode siap dan bekerja yang mengembalikan JSON ketika HTTP MENDAPATKAN metode ini disebut dari klien. Pada dasarnya:
@Path("get/id")
@GET
@Produces("application/json")
public M_機械 getMachineToUpdate(@PathParam("id") String id) {
// some code to return JSON ...
return myJson;
}
Tapi aku juga ingin mengembalikan kode status HTTP (500, 200, 204, dll.) bersama dengan data JSON.
Saya mencoba untuk menggunakan HttpServletResponse
:
response.sendError("error message", 500);
Tapi hal ini membuat browser pikir itu's "nyata" 500 sehingga output halaman web biasa HTTP error 500 halaman.
Saya ingin mengembalikan kode status HTTP sehingga saya client-side JavaScript dapat menangani beberapa logika yang tergantung di atasnya (misalnya untuk menampilkan kode kesalahan dan pesan pada halaman HTML). Ini mungkin atau harus kode status HTTP tidak dapat digunakan untuk hal seperti itu?
Berikut ini's contoh:
Lihatlah Respon kelas.
Perhatikan bahwa anda harus selalu menentukan jenis konten, terutama jika anda melewati beberapa jenis konten, tetapi jika setiap pesan akan direpresentasikan sebagai JSON, anda hanya dapat membubuhi keterangan dengan metode
@Menghasilkan("application/json")
Ada beberapa kasus penggunaan untuk pengaturan kode status HTTP di REST web service, dan setidaknya satu itu tidak cukup didokumentasikan dalam ada jawaban (yaitu ketika anda menggunakan auto-ajaib JSON/XML serialization menggunakan JAXB, dan anda ingin mengembalikan sebuah objek yang akan serial, tapi juga kode status yang berbeda dari default 200). Jadi biarkan saya mencoba dan menghitung kasus penggunaan yang berbeda dan solusi untuk masing-masing:
Kode galat (500, 404,...)
Penggunaan yang paling umum terjadi ketika anda ingin mengembalikan kode status yang berbeda dari
200 OK
adalah ketika terjadi kesalahan. Misalnya:dll.. a) Melempar pengecualian
Dalam hal ini, saya berpikir bahwa terbersih cara untuk menangani masalah ini adalah untuk melempar sebuah exception. Pengecualian ini akan ditangani oleh sebuah
ExceptionMapper
, yang akan menerjemahkan pengecualian menjadi respon sesuai dengan kode kesalahan. Anda dapat menggunakan defaultExceptionMapper
yang datang pra-dikonfigurasi dengan Jersey (dan saya kira itu's sama dengan implementasi lainnya) dan membuang apapun yang ada sub-kelas darijavax.ws.rs.WebApplicationException
. Ini adalah pra-didefinisikan jenis pengecualian yang sudah dipetakan untuk kode kesalahan yang berbeda, misalnya:ExceptionMapper
kelas, dan menambahkan ini pembuat peta untuk Jersey dengan maksud dari@Provider
penjelasan (sumber dari contoh ini):Penyedia :
Catatan: anda juga dapat menulis ExceptionMappers untuk ada pengecualian jenis yang anda gunakan. b) Menggunakan Respon builder
Cara lain untuk menetapkan status kode ini untuk menggunakan
Respon
builder untuk membangun respon dengan tujuan kode. Dalam kasus tersebut, metode's return type harusjavax.ws.rs.inti.Respon
. Hal ini dijelaskan dalam berbagai tanggapan lain seperti hisdrewness' jawaban yang diterima dan terlihat seperti ini :Sukses, tapi tidak 200
Lain halnya bila anda ingin mengatur kembali status adalah ketika operasi itu sukses, tapi anda ingin kembali sukses kode yang berbeda dari 200, bersama dengan konten yang anda kembali dalam tubuh. Yang sering terjadi adalah ketika anda membuat entitas baru (
POST
permintaan) dan ingin kembali info tentang entitas baru ini atau mungkin entitas itu sendiri, bersama-sama dengan201 Dibuat
kode status. Salah satu pendekatan adalah dengan menggunakan respon objek seperti yang dijelaskan di atas dan mengatur tubuh dari permintaan sendiri. Namun, dengan melakukan ini, anda kehilangan kemampuan untuk menggunakan otomatis serialisasi XML atau JSON yang disediakan oleh JAXB. Ini adalah metode asli kembali suatu entitas objek yang akan bersambung ke JSON dengan JAXB:Ini akan mengembalikan JSON representasi dari pengguna yang baru dibuat, tapi kembali status akan menjadi 200, tidak 201. Sekarang masalahnya adalah jika saya ingin menggunakan
Respon
pembangun untuk mengatur kode kembali, aku harus kembaliRespon
objek dalam metode saya. Bagaimana saya masih kembaliUser
objek yang akan serial? a) Mengatur kode pada servlet responSalah satu pendekatan untuk memecahkan masalah ini adalah untuk mendapatkan sebuah servlet permintaan objek dan mengatur respon kode secara manual diri kita sendiri, seperti yang ditunjukkan dalam Garett Wilson's jawaban :
Metode ini masih kembali suatu entitas objek dan kode status akan menjadi 201. Perhatikan bahwa untuk membuatnya bekerja, saya harus menyiram respon. Ini adalah aplikasi menyenangkan kebangkitan tingkat rendah Servlet API kode di kami bagus JAX_RS sumber daya, dan jauh lebih buruk, hal itu menyebabkan header untuk unmodifiable setelah ini karena mereka sudah dikirim pada kawat. b) Menggunakan respon objek dengan entitas
Solusi terbaik, dalam hal ini, adalah dengan menggunakan Respon objek dan mengatur entitas yang akan serial ini respon objek. Akan lebih baik untuk membuat Respon objek generik untuk menunjukkan jenis muatan entitas dalam kasus itu, tapi tidak saat ini kasus tersebut.
Dalam hal ini, kita gunakan dibuat metode Respon builder kelas dalam rangka untuk mengatur kode status ke 201. Kami melewati entitas objek (user) untuk respon melalui entitas() metode. Hasilnya adalah bahwa HTTP kode 401 seperti yang kita inginkan, dan tubuh respon yang sama persis JSON seperti sebelumnya ketika kami baru saja kembali objek Pengguna. Ia juga menambahkan lokasi header. Respon kelas memiliki sejumlah builder metode untuk status yang berbeda (amerika ?) seperti : Respon.diterima() Respon.ok() Respon.tidak adakonten() Respon.notAcceptable() NB: hateoas objek adalah sebuah kelas helper yang saya kembangkan untuk membantu menghasilkan sumber daya Uri. Anda akan perlu untuk datang dengan anda sendiri mekanisme di sini ;) Yang's tentang hal itu. Saya harap panjang ini membantu respon seseorang :)
Jawaban oleh hisdrewness akan bekerja, tetapi memodifikasi seluruh pendekatan untuk membiarkan penyedia seperti Jackson+JAXB secara otomatis mengkonversi objek kembali ke beberapa format output seperti JSON. Terinspirasi oleh Apache CXF pos (yang menggunakan CXF-kelas tertentu) I've ditemukan salah satu cara untuk mengatur respon kode yang harus bekerja di setiap JAX-RS implementasi: inject yang HttpServletResponse konteks dan secara manual mengatur kode respon. Sebagai contoh, berikut adalah cara untuk mengatur kode respon untuk
MENCIPTAKAN
saat yang tepat.Improvement: Setelah menemukan lain yang terkait jawaban, saya belajar bahwa seseorang dapat menyuntikkan
HttpServletResponse
sebagai variabel anggota, bahkan untuk singleton layanan kelas (setidaknya di RESTEasy)!! Ini adalah banyak pendekatan yang lebih baik dari polusi API dengan rincian pelaksanaan. Itu akan terlihat seperti ini:Jika anda ingin menyimpan sumber daya lapisan bersih dari
Respon
benda-benda, maka saya sarankan anda menggunakan@NameBinding
dan mengikat untuk implementasiContainerResponseFilter
.Berikut ini's daging anotasi:
Berikut ini's daging filter:
Dan kemudian pelaksanaan pada sumber daya anda hanya menjadi:
Dalam kasus anda ingin mengubah kode status karena pengecualian, dengan JAX-RS 2.0 anda dapat menerapkan ExceptionMapper seperti ini. Ini menangani semacam ini pengecualian untuk seluruh aplikasi.
Jika anda WS-RS perlu meningkatkan kesalahan mengapa tidak hanya menggunakan WebApplicationException?
JAX-RS memiliki dukungan untuk standar/custom HTTP kode. Lihat ResponseBuilder dan ResponseStatus, misalnya:
http://jackson.codehaus.org/javadoc/jax-rs/1.0/javax/ws/rs/core/Response.ResponseBuilder.html#status%28javax.ws.rs.core.Response.Status%29
Perlu diingat bahwa JSON informasi lebih lanjut tentang data-data yang berhubungan dengan sumber daya/aplikasi. HTTP kode lebih lanjut tentang status operasi CRUD yang diminta. (setidaknya itu adalah bagaimana hal itu's seharusnya di SISA-ful sistem)
Silahkan lihat contoh di sini, itu yang terbaik menggambarkan masalah dan bagaimana hal itu diselesaikan dalam terbaru (2.3.1) versi Jersey.
https://jersey.java.net/documentation/latest/representations.html#d0e3586
Hal ini pada dasarnya melibatkan mendefinisikan sebuah Pengecualian kustom dan menjaga jenis kembali sebagai entitas. Ketika ada kesalahan, pengecualian dilemparkan, jika tidak, anda kembali POJO.
Saya menemukan itu sangat berguna untuk membangun juga json pesan dengan berulang-ulang kode, seperti ini:
I'm tidak menggunakan JAX-RS, tapi saya've punya skenario yang sama di mana saya gunakan:
Juga, perhatikan bahwa secara default Jersey akan menimpa respon tubuh dalam kasus http kode 400 atau lebih.
Dalam rangka untuk mendapatkan yang ditetapkan entitas sebagai respon tubuh, cobalah untuk menambahkan berikut init-param untuk anda Jersey di web.xml file konfigurasi :
I'm menggunakan jersey 2.0 dengan badan pesan pembaca dan penulis. Saya punya metode jenis kembali sebagai entitas tertentu yang juga digunakan dalam pelaksanaan badan pesan penulis dan saya kembali sama pojo, yang SkuListDTO. @DAPATKAN @Mengkonsumsi({"application/xml", "application/json"}) @Menghasilkan({"application/xml", "application/json"}) @Path("/skuResync")
semua aku berubah ini, aku meninggalkan penulis pelaksanaannya saja dan itu masih bekerja.
Berikut kode yang bekerja untuk saya. Menyuntikkan messageContext melalui dijelaskan setter dan pengaturan kode status saya "tambahkan" metode.