Spring: bagaimana cara menyuntikkan HttpServletRequest ke dalam kacang yang memiliki cakupan permintaan?

96

Saya mencoba menyiapkan kacang cakupan permintaan di Spring.

Saya telah berhasil mengaturnya sehingga kacang dibuat satu kali per permintaan. Sekarang, ia perlu mengakses objek HttpServletRequest.

Karena kacang dibuat sekali per permintaan, saya membayangkan wadah dapat dengan mudah menyuntikkan objek permintaan ke kacang saya. Bagaimana saya bisa melakukan itu?

Leonel
sumber

Jawaban:

115

Kacang bercakupan permintaan dapat disalurkan secara otomatis dengan objek permintaan.

private @Autowired HttpServletRequest request;
skaffman
sumber
2
Apakah ada cara XML kuno untuk ini?
cherouvim
2
Tidak berfungsi untuk saya (spring mvc 3.1) - mungkin ada hal lain yang perlu dilakukan? Mengikuti solusi Samit.
kldavis4
2
Masalahnya adalah ketika Anda menguji validator menggunakan MockMvc dan injeksi semacam ini Anda akan mengalami masalah. Mungkin solusi lain akan lebih disukai dalam kasus ini
Neyko
21
Dimungkinkan juga untuk meng-autowire HttpServletRequest juga ke dalam kacang non-request-scoped, karena untuk HttpServletRequest Spring akan menghasilkan proxy HttpServletRequest yang mengetahui cara mendapatkan instance permintaan yang sebenarnya. Jadi, aman untuk meminta autowire bahkan jika pengontrol Anda memiliki cakupan tunggal.
vtor
3
Peringatan untuk pengguna Spring <= 3.1 , pemasangan kabel otomatis tidak akan berfungsi saat menjalankan pengujian.
Rubens Mariuzzo
138

Musim semi memperlihatkan HttpServletRequestobjek saat ini (serta HttpSessionobjek saat ini ) melalui tipe objek pembungkusServletRequestAttributes . Objek pembungkus ini terikat ke ThreadLocal dan diperoleh dengan memanggil staticmetode RequestContextHolder.currentRequestAttributes().

ServletRequestAttributesmenyediakan metode getRequest()untuk mendapatkan permintaan saat ini, getSession()untuk mendapatkan sesi saat ini, dan metode lain untuk mendapatkan atribut yang disimpan di kedua cakupan. Kode berikut, meskipun agak jelek, akan membuat Anda mendapatkan objek permintaan saat ini di mana saja dalam aplikasi:

HttpServletRequest curRequest = 
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();

Perhatikan bahwa RequestContextHolder.currentRequestAttributes()metode mengembalikan antarmuka dan perlu diketik untuk ServletRequestAttributesmengimplementasikan antarmuka.


Spring Javadoc: RequestContextHolder | ServletRequestAttributes

samitgaur
sumber
8
Injeksi adalah resolusi yang baik, tetapi saya telah menemukan masalah dengan validator musim semi pengujian MockMvc yang menyuntikkan HttpServletRequest. Jadi, jika Anda ingin pengujian tiruan dan kode produksi berjalan dengan baik, inilah pilihannya.
Neyko
@Neyko Mengapa demikian? untuk uji tiruan (Uji unit?), Anda dapat menyuntikkan HttpServletRequest tiruan atau apa pun yang Anda inginkan .. bukan? Atau Anda bisa menggunakan MockHttpServletRequest?
wonhee
Apakah aman digunakan dalam instance layanan dengan cakupan tunggal?
Jin Kwon
2

Seperti yang disarankan di sini, Anda juga dapat memasukkan HttpServletRequestparameter sebagai metode, misalnya:

public MyResponseObject myApiMethod(HttpServletRequest request, ...) {
    ...
}
Akan Kain
sumber