מבוא ל- MVC HandlerInterceptor באביב

1. הקדמה

במדריך זה נתמקד בהבנת ה- MVC באביב HandlerInterceptor ואיך להשתמש בו נכון.

2. מטפל MVC באביב

על מנת להבין את המיירט, בואו ניקח צעד אחורה ונסתכל על ה- HandlerMapping. זה ממפה שיטה לכתובת אתר, כך שה- DispatcherServlet יוכל להפעיל אותה בעת עיבוד בקשה.

וה DispatcherServlet משתמש ב- HandlerAdapter להפעיל את השיטה בפועל.

עכשיו שאנחנו מבינים את ההקשר הכללי - כאן נכנס מיירט המטפל. נשתמש ב- HandlerInterceptor לבצע פעולות לפני הטיפול, לאחר הטיפול, או לאחר השלמתו (כאשר התצוגה מוצגת), של בקשה.

המיירט יכול לשמש לחששות רוחביים ולהימנע מקוד מטפל חוזר כמו רישום, שינוי פרמטרים בשימוש גלובלי במודל האביב וכו '.

בחלקים הקרובים זה בדיוק מה שנבחן - ההבדלים בין יישומי יירוט שונים.

3. תלות Maven

על מנת להשתמש מיירטים, עליך לכלול את החלק הבא בא תלות החלק שלך pom.xml קוֹבֶץ:

 org.springframework spring-web 5.2.8.RELEASE 

הגרסה האחרונה תוכל למצוא כאן.

4. מיירט מטפל באביב

מיירטים העובדים עם HandlerMapping על המסגרת חייבת ליישם את HandlerInterceptor מִמְשָׁק.

ממשק זה מכיל שלוש שיטות עיקריות:

  • טיפול מראש () - נקרא לפני שמבצע המטפל בפועל, אך התצוגה עדיין לא נוצרה
  • postHandle () - נקרא לאחר הוצאתו להורג של המטפל
  • afterCompletion () - התקשר לאחר סיום הבקשה המלאה ונוצרה התצוגה

שלוש השיטות הללו מספקות גמישות לבצע כל מיני עיבודים לפני ואחרי.

והערה מהירה - ההבדל העיקרי בין HandlerInterceptor ו HandlerInterceptorAdapter הוא שבראשונה עלינו לבטל את כל שלוש השיטות: preHandle (), postHandle () ו afterCompletion ()ואילו בשנייה אנו עשויים ליישם רק שיטות נדרשות.

הערה מהירה לפני שנמשיך הלאה - אם אתה רוצה לדלג על התיאוריה ולקפוץ ישר לדוגמאות, קפוץ ישר לסעיף 5.

הנה מה פשוט preHandle () היישום ייראה כך:

@Override preHandle בוליאני ציבורי (בקשת HttpServletRequest, תגובה HttpServletResponse, מטפל באובייקט) זורק חריג {// הקוד חוזר נכון; }

שימו לב שהשיטה מחזירה א בוליאני value - אשר אומר ל- Spring אם המטפל צריך לעבד את הבקשה נוספת (נָכוֹן) או שלא (שֶׁקֶר).

לאחר מכן, יש לנו יישום של postHandle ():

@Override public void postHandle (בקשת HttpServletRequest, תגובה HttpServletResponse, מטפל באובייקטים, ModelAndView modelAndView) זורק חריג {// הקוד שלך}

שיטה זו נקראת מיד לאחר עיבוד הבקשה HandlerAdapter, אבל לפני שמייצרים נוף.

וכמובן שניתן להשתמש בה בדרכים רבות - למשל, אנו עשויים להוסיף אווטר של משתמש מחובר למודל.

השיטה הסופית שעלינו ליישם במנהג HandlerInterceptor היישום הוא afterCompletion ():

@ ביטול ציבורי בטל לאחר השלמה (בקשת HttpServletRequest, תגובת HttpServletResponse, מטפל באובייקטים, חריג למשל) {// הקוד שלך}

כאשר התצוגה נוצרת בהצלחה, אנו יכולים להשתמש בקרס זה כדי לעשות דברים כמו לאסוף נתונים סטטיסטיים נוספים הקשורים לבקשה.

הערה אחרונה שיש לזכור היא כי א HandlerInterceptor רשום ל DefaultAnnotationHandlerMapping שעועית, האחראית להחלת מיירטים על כל כיתות המסומנות בסימן א @בקר ביאור. יתר על כן, אתה רשאי לציין כל מספר מיירטים ביישום האינטרנט שלך.

5. מיירט לוגר מותאם אישית

בדוגמה זו נתמקד בכניסה ליישום האינטרנט שלנו. קודם כל, הכיתה שלנו צריכה להאריך HandlerInterceptorAdapter:

מחלקה ציבורית LoggerInterceptor מרחיב את HandlerInterceptorAdapter {...}

עלינו גם לאפשר כניסה למיירט שלנו:

יומן לוגר סטטי פרטי = LoggerFactory.getLogger (LoggerInterceptor.class);

זה מאפשר ל- Log4J להציג יומנים, וכן לציין, איזה מחלקה כרגע רושם מידע לפלט שצוין.

לאחר מכן, נתמקד ביישומי יירוט מותאמים אישית:

5.1. שיטה preHandle ()

שיטה זו נקראת לפני הטיפול בבקשה; זה חוזר נָכוֹן, כדי לאפשר למסגרת לשלוח את הבקשה הלאה לשיטת המטפל (או למיירט הבא). אם השיטה חוזרת שֶׁקֶר, אביב מניח כי הבקשה טופלה ואין צורך בעיבוד נוסף.

אנו יכולים להשתמש בקרס כדי לרשום מידע על פרמטרי הבקשות: מאיפה הבקשה וכו '.

בדוגמה שלנו, אנו רושמים מידע זה באמצעות לוגר פשוט של Log4J:

@ Override preHandle בוליאני ציבורי (HttpServletRequest בקשה, HttpServletResponse תגובה, מטפל אובייקטים) זורק חריג {log.info ("[preHandle] [" + בקשה + "]" + "[" + request.getMethod () + "]" + בקשה .getRequestURI () + getParameters (בקשה)); לחזור אמיתי; } 

כפי שאנו רואים, אנו רושמים מידע בסיסי על הבקשה.

במקרה שנקלע לסיסמה כאן, נצטרך לוודא שלא נרשום זאת כמובן.

אפשרות פשוטה היא להחליף סיסמאות וכל סוג נתונים רגיש אחר בכוכבים.

להלן יישום מהיר של אופן הפעולה:

מחרוזת פרטית getParameters (בקשת HttpServletRequest) {StringBuffer פורסם = StringBuffer חדש (); ספירה e = request.getParameterNames (); אם (e! = null) {posted.append ("?"); } בעוד (e.hasMoreElements ()) {if (posted.length ()> 1) {posted.append ("&"); } מחרוזת curr = (String) e.nextElement (); posted.append (curr + "="); אם (curr.contains ("סיסמה") || curr.contains ("pass") || curr.contains ("pwd")) {posted.append ("*****"); } אחר {posted.append (request.getParameter (curr)); }} מחרוזת ip = request.getHeader ("X-FORWARDED-FOR"); מחרוזת ipAddr = (ip == null)? getRemoteAddr (בקשה): ip; אם (ipAddr! = null &&! ipAddr.equals ("")) {posted.append ("& _ psip =" + ipAddr); } החזרה שפורסמה. toString (); }

לבסוף, אנו שואפים לקבל את כתובת ה- IP המקורית של בקשת ה- HTTP.

הנה יישום פשוט:

מחרוזת פרטית getRemoteAddr (HttpServletRequest בקשה) {String ipFromHeader = request.getHeader ("X-FORWARDED-FOR"); אם (ipFromHeader! = null && ipFromHeader.length ()> 0) {log.debug ("ip מ- proxy - X-FORWARDED-FOR:" + ipFromHeader); החזר ipFromHeader; } להחזיר request.getRemoteAddr (); }

5.2. שיטה postHandle ()

וו זה פועל כאשר ה- HandlerAdapter מופעל על המטפל אך DispatcherServlet עדיין לא נותן את הנוף.

אנו יכולים להשתמש בשיטה זו כדי להוסיף תכונות נוספות ל- ModelAndView או לקבוע את הזמן שנדרש לשיטת המטפל לעיבוד בקשת הלקוח.

במקרה שלנו, אנחנו פשוט רושמים בקשה לפני כן DispatcherServlet הולך להציג תצוגה.

@Override public void voHandle (בקשת HttpServletRequest, HttpServletResponse, מטפל באובייקטים, ModelAndView modelAndView) זורק חריג {log.info ("[postHandle] [" + בקשה + "]"); }

5.3. שיטה afterCompletion ()

לאחר סיום הבקשה והתצוגה מוצגת, אנו עשויים לקבל נתוני בקשה ותגובה, כמו גם מידע על חריגים, אם התרחשו:

@ ביטול ציבורי בטל לאחר השלמה (בקשת HttpServletRequest, תגובת HttpServletResponse, מטפל באובייקטים, ex exception) זורק Exception {if (ex! = Null) {ex.printStackTrace (); } log.info ("[afterCompletion] [" + בקשה + "] [יוצא מן הכלל:" + ex + "]"); }

6. תצורה

כדי להוסיף את המיירטים שלנו בתצורת האביב, עלינו לעקוף addInterceptors () שיטה בפנים WebConfig כיתה שמיישמת WebMvcConfigurer:

@Override ריקים ציבוריים addInterceptors (InterceptorRegistry registry) {registry.addInterceptor (LoggerInterceptor חדש ()); }

אנו עשויים להשיג את אותה תצורה על ידי עריכת קובץ התצורה של XML Spring שלנו:

כאשר תצורה זו פעילה, המיירט יהיה פעיל וכל הבקשות ביישום יירשמו כהלכה.

שימו לב, אם מוגדרים מיירטים מרובי קפיצים, ה- preHandle () השיטה מתבצעת לפי סדר התצורה, ואילו postHandle () ו afterCompletion () שיטות מופעלות בסדר הפוך.

אם אנו משתמשים באביב אתחול במקום באביב וניל, עלינו לזכור שלא להעלות הערה על מחלקת התצורה שלנו @EnableWebMvc, או שנפסיד בתצורות האוטומטיות של Boot.

7. מסקנה

מדריך זה הוא מבוא מהיר ליירוט בקשות HTTP באמצעות Spring MVC Handler Interceptor.

כל הדוגמאות והתצורות זמינות כאן ב- GitHub.