ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 01.12.2023
Просмотров: 467
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Что такое ViewResolver?
ViewResolver – распознаватель представлений, это способ работы с представлениями
(html-файлы), который поддерживает их распознавание на основе имени, возвращаемого контроллером.
Spring Framework поставляется с большим количеством реализаций ViewResolver.
Например, класс UrlBasedViewResolver поддерживает прямое преобразование логических имен в URL.
InternalResourceViewResolver – реализация ViewResolver по умолчанию, которая позволяет находить представления, которые возвращает контроллер для последующего перехода к ним. Ищет по заданному пути, префиксу, суффиксу и имени.
Любым реализациям ViewResolver желательно поддерживать интернационализацию, то есть множество языков.
Существует также несколько реализаций для интеграции с различными технологиями представлений, такими как FreeMarker (FreeMarkerViewResolver), Velocity
(VelocityViewResolver) и JasperReports (JasperReportsViewResolver).
Чем отличаются Model, ModelMap и ModelAndView?
Model – интерфейс, представляет коллекцию пар ключ-значение Map
Содержимое модели используется для отображения данных во View.
Например, если View выводит информацию об объекте Customer, то она может ссылаться к ключам модели, например, customerName, customerPhone, и получать значения для этих ключей.
Объекты-значения из модели также могут содержать бизнес-логику.
ModelMap – класс, наследуется от LinkedHashMap, используется для передачи значений для визуализации представления.
Преимущество ModelMap заключается в том, что он дает возможность передавать коллекцию значений и обрабатывать эти значения, как если бы они были внутри Map.
ModelAndView – это контейнер для ModelMap, объект View и HttpStatus. Это позволяет контроллеру возвращать все значения как одно.
View используется для отображения данных приложения пользователю.
Spring MVC поддерживает несколько поставщиков View (они называются шаблонизаторы) –
JSP, JSF, Thymeleaf, и т. п.
Интерфейс View преобразует объекты в обычные сервлеты.
Расскажите про паттерн Front Controller, как он реализован в Spring?
Front Controller обеспечивает единую точку входа для всех входящих запросов. Все запросы обрабатываются одним обработчиком – DispatcherServlet с маппингом “/”. Этот обработчик может выполнить аутентификацию, авторизацию, регистрацию или отслеживание запроса, а затем распределяет их между контроллерами, обрабатывающими разные URL. Это и есть реализация паттерна Front Controller.
Веб-приложение может определять любое количество DispatcherServlet-ов. Каждый из них будет работать в собственном пространстве имен, загружая собственный дочерний
WebApplicationContext с вьюшками, контроллерами и т. д.
•
один из контекстов будет корневым, а все остальные контексты будут дочерними;
•
все дочерние контексты могут получить доступ к бинам, определенным в корневом контексте, но не наоборот;
•
каждый дочерний контекст внутри себя может переопределить бины из корневого контекста.
WebApplicationContext расширяет ApplicationContext (создает и управляет бинами и т. д.), но помимо этого имеет дополнительный метод getServletContext(), через который у него есть возможность получать доступ к ServletContext-у.
ContextLoaderListener создает корневой контекст приложения и будет использоваться всеми дочерними контекстами, созданными всеми DispatcherServlet-ами.
Расскажите про паттерн MVC, как он реализован в Spring?
MVC – это шаблон проектирования, делящий программу на 3 вида компонентов:
1. Model – модель отвечает за хранение данных.
2. View – отвечает за вывод данных на фронтенде.
3. Controller – оперирует моделями и отвечает за обмен данными model с view.
Основная цель следования принципам MVC – отделить реализацию бизнес-логики приложения (модели) от ее визуализации (view).
Spring MVC – это веб-фреймворк, основанный на Servlet API с использованием двух шаблонов проектирования Front controller и MVC.
Spring MVC реализует четкое разделение задач, что позволяет легко разрабатывать и тестировать приложения. Данные задачи разбиты между разными компонентами: Dispatcher
Servlet, Controllers, View Resolvers, Views, Models, ModelAndView, Model and Session
Attributes, которые полностью независимы друг от друга и отвечают только за одно направление. Поэтому MVC предоставляет большую гибкость. Он основан на интерфейсах
(с классами реализации), и можно настраивать каждую часть фреймворка с помощью пользовательских интерфейсов.
Основные интерфейсы для обработки запросов:
DispatcherServlet является главным контроллером, который получает запросы и распределяет их между другими контроллерами. @RequestsMapping указывает, какие именно запросы будут обрабатываться в конкретном контроллере. Может быть несколько экземпляров DispatcherServlet, отвечающих за разные задачи (обработка запросов пользовательского интерфейса, REST служб и т. д.). Каждый экземпляр DispatcherServlet имеет собственную конфигурацию WebApplicationContext.
HandlerMapping. Выбор класса и его метода, которые должны обработать данный входящий запрос на основе любого внутреннего или внешнего для этого запроса атрибута или состояния.
Controller оперирует моделями и отвечает за обмен данными model с view.
ViewResolver. Выбор, какое именно View должно быть показано клиенту на основе имени,
полученного от контроллера.
View. Отвечает за возвращение ответа клиенту в виде текстов и изображений. Используются встраиваемые шаблонизаторы (Thymeleaf, FreeMarker и т. д.), так как у Spring нет родных.
Некоторые запросы могут идти прямо во View, не заходя в Model, другие проходят через все слои.
HandlerAdapter. Помогает DispatcherServlet вызвать и выполнить метод для обработки входящего запроса.
ContextLoaderListener – слушатель при старте и завершении корневого класса Spring
WebApplicationContext. Основным назначением является связывание жизненного цикла
ApplicationContext и ServletContext, а также автоматического создания ApplicationContext.
Можно использовать этот класс для доступа к бинам из различных контекстов спринга.
Ниже приведена последовательность событий, соответствующая входящему HTTP-запросу:
•
после получения HTTP-запроса DispatcherServlet обращается к интерфейсу
HandlerMapping, который определяет, какой контроллер (Controller) должен быть вызван, после чего HandlerAdapter отправляет запрос в нужный метод контроллера;
•
контроллер принимает запрос и вызывает соответствующий метод, вызванный метод формирует данные Model и возвращает их в DispatcherServlet вместе с именем View
(как правило имя html-файла);
•
при помощи интерфейса ViewResolver DispatcherServlet определяет, какое View нужно использовать на основании имени, полученного от контроллера;
•
если это REST-запрос на сырые данные (JSON/XML), то DispatcherServlet сам его отправляет, минуя ViewResolver;
•
если обычный запрос, то DispatcherServlet отправляет данные Model в виде атрибутов во View-шаблонизаторы Thymeleaf, FreeMarker и т. д., которые сами отправляют ответ.
Таким образом, все действия происходят через один DispatcherServlet.
Что такое АОП? Как реализовано в спринге?
Аспектно-ориентированное программирование (АОП)
– это парадигма программирования, целью которой является повышение модульности за счет разделения междисциплинарных задач. Это достигается путем добавления дополнительного поведения к существующему коду без изменения самого кода.
АОП предоставляет возможность реализации сквозной логики в одном месте, т. е. логики,
которая применяется к множеству частей приложения, и обеспечения автоматического применения этой логики по всему приложению.
Аспект в АОП – это модуль или класс, реализующий сквозную функциональность. Аспект изменяет поведение остального кода, применяя совет в точках соединения, определенных некоторым срезом.
Совет (advice) – дополнительная логика, код, который должен быть вызван из точки соединения.
Точка соединения (join point) – место в выполняемой программе (вызов метода, создание объекта, обращение к переменной), где следует применить совет.
Срез (pointcut) – набор точек соединения.
Подход Spring к АОП заключается в создании «динамических прокси» для целевых объектов и «привязывании» объектов к конфигурированному совету для выполнения сквозной логики.
Есть два варианта создания прокси-класса:
•
либо он должен наследоваться от оригинального класса (CGLIB) и переопределять его методы, добавляя нужную логику;
•
либо он должен имплементировать те же самые интерфейсы, что и первый класс
(Dynamic Proxy).
В чем разница между Filters, Listeners and Interceptors?
Filter выполняет задачи фильтрации либо по пути запроса к ресурсу, либо по пути ответа от ресурса, либо в обоих направлениях.
Фильтры выполняют фильтрацию в методе doFilter. Каждый фильтр имеет доступ к объекту
FilterConfig, из которого он может получить параметры инициализации, и ссылку на
ServletContext. Фильтры настраиваются в дескрипторе развертывания веб-приложения.
При создании цепочки фильтров, веб-сервер решает, какой фильтр вызывать первым, в соответствии с порядком регистрации фильтров.
Когда вызывается метод doFilter(...) первого фильтра, веб-сервер создает объект FilterChain,
представляющий цепочку фильтров, и передает ее в метод.
Фильтры зависят от контейнера сервлетов, могут работать с js, css.
Interceptor являются аналогом Filter в Spring. Перехватить запрос клиента можно в трех местах: preHandle, postHandle и afterCompletion.
Перехватчики работают с HandlerMapping и поэтому должны реализовывать интерфейс
HandlerInterceptor или наследоваться от готового класса HandlerInterceptorAdapter, после чего переопределить указанные методы.
Чтобы добавить перехватчики в конфигурацию Spring, необходимо переопределить метод addInterceptors() внутри класса, который реализует WebMvcConfigurer.
Interceptor основан на механизме Reflection, а фильтр основан на обратном вызове функции.
preHandle – метод используется для обработки запросов, которые еще не были переданы в метод контроллера. Должен вернуть true для передачи следующему перехватчику или в handler method. False укажет на обработку запроса самим обработчиком и отсутствию необходимости передавать его дальше. Метод имеет возможность выкидывать исключения и пересылать ошибки к представлению.
postHandle – вызывается после handler method, но до обработки DispatcherServlet для передачи представлению. Может использоваться для добавления параметров в объект
ModelAndView.
afterCompletion – вызывается после отрисовки представления.
Listener – это класс, имплементирующий интерфейс ServletContextListener с аннотацией
@WebListener. Listener ждет, когда произойдет указанное событие, затем «перехватывает»
событие и запускает собственное событие. Он инициализируется только один раз при запуске веб-приложения и уничтожается при остановке веб-приложения. Все
ServletContextListeners уведомляются об инициализации контекста до инициализации любых фильтров или сервлетов в веб-приложении и об уничтожении контекста после того, как все сервлеты и фильтры уничтожены.
Можно ли передать в запросе один и тот же параметр несколько раз? Как?
Да, можно принять все значения, используя массив в методе контроллера:
http://localhost:8080/login?name=Ranga&name=Ravi&name=Sathish
public String method(@RequestParam(value="name") String[] names){...}
http://localhost:8080/api/foos?id=1,2,3
public String getFoos(@RequestParam List
1 ... 17 18 19 20 21 22 23 24 25
Как работает Spring Security? Как сконфигурировать? Какие интерфейсы
используются?
Кратко:
Основными блоками Spring Security являются:
•
SecurityContextHolder, чтобы обеспечить доступ к SecurityContext;
•
SecurityContext содержит объект Authentication и в случае необходимости информацию системы безопасности, связанную с запросом;
•
Authentication представляет принципала с точки зрения Spring Security;
•
GrantedAuthority отражает разрешения, выданные доверителю в масштабе всего приложения;
•
UserDetails предоставляет необходимую информацию для построения объекта
Authentication из DAO-объектов приложения или других источника данных системы безопасности;
•
UserDetailsService создает UserDetails, если передано имя пользователя в виде
String (или идентификатор сертификата или что-то подобное).
Подробно:
Самым фундаментальным является SecurityContextHolder. В нем храним информацию о текущем контексте безопасности приложения, который включает в себя подробную информацию о пользователе, работающем с приложением. По умолчанию
SecurityContextHolder использует MODE_THREADLOCAL для хранения такой информации.
Это означает, что контекст безопасности всегда доступен для методов, исполняющихся в том же самом потоке, даже если контекст безопасности явно не передается в качестве аргумента этих методов:
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails выступает в качестве принципала.
MODE_GLOBAL – все потоки Java-машины используют один контекст безопасности.
MODE_INHERITABLETHREADLOCAL – потоки, порожденные от одного защищенного потока, наличие аналогичной безопасности.
Интерфейс UserDetailsService – подход к загрузке информации о пользователе в Spring
Security. Единственный метод этого интерфейса принимает имя пользователя в виде String и возвращает UserDetails. Он представляет собой принципала, но в расширенном виде и с учетом специфики приложения.
В случае успешной аутентификации UserDetails используется для создания Authentication объекта, который хранится в SecurityContextHolder.
Еще одним важным методом Authentication явлется getAuthorities() – массив объектов
GrantedAuthority (роли).
Credentials – под ними понимаются пароль пользователя, но им может быть и отпечаток пальца, фото сетчатки и т. п.
Процесс аутентификации:
1. UsernamePasswordAuthenticationFilter получают имя пользователя и пароль и создает экземпляр класса UsernamePasswordAuthenticationToken (экземпляр интерфейса
Authentication).
2. Токен передается экземпляру AuthenticationManager для проверки.
3. AuthenticationManager возвращает полностью заполненный экземпляр Authentication в случае успешной аутентификации.
4. Устанавливается контекст безопасности через вызов
SecurityContextHolder.getContext().setAuthentication(...), куда передается вернувшийся экземпляр Authentication.
5. При успешной аутентификации можно использовать successHandler.