Shablonizatorlar
REST veb-xizmatlari bilan bir qatorda, Spring MVC-dan dinamik HTML-tarkibni boshqarish uchun ham foydalanishingiz mumkin. Spring MVC turli shablon texnologiyalarini qo'llab-quvvatlaydi, jumladan Thymeleaf, FreeMarker va JSP. Bundan tashqari, boshqa ko'plab shablonizatorlar Spring MVC bilan o'zlarining integratsiya vositalariga ega.
Spring Boot quyidagi shablonizatorlar uchun avtoko'ngiroqni qo'llab-quvvatlaydi:
Agar ushbu shablonizatorlardan biri default konfiguratsiya bilan ishlatilsa, unda shablonlar avtomatik ravishda src/main/resources/templates dan tanlanadi.
Xatolarni qayta ishlash
Odatiy holatda Spring Boot barcha xatolarni mos ravishda boshqaradigan /error ko'rsatadi va bu servlet konteynerida "global" xato sahifasi sifatida ro'yxatdan o'tkaziladi. Mashina mijozlari uchun bu xatolarning tafsilotlarini, HTTP status kodini va istisno xabarnomasini o'z ichiga olgan JSON shaklida javob hosil qiladi. Brauzer mijozlari uchun HTML formatida o'sha ma'lumotlarni vizualizatsiya qiluvchi "whitelabel" xato tasviri mavjud (uni sozlash uchun errorni yechadigan View qo'shing).
Agar xatolarni boshqarishning default logikasini maxsuslashtirish kerak bo'lsa, server.error xususiyatlarini o'rnatishingiz mumkin.
Odatdagi logikani to'liq almashtirish uchun ErrorController ni amalga oshirishingiz va bu turdagi bean aniqlanishini ro'yxatdan o'tkazishingiz yoki mavjud mexanizmni foydalanish uchun ErrorAttributes turidagi bean qo'shishingiz va lekin uning mazmunini o'zgartirishingiz mumkin.
BasicErrorController maxsus
ErrorController uchun asosiy klass sifatida foydalanish mumkin. Bu, ayniqsa, yangi tarkib turini boshqarish kerak bo'lganda qulay bo'ladi (odatiy boshqaruvchi faqat
text/html ni boshqaradi va qolgan barcha narsalar uchun zaxira imkoniyatini beradi). Buning uchun
BasicErrorController ni kengaytiring,
produces atributi ega
@RequestMapping anotatsiyasiga ega ochiq metod qo'shing va yangi turdagi bean yarating.
Bundan tashqari, aniqlangan boshqaruvchi uchun qaytariladigan JSON-hujjatni yoki/yoki istisno turini tuzish uchun @ControllerAdvice bilan anotatsiyalangan klassni ham aniqlashingiz mumkin, quyidagi misolda ko'rsatib o'tilganidek:
@ControllerAdvice(basePackageClasses = SomeController.class) public class MyControllerAdvice extends ResponseEntityExceptionHandler { @ResponseBody @ExceptionHandler(MyException.class) public ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) { HttpStatus status = getStatus(request); return new ResponseEntity<>(new MyErrorBody(status.value(), ex.getMessage()), status); } private HttpStatus getStatus(HttpServletRequest request) { Integer code = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); HttpStatus status = HttpStatus.resolve(code); return (status != null) ? status : HttpStatus.INTERNAL_SERVER_ERROR; } }
@ControllerAdvice(basePackageClasses = [SomeController::class]) class MyControllerAdvice : ResponseEntityExceptionHandler() { @ResponseBody @ExceptionHandler(MyException::class) fun handleControllerException(request: HttpServletRequest, ex: Throwable): ResponseEntity<*> { val status = getStatus(request) return ResponseEntity(MyErrorBody(status.value(), ex.message), status) } private fun getStatus(request: HttpServletRequest): HttpStatus { val code = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE) as Int val status = HttpStatus.resolve(code) return status ?: HttpStatus.INTERNAL_SERVER_ERROR } }
Yuqoridagi misolda, agar MyException xatosi SomeController bilan bir xil paketda aniqlangan boshqaruvchi tomonidan yaratilsa, ErrorAttributes tasviri o'rniga MyErrorBody POJO ob'ektining JSON tasviri ishlatiladi.
Ba'zi hollarda boshqaruvchi darajasida qayta ishlangan xatolar metrik infratuzilmasida ro'yxatga olinmaydi. Iloji bo'lsa, bunday istisnolarni metrik so'rovlarida qayd etish uchun, qayta ishlangan istisnoni so'rov atributi sifatida sozlash mumkin:
@Controller public class MyController { @ExceptionHandler(CustomException.class) String handleCustomException(HttpServletRequest request, CustomException ex) { request.setAttribute(ErrorAttributes.ERROR_ATTRIBUTE, ex); return "errorView"; } }
@Controller class MyController { @ExceptionHandler(CustomException::class) fun handleCustomException(request: HttpServletRequest, ex: CustomException?): String { request.setAttribute(ErrorAttributes.ERROR_ATTRIBUTE, ex) return "errorView" } }
Maxsus xato sahifalari
Agar ma'lum bir holat kodining maxsus HTML xato sahifasini ekranga chiqarish kerak bo'lsa, faylni /error katalogiga qo'shishingiz mumkin. Xato sahifalari statik HTML (ya'ni har qanday statik resurs kataloglariga qo'shilgan) yoki shablonlardan foydalangan holda qurilgan bo'lishi mumkin. Fayl nomi to'liq holat kodi yoki seriya maskasini o'z ichiga olishi kerak.
Masalan, statik HTML fayli bilan 404ni ko'rsatish uchun katalog tuzilishi quyidagicha bo'lishi kerak:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
Barcha 5xx xatolarni FreeMarker shabloni yordamida ko'rsatish uchun katalog tuzilishi quyidagicha bo'lishi kerak:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftlh
+- <other templates>
Murakkab tasvirlar uchun ErrorViewResolver interfeysini amalga oshiruvchi beanlar ham qo'shishingiz mumkin, quyidagi misolda ko'rsatib o'tilganidek:
public class MyErrorViewResolver implements ErrorViewResolver { @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { // Xohlagan modelni qaytarish uchun so'rov yoki statusdan foydalanamiz if (status == HttpStatus.INSUFFICIENT_STORAGE) { // Bu yerda biz maxsus model qiymatini qo'shishimiz mumkin new ModelAndView("myview"); } return null; } }
class MyErrorViewResolver : ErrorViewResolver { override fun resolveErrorView(request: HttpServletRequest, status: HttpStatus, model: Map<String, Any>): ModelAndView? { // Xohlagan modelni qaytarish uchun so'rov yoki statusdan foydalanamiz if (status == HttpStatus.INSUFFICIENT_STORAGE) { // Bu yerda biz maxsus model qiymatini qo'shishimiz mumkin return ModelAndView("myview") } return null } }
Bundan tashqari, odatiy ExceptionHandler anotatsiyasi bilan belgilangan metodlar va @ControllerAdvice anotatsiyasi kabi oddiy Spring MVC funksiyalaridan foydalanishingiz mumkin. ErrorController keyin barcha ishlov berilmagan istisnolarni ushlaydi.
Spring MVCdan tashqarida xato sahifalarini ko'rsatish
Spring MVCni ishlatmaydigan dasturlar uchun ErrorPagesni to'g'ridan-to'g'ri ro'yxatdan o'tkazish uchun ErrorPageRegistrar interfeysidan foydalanishingiz mumkin. Ushbu abstraktsiya bevosita pastki darajadagi o'rnatilgan servlet konteyneri bilan ishlaydi va sizda Spring MVC uchun DispatcherServlet mavjud bo'lmagan holatlarda ham yaxshi ishlaydi.
@Configuration(proxyBeanMethods = false) public class MyErrorPagesConfiguration { @Bean public ErrorPageRegistrar errorPageRegistrar() { return this::registerErrorPages; } private void registerErrorPages(ErrorPageRegistry registry) { registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400")); } }
@Configuration(proxyBeanMethods = false) class MyErrorPagesConfiguration { @Bean fun errorPageRegistrar(): ErrorPageRegistrar { return ErrorPageRegistrar { registry: ErrorPageRegistry -> registerErrorPages(registry) } } private fun registerErrorPages(registry: ErrorPageRegistry) { registry.addErrorPages(ErrorPage(HttpStatus.BAD_REQUEST, "/400")) } }
Filter bilan qayta ishlanadigan yo'lni ishlatib
ErrorPageni ro'yxatdan o'tkazayotgan bo'lsangiz (Springga tegishli bo'lmagan ba'zi veb-freymvorklar uchun umumiy, masalan, Jersey va Wicket), unda
Filter
ERROR dispetcheri sifatida aniq ro'yxatga olinishi kerak, quyidagi misolda ko'rsatib o'tilgan:
@Configuration(proxyBeanMethods = false) public class MyFilterConfiguration { @Bean public FilterRegistrationBean<MyFilter> myFilter() { FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(new MyFilter()); // ... registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class)); return registration; } }
@Configuration(proxyBeanMethods = false) class MyFilterConfiguration { @Bean fun myFilter(): FilterRegistrationBean<MyFilter> { val registration = FilterRegistrationBean(MyFilter()) // ... registration.setDispatcherTypes(EnumSet.allOf(DispatcherType::class.java)) return registration } }
Shuni yodda tutingki, FilterRegistrationBean odatda ERROR dispetcher turini o'z ichiga olmaydi.
WAR joylashtirishda xatolarni boshqarish
Servlet konteynerida joylashtirilganda Spring Boot xato kodiga mos keladigan xato sahifasiga so'rovni yo'naltirish uchun o'z xato sahifasi filtrini ishlatadi. Bu zarur, chunki servlet spetsifikatsiyasi xato sahifalarini ro'yxatdan o'tkazish uchun APIni ta'minlamaydi. Sizning war faylingizni joylashtirayotgan konteyner va dasturning foydalanayotgan texnologiyalariga qarab qo'shimcha konfiguratsiya talab qilinishi mumkin.
Xato sahifa filtri javob hali tasdiqlanmaganida to'g'ri xato sahifasiga so'rovni yo'naltirishi mumkin. Odatiy bo'lib, WebSphere Application Server 8.0 va undan keyingi versiyalar javobni servlet xizmat metodi muvaffaqiyatli yakunlangandan so'ng tasdiqlaydi. Bu xatti-harakatni com.ibm.ws.webcontainer.invokeFlushAfterService parametrini false ga o'rnatish orqali o'chirishingiz kerak.
Agar siz Spring Securitydan foydalanayotgan bo'lsangiz va xato sahifasida printsipga kirishni xohlasangiz, Spring Security filtrini xatolarni yuborishda chaqirilishi uchun sozlashingiz kerak. Buning uchun spring.security.filter.dispatcher-types xususiyatini async, error, forward, request ga o'rnating.
CORS qo'llab-quvvatlashi
Turli manbalar orasidagi resurslarni almashish (CORS) W3C spetsifikatsiyasi bo'lib, ko'pgina brauzerlar tomonidan amalga oshirilgan bo'lib, qanday turdagi domensiz so'rovlar ruxsat etilishini moslashuvchan tarzda aniqlash imkonini beradi, va u IFRAME yoki JSONP kabi kamroq xavfsiz va kamroq samarali yondashuvlarni almashtirish niyatida.
Versiya 4.2dan boshlab, Spring MVC CORSni qo'llab-quvvatlaydi. Spring Boot dasturida @CrossOrigin annotatsiyalari bilan CORS konfiguratsiyasi uchun boshqaruvchi metodini ishlatish maxsus konfiguratsiyani talab qilmaydi. Global CORS konfiguratsiyasini addCorsMappings(CorsRegistry) metodi sozlangan WebMvcConfigurer beani ro'yxatdan o'tkazish orqali aniqlash mumkin, quyidagi misolda ko'rsatilganidek:
@Configuration(proxyBeanMethods = false) public class MyCorsConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**"); } }; } }
@Configuration(proxyBeanMethods = false) class MyCorsConfiguration { @Bean fun corsConfigurer(): WebMvcConfigurer { return object : WebMvcConfigurer { override fun addCorsMappings(registry: CorsRegistry) { registry.addMapping("/api/**") } } } }
GO TO FULL VERSION