אביב - בקשות כניסה נכנסות

1. הקדמה

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

2. תלות Maven

תלות הרישום פשוט תהיה זהה לאלה שבמאמר המבוא; בואו פשוט להוסיף אביב כאן:

 org.springframework spring-core 5.2.2.RELEASE 

הגרסה האחרונה יכולה להימצא כאן עבור אביב הליבה.

3. בקר אינטרנט בסיסי

ראשית, נגדיר בקר שישמש בדוגמה שלנו:

@RestController מחלקה ציבורית TaxiFareController {@GetMapping ("/ taxifare / get /") ציבורי RateCard getTaxiFare () {להחזיר RateCard חדש (); } @PostMapping ("/ taxifare / calc /") ציבורי מחרוזת calcTaxiFare (@RequestBody @Valid TaxiRide taxiRide) {// להחזיר את המחיר המחושב}}

4. רישום בקשות בהתאמה אישית

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

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

  1. preHandle () - שיטה זו מבוצעת לפני שיטת שירות הבקר בפועל
  2. afterCompletion () - שיטה זו מבוצעת לאחר שהבקר מוכן לשלוח את התגובה

יתר על כן, Spring מספק את יישום ברירת המחדל של HandlerInterceptor ממשק בצורה של HandlerInterceptorAdaptor מחלקה אשר ניתן להרחיב על ידי המשתמש.

בואו ניצור מיירט משלנו - על ידי הרחבה HandlerInterceptorAdaptor כפי ש:

@Component class class TaxiFareRequestInterceptor מרחיב את HandlerInterceptorAdapter {@Override pre-Handy בוליאני ציבורי (HttpServletRequest בקשה, HttpServletResponse תגובה, אובייקט מטפל) {return true; } @ ביטול ציבורי בטל לאחר השלמה (בקשת HttpServletRequest, תגובה HttpServletResponse, מטפל באובייקטים, חריג לשעבר) {//}}

לבסוף, נגדיר את ה- TaxiRideRequestInterceptor בתוך מחזור החיים של MVC כדי ללכוד עיבודים לפני ואחרי של קריאות שיטת בקר אשר ממופות לנתיב / taxifare מוגדר ב TaxiFareController מעמד.

@Configuration מעמד ציבורי TaxiFareMVCConfig מיישם את WebMvcConfigurer {@ TaxiFareRequestInterceptor פרטית מאושרת TaxiFareRequestInterceptor; @ ביטול ריקים ציבוריים addInterceptors (רישום InterceptorRegistry) {registry.addInterceptor (taxiFareRequestInterceptor) .addPathPatterns ("/ ** / taxifare / ** /"); }}

לסיכום, ה WebMvcConfigurer מוסיף TaxiFareRequestInterceptor בתוך מחזור החיים של MVC באביב על ידי הפעלת addInterceptors () שיטה.

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

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

היישום ישליך חריג לאחר קריאת זרם הבקשה:

{"חותמת זמן": 1500645243383, "status": 400, "error": "בקשה רעה", "חריג": "org.springframework.http.converter. HttpMessageNotReadableException", "message": "לא ניתן לקרוא את המסמך: הזרם נסגר ; חריג מקונן הוא java.io.IOException: זרם סגור "," path ":" / rest-log / taxifare / calcute / "}

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

Spring מספק כמה שיעורים שימושיים כגון ContentCachingRequestWrapper ו- ContentCachingResponseWrapper אשר ניתן להשתמש בהם במטמון נתוני הבקשה לצורך רישום.

בואו נתאים את שלנו preHandle () שֶׁל TaxiRideRequestInterceptor מחלקה למטמון אובייקט הבקשה באמצעות ContentCachingRequestWrapper מעמד.

@Override מראש בוליאני ציבורי (HttpServletRequest בקשה, HttpServletResponse תגובה, מטפל באובייקטים) {HttpServletRequest requestCacheWrapperObject = ContentCachingRequestWrapper חדש (בקשה); requestCacheWrapperObject.getParameterMap (); // קרא את inputStream מ- requestCacheWrapperObject והתחבר שהוא יחזור נכון; }

כפי שאנו רואים, שמרנו את אובייקט הבקשה באמצעות המטמון ContentCachingRequestWrapper מחלקה שבה ניתן להשתמש כדי לקרוא את נתוני המטען לצורך רישום מבלי להפריע לאובייקט הבקשה בפועל:

requestCacheWrapperObject.getContentAsByteArray ();

הַגבָּלָה

  • ContentCachingRequestWrapper הכיתה תומכת רק בדברים הבאים:
סוג תוכן: יישום / x-www-form-urlencoded שיטת סוג: POST
  • עלינו להפעיל את השיטה הבאה כדי להבטיח שמירה של נתוני בקשה במטמון ContentCachingRequestWrapper לפני השימוש בו:
requestCacheWrapperObject.getParameterMap ();

5. רישום בקשות מובנה באביב

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

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

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

  • CommonsRequestLoggingFilter
  • Log4jNestedDiagnosticContextFilter (הוצא משימוש)
  • ServletContextRequestLoggingFilter

עכשיו, בוא נעבור ל CommonsRequestLoggingFilter ולהגדיר אותו כדי ללכוד בקשה נכנסת לרישום.

5.1. הגדר את הגדרת יישום אתחול האביב

ניתן להגדיר יישום Spring Boot על ידי הוספת הגדרת שעועית כדי לאפשר רישום בקשות:

@Configuration class class RequestLoggingFilterConfig {@Bean Public CommonsRequestLoggingFilter logFilter () {CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter (); filter.setIncludeQueryString (נכון); filter.setIncludePayload (true); filter.setMaxPayloadLength (10000); filter.setIncludeHeaders (false); filter.setAfterMessagePrefix ("בקשת נתונים:"); מסנן החזרה; }}

כמו כן, מסנן רישום זה מחייב להגדיר את רמת היומן ל- DEBUG. אנו יכולים להפעיל את מצב DEBUG על ידי הוספת האלמנט להלן ב- logback.xml:

דרך נוספת לאפשר את יומן הרמה DEBUG היא להוסיף את הדברים הבאים ב application.properties:

logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter = DEBUG

5.2. הגדר תצורת יישום אינטרנט מסורתי

ביישום האינטרנט הרגיל של Spring, לְסַנֵן ניתן להגדיר באמצעות תצורת XML או תצורת Java. בוא נקים את CommonsRequestLoggingFilter באמצעות תצורה מבוססת Java קונבנציונאלית.

כידוע, ה includePayload תכונה של CommonsRequestLoggingFilter מוגדר כ- false כברירת מחדל. נצטרך מחלקה מותאמת אישית כדי לבטל את ערך התכונה כדי לאפשר אותה includePayload לפני ההזרקה למיכל באמצעות תצורת Java:

class class CustomeRequestLoggingFilter מרחיב CommonsRequestLoggingFilter {public CustomeRequestLoggingFilter () {super.setIncludeQueryString (true); super.setIncludePayload (נכון); super.setMaxPayloadLength (10000); }}

עכשיו, אנחנו צריכים להזריק את CustomeRequestLoggingFilter באמצעות אתחול אינטרנט מבוסס Java:

מחלקה ציבורית CustomWebAppInitializer מיישם את WebApplicationInitializer {public void onStartup (ServletContext container) {AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext (); context.setConfigLocation ("com.baeldung"); container.addListener (ContextLoaderListener חדש (הקשר)); ServletRegistration.Dynamic dispatcher = container.addServlet ("dispatcher", DispatcherServlet חדש (הקשר)); dispatcher.setLoadOnStartup (1); dispatcher.addMapping ("/"); container.addFilter ("customRequestLoggingFilter", CustomeRequestLoggingFilter.class) .addMappingForServletNames (null, false, "dispatcher"); }}

6. דוגמה בפעולה

כעת נוכל לחבר אתחול האביב עם הקשר ולראות בפעולה כי רישום בקשות נכנסות פועל כצפוי:

@Test הציבור בטל givenRequest_whenFetchTaxiFareRateCard_thanOK () {TestRestTemplate testRestTemplate = TestRestTemplate חדש (); TaxiRide taxiRide = TaxiRide חדש (נכון, 10 ליטר); מחיר מחרוזת = testRestTemplate.postForObject (URL + "חישוב /", taxiRide, String.class); assertThat (מחיר, שווה ל- ("200"); }

7. מסקנה

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

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

כמו תמיד, היישום של דוגמאות וקטעי קוד זמין ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found