Menukar Parameter Model Spring dengan Handler Interceptor

1. Pengenalan

Dalam tutorial ini kita akan memfokus pada Spring MVC HandlerInterceptor. Lebih khusus lagi, kami akan mengubah parameter model Spring MVC sebelum dan sesudah menangani permintaan.

Sekiranya anda ingin membaca mengenai asas - asas HandlerInterceptor, baca artikel ini.

2. Pergantungan Maven

Untuk menggunakan Interceptors , anda perlu memasukkan bahagian berikut dalam bahagian dependencies pada fail pom.xml anda :

 org.springframework spring-web 5.2.8.RELEASE  

Versi terkini boleh didapati di sini.

Ketergantungan ini hanya merangkumi Spring Web jadi jangan lupa untuk menambahkan konteks pring-core dan spring untuk aplikasi web penuh, dan perpustakaan log pilihan anda.

3. Pelaksanaan Adat

Salah satu kes penggunaan HandlerInterceptor adalah menambahkan parameter umum / pengguna khusus ke model, yang akan tersedia pada setiap paparan yang dihasilkan.

Dalam contoh kami, kami akan menggunakan pelaksanaan pencegat khusus untuk menambahkan nama pengguna pengguna yang log masuk ke parameter model. Dalam sistem yang lebih kompleks, kami mungkin menambah maklumat yang lebih khusus seperti: laluan avatar pengguna, lokasi pengguna, dll.

Mari mulakan dengan menentukan kelas Interceptor baru kami :

public class UserInterceptor extends HandlerInterceptorAdapter { private static Logger log = LoggerFactory.getLogger(UserInterceptor.class); ... }

Kami memperluas HandlerInterceptorAdapter , kerana kami hanya ingin menerapkan kaedah preHandle () dan postHandle () .

Seperti yang telah kami sebutkan sebelumnya, kami ingin menambahkan nama pengguna yang masuk ke model. Pertama sekali, kita perlu memeriksa sama ada pengguna log masuk. Kita boleh mendapatkan maklumat ini dengan memeriksa SecurityContextHolder :

public static boolean isUserLogged() { try { return !SecurityContextHolder.getContext().getAuthentication() .getName().equals("anonymousUser"); } catch (Exception e) { return false; } }

Apabila HttpSession dibuat, tetapi tidak ada yang log masuk, nama pengguna dalam konteks Spring Security sama dengan anonymousUser . Seterusnya, kami meneruskan pelaksanaan preHandle ():

3.1. Kaedah praHandle ()

Sebelum menangani permintaan, kami tidak dapat mengakses parameter model. Untuk menambahkan nama pengguna, kita perlu menggunakan HttpSession untuk menetapkan parameter:

@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception { if (isUserLogged()) { addToModelUserDetails(request.getSession()); } return true; }

Ini sangat penting jika kita menggunakan sebilangan maklumat ini sebelum menangani permintaan. Seperti yang kita lihat, kita memeriksa apakah pengguna log masuk dan kemudian menambahkan parameter pada permintaan kita dengan mendapatkan sesi:

private void addToModelUserDetails(HttpSession session) { log.info("=============== addToModelUserDetails ========================="); String loggedUsername = SecurityContextHolder.getContext().getAuthentication().getName(); session.setAttribute("username", loggedUsername); log.info("user(" + loggedUsername + ") session : " + session); log.info("=============== addToModelUserDetails ========================="); }

Kami menggunakan SecurityContextHolder untuk mendapatkan Nama Pengguna yang dicatat . Anda boleh mengatasi pelaksanaan Spring Security UserDetails untuk mendapatkan e-mel dan bukannya nama pengguna standard.

3.2. Kaedah p ostHandle ()

Setelah menangani permintaan, parameter model kami tersedia, jadi kami dapat mengaksesnya untuk mengubah nilai atau menambahkan yang baru. Untuk melakukannya, kami menggunakan kaedah postHandle () yang diganti :

@Override public void postHandle( HttpServletRequest req, HttpServletResponse res, Object o, ModelAndView model) throws Exception { if (model != null && !isRedirectView(model)) { if (isUserLogged()) { addToModelUserDetails(model); } } }

Mari lihat perincian pelaksanaannya.

Pertama sekali, lebih baik memeriksa sama ada model itu tidak kosong. Ini akan menghalang kita daripada menemui NullPointerException .

Lebih-lebih lagi, kami dapat memeriksa apakah Tampilan bukan contoh Redirect View.

Tidak perlu menambah / mengubah parameter setelah permintaan ditangani dan kemudian diarahkan, dengan segera, pengawal baru akan melakukan penanganan lagi. Untuk memeriksa apakah pandangan diarahkan, kami memperkenalkan kaedah berikut:

public static boolean isRedirectView(ModelAndView mv) { String viewName = mv.getViewName(); if (viewName.startsWith("redirect:/")) { return true; } View view = mv.getView(); return (view != null && view instanceof SmartView && ((SmartView) view).isRedirectView()); }

Akhirnya, kami memeriksa lagi jika pengguna log, dan jika ya, kami menambahkan parameter pada model Spring:

private void addToModelUserDetails(ModelAndView model) { log.info("=============== addToModelUserDetails ========================="); String loggedUsername = SecurityContextHolder.getContext() .getAuthentication().getName(); model.addObject("loggedUsername", loggedUsername); log.trace("session : " + model.getModel()); log.info("=============== addToModelUserDetails ========================="); }

Harap maklum bahawa pembalakan sangat penting, kerana logik ini berfungsi "di belakang tabir" aplikasi kami. Kita lupa bahawa kita mengubah beberapa parameter model pada setiap Tampilan tanpa mencatatnya dengan betul.

4. Konfigurasi

Untuk menambahkan Interceptor yang baru dibuat ke konfigurasi Spring, kita perlu mengganti kaedah addInterceptors () di dalam kelas WebConfig yang menerapkan WebMvcConfigurer:

@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new UserInterceptor()); }

Kami mungkin mencapai konfigurasi yang sama dengan mengedit fail konfigurasi Spring XML kami:

Mulai saat ini, kami dapat mengakses semua parameter yang berkaitan dengan pengguna pada semua paparan yang dihasilkan.

Harap perhatikan, jika beberapa Spring Interceptors dikonfigurasikan, kaedah preHandle () dijalankan mengikut susunan konfigurasi sedangkan kaedah postHandle () dan afterCompletion () dipanggil dalam urutan terbalik.

5. Kesimpulan

Tutorial ini menyajikan permintaan web pemintas menggunakan HandlerInterceptor Spring MVC untuk memberikan maklumat pengguna.

Dalam contoh khusus ini, kami memfokuskan pada menambahkan butiran pengguna yang dicatat dalam aplikasi web kami ke parameter model. Anda boleh memperluaskan pelaksanaan HandlerInterceptor ini dengan menambahkan maklumat yang lebih terperinci.

Semua contoh dan konfigurasi terdapat di sini di GitHub.

5.1. Artikel dalam Siri

Semua artikel siri ini:

  • Pengenalan kepada Interceptors Spring MVC Handler
  • Menukar Parameter Model Musim Semi dengan Pemegang Interceptor (yang ini)