jar (thymeleaf-spring3-{version}.
jar и thymeleaf-spring4-{version}.
jar) и должны быть добавлены в ваш путь к классам, чтобы использовать интеграцию Thymeleaf Spring в вашем приложении.
В примерах кода и примере приложения в этом руководстве используется Spring 4.x и связанные с ним интеграции Thymeleaf, но содержимое этого текста также применимо и к Spring 3.x. Если ваше приложение использует Spring 3.x, все, что вам нужно сделать, это заменить пакет org.thymeleaf.spring4 на org.thymeleaf.spring3 в примерах кода.
1. Интеграция Thymeleaf со Spring
Thymeleaf предлагает набор интеграций Spring, которые позволяют использовать его в качестве полнофункциональной замены JSP в приложениях Spring MVC. Эти интеграции позволят вам: Сопоставьте методы в ваших объектах Spring MVC. Контроллер шаблоны, управляемые Thymeleaf, точно так же, как и JSP. Используйте в своих шаблонах язык выражений Spring (Spring EL) вместо OGNL. Создавайте формы в своих шаблонах, которые полностью интегрированы с компонентами поддержки форм и привязками результатов, включая использование редакторов свойств, служб преобразования и обработки ошибок проверки.Отображать сообщения интернационализации из файлов сообщений, управляемых Spring (через обычные объекты MessageSource).
Найдите свои шаблоны, используя собственные механизмы разрешения ресурсов Spring. Обратите внимание: чтобы полностью понять это руководство, вам необходимо сначала пройти руководство " Использование Тимелеафа ", где подробно объясняется стандартный диалект.
2. Стандартный диалект Spring
Чтобы обеспечить более простую и лучшую интеграцию, Thymeleaf предоставляет диалект, который специально реализует все необходимые функции для правильной работы с Spring. Этот конкретный диалект основан на стандартном диалекте Thymeleaf и реализован в классе org.thymeleaf.spring4.dialect.SpringStandardDialect, который на самом деле происходит от org.thymeleaf.standard.StandardDialect. В дополнение ко всем функциям, уже присутствующим в стандартном диалекте и, следовательно, унаследованным, SpringStandard Dialect предлагает следующие специфические функции: Использование языка выражений Spring (Spring EL или SpEL) в качестве языка выражений переменных, а не OGNL. Поэтому все выражения ${.} И *{.
} будет оцениваться механизмом языка выражений Spring. Также обратите внимание, что доступна поддержка компилятора Spring EL (Spring 4.2.4+).
Получите доступ к любым компонентам в контексте вашего приложения, используя синтаксис SpringEL: ${@myBean.doSomething()} Новые атрибуты для обработки форм: й:поле , го: ошибки И й:класс ошибок , за исключением новой реализации й:объект , что позволяет использовать его для выбора команды формы.
Объект и метод выражения #themes.code(.
) , что эквивалентно пользовательскому тегу JSP весна: тема .
Метод объекта и выражения, #mvc.uri(.
) , что эквивалентно пользовательской функции JSP весна:mvcUrl(.
) (Только весна 4.1+).
Обратите внимание, что в большинстве случаев вам не следует использовать этот диалект непосредственно в обычном объекте TemplateEngine как часть его конфигурации.
Если у вас нет особых потребностей в интеграции Spring, вместо этого вам следует создать экземпляр нового класса механизма шаблонов, который автоматически выполняет все необходимые шаги настройки: org.thymeleaf.spring4.SpringTemplateEngine .
Пример конфигурации bean-компонента:
Или, используя конфигурацию Spring на основе XML:@Bean public SpringResourceTemplateResolver templateResolver(){ // SpringResourceTemplateResolver automatically integrates with Spring's own // resource resolution infrastructure, which is highly recommended. SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); templateResolver.setApplicationContext(this.applicationContext); templateResolver.setPrefix("/WEB-INF/templates/"); templateResolver.setSuffix(".
html"); // HTML is the default value, added here for the sake of clarity. templateResolver.setTemplateMode(TemplateMode.HTML); // Template cache is true by default. Set to false if you want // templates to be automatically updated when modified. templateResolver.setCacheable(true); return templateResolver; } @Bean public SpringTemplateEngine templateEngine(){ // SpringTemplateEngine automatically applies SpringStandardDialect and // enables Spring's own MessageSource message resolution mechanisms. SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver()); // Enabling the SpringEL compiler with Spring 4.2.4 or newer can // speed up execution in most scenarios, but might be incompatible // with specific cases when expressions in one template are reused // across different data types, so this flag is "false" by default // for safer backwards compatibility. templateEngine.setEnableSpringELCompiler(true); return templateEngine; }
<!-- SpringResourceTemplateResolver automatically integrates with Spring's own -->
<!-- resource resolution infrastructure, which is highly recommended. -->
<bean id="templateResolver"
class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/" />
<property name="suffix" value=".
html" />
<!-- HTML is the default value, added here for the sake of clarity. -->
<property name="templateMode" value="HTML" />
<!-- Template cache is true by default. Set to false if you want -->
<!-- templates to be automatically updated when modified. -->
<property name="cacheable" value="true" />
</bean>
<!-- SpringTemplateEngine automatically applies SpringStandardDialect and -->
<!-- enables Spring's own MessageSource message resolution mechanisms. -->
<bean id="templateEngine"
class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<!-- Enabling the SpringEL compiler with Spring 4.2.4 or newer can speed up -->
<!-- execution in most scenarios, but might be incompatible with specific -->
<!-- cases when expressions in one template are reused across different data -->
<!-- ypes, so this flag is "false" by default for safer backwards -->
<!-- compatibility. -->
<property name="enableSpringELCompiler" value="true" />
</bean>
3. Представления и преобразователи представлений
3.1 Представления и преобразователи представлений в Spring MVC
Spring MVC имеет два интерфейса, которые соответствуют ядру его системы шаблонов: org.springframework.web.servlet.View org.springframework.web.servlet.ViewResolver Взгляды моделируют страницы в наших приложениях и позволяют нам изменять и предопределять их поведение, определяя их как bean-компоненты.Представления отвечают за рендеринг фактического HTML-интерфейса, обычно используя какой-либо механизм шаблонов, например Thymeleaf. Просмотр резольверов являются объектами, ответственными за получение объектов Вид для конкретной операции и локали.
Обычно контроллеры просят ViewResolvers переслать представление с определенным именем (строка, возвращаемая методом контроллера), а затем все преобразователи представлений в приложении выполняются в упорядоченной цепочке до тех пор, пока один из них не сможет разрешить это представление, после чего возвращается объект View, и ему передается управление для рендеринга HTML. Обратите внимание, что не все страницы в наших приложениях нужно определять как представления, а только те, поведение которых мы хотим, чтобы оно было нестандартным или настроено особым образом (например, подключив к нему какие-то специальные компоненты).
Если ПросмотрРезолвер запрашивается представление, не имеющее соответствующего bean-компонента (что является частым случаем), создается новый объект View для этого случая и возвращается.
Типичная конфигурация JSP + JSTL ViewResolver в прошлом приложении Spring MVC это выглядело так: <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsps/" />
<property name="suffix" value=".
jsp" />
<property name="order" value="2" />
<property name="viewNames" value="*jsp" />
</bean>
Достаточно беглого взгляда на его свойства, чтобы понять, как он был настроен:
ViewNames позволяет указать (с подстановочными знаками) имена представлений, которые будут разрешены этим ViewResolver.
3.2 Представления и преобразователи представлений в Thymeleaf
Thymeleaf предлагает реализации для двух упомянутых выше интерфейсов: org.thymeleaf.spring4.view.ThymeleafView org.thymeleaf.spring4.view.ThymeleafViewResolver Эти два класса будут отвечать за обработку шаблонов Thymeleaf в результате выполнения контроллера.
Конфигурация Resolver Thymeleaf View очень похожа на JSP: @Bean
public ThymeleafViewResolver viewResolver(){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
// NOTE 'order' and 'viewNames' are optional
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[] {".
html", ".
xhtml"});
return viewResolver;
}
.
или в XML: <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
<!-- NOTE 'order' and 'viewNames' are optional -->
<property name="order" value="1" />
<property name="viewNames" value="*.
html,*.
xhtml" />
</bean>
Параметр ШаблонEngine Разумеется, это объект SpringTemplateEngine, который мы определили в предыдущей главе.
Два других ( заказ И ViewNames ) не являются обязательными и имеют то же значение, что и в JSP ViewResolver, который мы видели ранее.
Обратите внимание, что нам не нужны параметры префикса или суффикса, поскольку они уже указаны в преобразователе шаблонов (который, в свою очередь, передается в механизм шаблонов).
Что, если мы хотим определить Просмотр компонента И добавьте к нему несколько статических переменных ? Легко, просто определите для него прототип: @Bean
@Scope("prototype")
public ThymeleafView mainView() {
ThymeleafView view = new ThymeleafView("main"); // templateName = 'main'
view.setStaticVariables(
Collections.singletonMap("footer", "The ACME Fruit Company"));
return view;
}
Сделав это, вы можете запросить этот компонент, выбрав его по имени (в данном случае mainView).
4. Стартовый менеджер из семян весеннего тимьяна
Исходный код примеров, показанных в этой и последующих главах этого руководства, можно найти в репозитории.GitHub Spring Seyme Начальный менеджер семян .
4.1 Концепция
Что касается тимьяна — мы большие поклонники тимьяна и каждую весну готовим стартовые наборы с хорошей почвой и нашими любимыми семенами, сажаем их на испанское солнце и терпеливо ждем, пока вырастут наши новые растения.Но в этом году нам надоело наклеивать этикетки на стартовые контейнеры с семенами, чтобы узнать, какие семена находятся в каждой ячейке контейнера, поэтому мы решили подготовить приложение с использованием Spring MVC и Тимелиф чтобы помочь нам каталогизировать наши закуски: Менеджер SeedStarter весеннего тимьяна .
Подобно приложению Good Thymes Virtual Grocery, которое мы разработали в руководстве по использованию Thymeleaf, STSM позволит нам продемонстрировать наиболее важные аспекты интеграции Thymeleaf в качестве механизма шаблонов для Spring MVC.
4.2 Бизнес-уровень
Для нашего приложения нам понадобится очень простой бизнес-уровень.
Прежде всего, давайте посмотрим на объекты нашей модели:
Пара очень простых сервисных классов предоставит необходимые бизнес-методы.
Нравиться: @Service
public class SeedStarterService {
@Autowired
private SeedStarterRepository seedstarterRepository;
public List<SeedStarter> findAll() {
return this.seedstarterRepository.findAll();
}
public void add(final SeedStarter seedStarter) {
this.seedstarterRepository.add(seedStarter);
}
}
И: @Service
public class VarietyService {
@Autowired
private VarietyRepository varietyRepository;
public List<Variety> findAll() {
return this.varietyRepository.findAll();
}
public Variety findById(final Integer id) {
return this.varietyRepository.findById(id);
}
}
4.3 Конфигурация Spring MVC
Тогда нам нужно настроить конфигурацию Spring MVC для приложения, которое будет включать не только стандартные артефакты Spring MVC, такие как обработка ресурсов или сканирование аннотаций, но и создание экземпляров.Шаблонизатор И Посмотреть преобразователь .
@Configuration
@EnableWebMvc
@ComponentScan
public class SpringWebConfig
extends WebMvcConfigurerAdapter implements ApplicationContextAware {
private ApplicationContext applicationContext;
public SpringWebConfig() {
super();
}
public void setApplicationContext(final ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
/* ******************************************************************* */
/* GENERAL CONFIGURATION ARTIFACTS */
/* Static Resources, i18n Messages, Formatters (Conversion Service) */
/* ******************************************************************* */
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/images/**").
addResourceLocations("/images/"); registry.addResourceHandler("/css/**").
addResourceLocations("/css/"); registry.addResourceHandler("/js/**").
addResourceLocations("/js/"); } @Bean public ResourceBundleMessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("Messages"); return messageSource; } @Override public void addFormatters(final FormatterRegistry registry) { super.addFormatters(registry); registry.addFormatter(varietyFormatter()); registry.addFormatter(dateFormatter()); } @Bean public VarietyFormatter varietyFormatter() { return new VarietyFormatter(); } @Bean public DateFormatter dateFormatter() { return new DateFormatter(); } /* **************************************************************** */ /* THYMELEAF-SPECIFIC ARTIFACTS */ /* TemplateResolver <- TemplateEngine <- ViewResolver */ /* **************************************************************** */ @Bean public SpringResourceTemplateResolver templateResolver(){ // SpringResourceTemplateResolver automatically integrates with Spring's own // resource resolution infrastructure, which is highly recommended. SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); templateResolver.setApplicationContext(this.applicationContext); templateResolver.setPrefix("/WEB-INF/templates/"); templateResolver.setSuffix(".
html");
// HTML is the default value, added here for the sake of clarity.
templateResolver.setTemplateMode(TemplateMode.HTML);
// Template cache is true by default. Set to false if you want
// templates to be automatically updated when modified.
templateResolver.setCacheable(true);
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine(){
// SpringTemplateEngine automatically applies SpringStandardDialect and
// enables Spring's own MessageSource message resolution mechanisms.
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
// Enabling the SpringEL compiler with Spring 4.2.4 or newer can
// speed up execution in most scenarios, but might be incompatible
// with specific cases when expressions in one template are reused
// across different data types, so this flag is "false" by default
// for safer backwards compatibility.
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
@Bean
public ThymeleafViewResolver viewResolver(){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
return viewResolver;
}
}
4.4 Контроллер
Конечно, для нашего приложения нам также понадобится контроллер.
Поскольку STSM будет содержать только одну веб-страницу со списком начальных значений и формой добавления новых, мы напишем только один класс контроллера для всех взаимодействий с сервером: @Controller
public class SeedStarterMngController {
@Autowired
private VarietyService varietyService;
@Autowired
private SeedStarterService seedStarterService;
.
}
Теперь давайте посмотрим, что мы можем добавить к этому классу контроллера.
Атрибуты модели
Сначала мы добавим некоторые атрибуты модели, которые нам понадобятся на странице: @ModelAttribute("allTypes")
public List<Type> populateTypes() {
return Arrays.asList(Type.ALL);
}
@ModelAttribute("allFeatures")
public List<Feature> populateFeatures() {
return Arrays.asList(Feature.ALL);
}
@ModelAttribute("allVarieties")
public List<Variety> populateVarieties() {
return this.varietyService.findAll();
}
@ModelAttribute("allSeedStarters")
public List<SeedStarter> populateSeedStarters() {
return this.seedStarterService.findAll();
}
Сопоставленные методы
Теперь идет самая важная часть контроллера — сопоставленные методы: один для отображения страницы формы, а другой для обработки добавления новых объектов.
Сидстартер .
@RequestMapping({"/","/seedstartermng"})
public String showSeedstarters(final SeedStarter seedStarter) {
seedStarter.setDatePlanted(Calendar.getInstance().
getTime());
return "seedstartermng";
}
@RequestMapping(value="/seedstartermng", params={"save"})
public String saveSeedstarter(
final SeedStarter seedStarter, final BindingResult bindingResult, final ModelMap model) {
if (bindingResult.hasErrors()) {
return "seedstartermng";
}
this.seedStarterService.add(seedStarter);
model.clear();
return "redirect:/seedstartermng";
}
4.5 Настройка службы конвертации
Обеспечить простое форматирование объектов.Дата , а также объекты Разнообразие на уровне представления мы настроили наше приложение так, чтобы объект Spring Конверсионная служба был создан и инициализирован (расширяемый WebMvcConfigurerАдаптер ), используя пару нужных нам объектов форматирования.
Посмотри снова: @Override
public void addFormatters(final FormatterRegistry registry) {
super.addFormatters(registry);
registry.addFormatter(varietyFormatter());
registry.addFormatter(dateFormatter());
}
@Bean
public VarietyFormatter varietyFormatter() {
return new VarietyFormatter();
}
@Bean
public DateFormatter dateFormatter() {
return new DateFormatter();
}
Весна форматтеры являются реализациями org.springframework.format.Formatter интерфейс.
Дополнительную информацию о том, как работает инфраструктура преобразования Spring, см.
в документации по адресу весна.
io .
Давайте посмотрим на Датаформаттер который форматирует даты в соответствии со строкой формата, присутствующей в ключе сообщения Формат даты наш Сообщения.
свойства : public class DateFormatter implements Formatter<Date> {
@Autowired
private MessageSource messageSource;
public DateFormatter() {
super();
}
public Date parse(final String text, final Locale locale) throws ParseException {
final SimpleDateFormat dateFormat = createDateFormat(locale);
return dateFormat.parse(text);
}
public String print(final Date object, final Locale locale) {
final SimpleDateFormat dateFormat = createDateFormat(locale);
return dateFormat.format(object);
}
private SimpleDateFormat createDateFormat(final Locale locale) {
final String format = this.messageSource.getMessage("date.format", null, locale);
final SimpleDateFormat dateFormat = new SimpleDateFormat(format);
dateFormat.setLenient(false);
return dateFormat;
}
}
РазнообразиеФорматтер автоматически конвертирует между нашими объектами Разнообразие и то, как мы хотим использовать их в наших формах (в основном по значениям их полей).
идентификатор ): public class VarietyFormatter implements Formatter<Variety> {
@Autowired
private VarietyService varietyService;
public VarietyFormatter() {
super();
}
public Variety parse(final String text, final Locale locale) throws ParseException {
final Integer varietyId = Integer.valueOf(text);
return this.varietyService.findById(varietyId);
}
public String print(final Variety object, final Locale locale) {
return (object != null ? object.getId().
toString() : "");
}
}
Позже мы узнаем больше о том, как эти средства форматирования влияют на отображение наших данных.
Теги: #java #Thymeleaf
-
Предупреждаем Вас О Заражении Письменно
19 Oct, 24 -
Текст Личного Сообщения В Электронном Письме
19 Oct, 24 -
Московский Python-Митап №44
19 Oct, 24