מבוא ל- DispatcherServlet האביב

1. הקדמה

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

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

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

2. DispatcherServlet בקש עיבוד

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

בואו להעמיק יותר כיצד א DispatcherServlet מעבד רכיב:

  • ה WebApplicationContext משויך ל- DispatcherServlet מתחת למפתח DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE הוא חיפש ויעמיד לרשות כל מרכיבי התהליך
  • ה DispatcherServlet מוצא את כל היישומים של HandlerAdapter ממשק מוגדר לשולח שלך באמצעות getHandler () - כל יישום שנמצא ומוגדר מטפל בבקשה באמצעות ידית() דרך המשך התהליך
  • ה LocaleResolver קשורה באופן אופציונלי לבקשה לאפשר לאלמנטים בתהליך לפתור את האזור
  • ה ThemeResolver קשורה באופן אופציונלי לבקשה לאלמנטים, כגון תצוגות, לקבוע באיזה נושא להשתמש
  • אם ריבוי פתרונות מוגדר, נבדקת הבקשה MultipartFiles - כל המצוי עטוף בא MultipartHttpServletRequest להמשך עיבוד
  • HandlerExceptionResolver יישומים שהוכרזו ב WebApplicationContext קולט חריגים שנזרקים במהלך עיבוד הבקשה

תוכל ללמוד עוד על כל הדרכים להרשמה ולהגדרת א DispatcherServlet פה.

3. HandlerAdapter ממשקים

ה HandlerAdapter ממשק מאפשר שימוש בבקרים, סרוולטים, Http בקשות, ונתיבי HTTP דרך כמה ממשקים ספציפיים. ה HandlerAdapter הממשק ממלא אפוא תפקיד מהותי בשלבים רבים של DispatcherServlet בקש זרימת עבודה לעיבוד.

ראשית, כל אחד HandlerAdapter היישום ממוקם בתוך HandlerExecutionChain מהשולח שלך getHandler () שיטה. ואז, כל אחת מהיישומים האלה ידית() ה HttpServletRequest חפץ ככל שרשת הביצוע מתקדמת.

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

3.1. מיפיות

כדי להבין מיפוי, עלינו לבחון תחילה כיצד להוסיף הערות לבקרים מכיוון שבקרים כל כך חיוניים ל HandlerMapping מִמְשָׁק.

ה SimpleControllerHandlerAdapter מאפשר יישום של בקר באופן מפורש ללא @בקר ביאור.

ה RequestMappingHandlerAdapter תומך בשיטות המסומנות עם ה- @ בקשת מיפוי ביאור.

אנו נתמקד ב @בקר ביאור כאן, אך משאב מועיל עם מספר דוגמאות המשתמשות ב- SimpleControllerHandlerAdapter זמין גם כן.

ה @ בקשת מיפוי ביאור מגדיר את נקודת הקצה הספציפית שבה מטפל יהיה זמין בתוך ה WebApplicationContext קשור אליו.

בואו נראה דוגמה של א בקר שחושף ומטפל ב '/ User / example' נקודת סיום:

@Controller @RequestMapping ("/ user") @ResponseBody מחלקה ציבורית UserController {@GetMapping ("/ example") משתמש ציבורי fetchUserExample () {// ...}}

הנתיבים שצוינו על ידי @ בקשת מיפוי ההערות מנוהלות באופן פנימי באמצעות HandlerMapping מִמְשָׁק.

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

לפיכך, אם ה DispatcherServlet ממופה ל- '/', ואז כל המיפויים יכוסו על ידי המיפוי הזה.

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

זכור כי '/' אינו זהה ל- '/ *' למיפוי סרבלים! '/' הוא מיפוי ברירת המחדל וחושף את כל כתובות האתר לתחום האחריות של השולח.

‘/ *’ מבלבל להרבה מפתחי אביב חדשים יותר. הוא לא מציין שכל הנתיבים עם אותו הקשר של URL הם בתחום האחריות של השולח. במקום זאת, הוא עוקף ומתעלם ממיפויי השולח האחרים. אז, '/ דוגמה' תעלה כ- 404!

מסיבה זו, אין להשתמש ב- '/ *' אלא בנסיבות מוגבלות מאוד (כמו קביעת תצורה של פילטר).

3.2. טיפול בבקשות HTTP

האחריות המרכזית של א DispatcherServlet זה למשלוח נכנס Http בקשות למטפלים הנכונים צוין עם @בקר אוֹ @ RestController ביאורים.

כהערה צדדית, ההבדל העיקרי בין @בקר ו @ RestController כיצד נוצרת התגובה - @ RestController מגדיר גם @ResponseBody כברירת מחדל.

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

3.3. ה ViewResolver מִמְשָׁק

א ViewResolver מחובר לא DispatcherServlet כהגדרת תצורה ב- ApplicationContext לְהִתְנַגֵד.

א ViewResolver קובע הן איזה סוג דעות מוגש על ידי השולח והן מאיפה הם מוגשים.

הנה תצורה לדוגמא שנכניס לתוכנו AppConfig לעיבוד דפי JSP:

@Configuration @EnableWebMvc @ComponentScan ("com.baeldung.springdispatcherservlet") AppConfig מחלקה ציבורית מיישמת WebMvcConfigurer {@Bean הציבור UrlBasedViewResolver viewResolver () {UrlBasedViewResolver resolver = חדש UrlBas; resolver.setPrefix ("/ WEB-INF / view /"); resolver.setSuffix (". jsp"); resolver.setViewClass (JstlView.class); פותר להחזיר; }}

מאוד ישר קדימה! ישנם שלושה חלקים עיקריים לכך:

  1. הגדרת הקידומת, שקובעת את נתיב ברירת המחדל של כתובת ה- URL למציאת תצוגות התצורה שבתוכה
  2. סוג התצוגה המוגדר כברירת מחדל המוגדר באמצעות הסיומת
  3. הגדרת כיתת תצוגה במפתן המאפשרת לשייך טכנולוגיות כמו JSTL או Tiles לתצוגות שניתנו

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

הנה תצורת נתיב לדוגמא ל- InternalViewResolver באמצעות תצורת ה- XML ​​של Spring:

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

// localhost: 8080 /

זוהי כתובת והיציאה המוגדרים כברירת מחדל עבור שרת Apache Tomcat המתארח במקום.

בהנחה שהבקשה שלנו נקראת dispatcherexample-1.0.0, תצוגות ה- JSP שלנו יהיו נגישות מ:

//localhost:8080/dispatcherexample-1.0.0/jsp/

הנתיב לתצוגות אלו במסגרת פרויקט אביב רגיל עם מייבן הוא זה:

src - | ראשי - | משאבי java webapp - | jsp WEB-INF

מיקום ברירת המחדל לתצוגות הוא בתוך WEB-INF. הנתיב שצוין עבורנו InternalViewResolver בקטע הקוד שלמעלה קובע את תיקיית המשנה של 'src / main / webapp' בה תצוגותיך יהיו זמינות.

3.4. ה LocaleResolver מִמְשָׁק

הדרך העיקרית להתאים אישית מידע על הפעלות, בקשות או קובצי cookie לשולח שלנו היא באמצעות LocaleResolver מִמְשָׁק.

CookieLocaleResolver הוא יישום המאפשר תצורה של מאפייני יישומים חסרי מדינה באמצעות קובצי Cookie. בואו נוסיף את זה ל AppConfig.

@Bean CookieLocaleResolver ציבוריים cookieLocaleResolverExample () {CookieLocaleResolver localeResolver = CookieLocaleResolver חדש (); localeResolver.setDefaultLocale (Locale.ENGLISH); localeResolver.setCookieName ("דוגמה של קובץ cookie-resolver"); localeResolver.setCookieMaxAge (3600); אזור החזרה Resolver; } @Bean Local LocaleResolver sessionLocaleResolver () {SessionLocaleResolver localeResolver = SessionLocaleResolver חדש (); localeResolver.setDefaultLocale (Locale.US); localResolver.setDefaultTimeZone (TimeZone.getTimeZone ("UTC")); אזור החזרה Resolver; } 

SessionLocaleResolver מאפשר תצורה ספציפית להפעלה ביישום סטטיסטי.

ה setDefaultLocale() השיטה מייצגת אזור גיאוגרפי, פוליטי או תרבותי, ואילו setDefaultTimeZone() קובע את הרלוונטי אזור זמן אובייקט ליישום אפונה בשאלה.

שתי השיטות זמינות בכל אחת מהיישומים לעיל של LocaleResolver.

3.5. ה ThemeResolver מִמְשָׁק

אביב מספק נושא סגנוני לדעותינו.

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

ראשון, בואו נקבע את כל התצורה הדרושה כדי למצוא ולהשתמש בקבצי הנושא הסטטיים שלנו. עלינו להגדיר מיקום משאב סטטי עבורנו ThemeSource להגדרת התצורה בפועל ערכות נושא עצמם (נושא אובייקטים מכילים את כל פרטי התצורה שנקבעו בקבצים אלה). הוסף את זה ל AppConfig:

@ ביטול ציבורי ריק ריק AddResourceHandlers (רישום ResourceHandlerRegistry) {registry.addResourceHandler ("/ resources / **") .addResourceLocations ("/", "/ resources /") .setCachePeriod (3600) .resourceChain (true) .addResolver (PathResourceResolver חדש) ()); } @Bean הציבור ResourceBundleThemeSource themeSource () {ResourceBundleThemeSource themeSource = חדש ResourceBundleThemeSource (); themeSource.setDefaultEnoding ("UTF-8"); themeSource.setBasenamePrefix ("ערכות נושא."); להחזיר themeSource; } 

בקשות המנוהלות על ידי DispatcherServlet יכול לשנות את ערכת הנושא באמצעות פרמטר שצוין שהועבר אליו setParamName() זמין ב- ThemeChangeInterceptor לְהִתְנַגֵד. להוסיף ל AppConfig:

@Bean ציבורי CookieThemeResolver themeResolver () {פותר קובץ CookieThemeResolver = חדש CookieThemeResolver (); resolver.setDefaultThemeName ("דוגמה"); resolver.setCookieName ("דוגמה-נושא-קובץ cookie"); פותר להחזיר; } @Bean ציבורי ThemeChangeInterceptor themeChangeInterceptor () {ThemeChangeInterceptor מיירט = חדש ThemeChangeInterceptor (); interceptor.setParamName ("נושא"); מיירט חזרה; } @Override ריקים ציבוריים addInterceptors (InterceptorRegistry registry) {registry.addInterceptor (themeChangeInterceptor ()); } 

תג JSP הבא נוסף לתצפית שלנו כדי להראות את הסטיילינג הנכון:

בקשת כתובת האתר הבאה מעבדת את דוגמא ערכת הנושא באמצעות הפרמטר 'נושא' שהועבר לתצורה שלנו ThemeChangeIntercepter:

//localhost:8080/dispatcherexample-1.0.0/?theme=example

3.6. ה ריבוי פתרונות מִמְשָׁק

א ריבוי פתרונות היישום בודק בקשה למספר חלקים ועוטף אותם בא MultipartHttpServletRequest להמשך עיבוד על ידי אלמנטים אחרים בתהליך אם נמצא לפחות חלק אחד. להוסיף ל AppConfig:

@Bean Public CommonsMultipartResolver multipartResolver () זורק IOException {CommonsMultipartResolver resolver = new CommonsMultipartResolver (); resolver.setMaxUploadSize (10000000); פותר להחזיר; } 

עכשיו לאחר שהגדרנו את שלנו ריבוי פתרונות שעועית, בוא נקבע בקר לעיבוד MultipartFile בקשות:

@Controller מחלקה ציבורית ברבים MultipartController {@Autowired ServletContext context; @PostMapping ("/ upload") ModelAndView ציבורי קובץ uploadController (@RequestParam ("קובץ") קובץ MultipartFile) זורק IOException {ModelAndView modelAndView = חדש ModelAndView ("אינדקס"); InputStream ב = file.getInputStream (); נתיב מחרוזת = קובץ חדש ("."). GetAbsolutePath (); FileOutputStream f = FileOutputStream חדש (path.substring (0, path.length () - 1) + "/ העלאות /" + file.getOriginalFilename ()); int ch; ואילו ((ch = in.read ())! = -1) {f.write (ch); } f.flush (); f.close (); בקרוב(); modelAndView.getModel () .put ("הודעה", "הקובץ הועלה בהצלחה!"); modelAndView להחזיר; }}

אנו יכולים להשתמש בטופס רגיל כדי להגיש קובץ לנקודת הקצה שצוינה. קבצים שהועלו יהיו זמינים ב 'CATALINA_HOME / bin / uploads'.

3.7. ה HandlerExceptionResolver מִמְשָׁק

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

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

@ControllerAdvice class class ExampleGlobalExceptionHandler {@ExceptionHandler @ResponseBody public handle StringExampleException (Exception e) {// ...}}

כל השיטות בתוך הכיתה באותה הערה @ExceptionHandler יהיה זמין בכל בקר שבתחום האחריות של השולח.

יישומים של HandlerExceptionResolver ממשק ב ApplicationContext של DispatcherServlet זמינים ל ליירט בקר ספציפי תחת אחריותו של אותו שולח בְּכָל פַּעַם @ExceptionHandler משמש כהערה, והמחלקה הנכונה מועברת כפרמטר:

@Controller מחלקה ציבורית FooController {@ExceptionHandler ({CustomException1.class, CustomException2.class}) handle publicException בטל () {// ...} // ...}

ה handleException () שיטה ישמש כעת כמטפל חריג עבור FooController בדוגמה שלנו לעיל אם אחד החריגים CustomException 1 אוֹ CustomException2 מתרחשת.

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

4. מסקנה

במדריך זה סקרנו את האביב DispatcherServlet וכמה דרכים להגדיר אותו.

כמו תמיד, קוד המקור המשמש במדריך זה זמין ב- Github.


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