日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring MVC应用程序中的Thymeleaf模板布局,无扩展

發(fā)布時(shí)間:2023/12/3 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC应用程序中的Thymeleaf模板布局,无扩展 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在使用JSP / JSTL和Apache Tiles幾年之后,我開始為我的Spring MVC應(yīng)用程序發(fā)現(xiàn)Thymeleaf。 Thymeleaf是一個(gè)非常出色的視圖引擎,盡管目前缺乏良好的IntelliJ(投票:http: //youtrack.jetbrains.com/issue/IDEABKL-6713 )支持,但它簡化并加快了開發(fā)速度(有Eclipse)插件 )。 在學(xué)習(xí)如何使用Thymeleaf的同時(shí),我研究了使用布局的不同可能性。

除了本機(jī)片段包含機(jī)制之外 ,還至少有兩個(gè)選項(xiàng)可用于布局: Thymeleaf與Apache Tile的集成以及Thymeleaf Layout Dialect 。 兩者似乎都可以正常工作,但是受關(guān)于簡單和自定義選項(xiàng)的評論的啟發(fā),我嘗試了一下。 在這篇文章中,我將展示我創(chuàng)建了解決方案。

創(chuàng)建具有Thymeleaf支持的Spring MVC項(xiàng)目

為了快速入門,我在Thymeleaf 2.1支持下使用了Spring MVC原型 。 我通過簡單地調(diào)用原型創(chuàng)建了一個(gè)項(xiàng)目,然后將其導(dǎo)入到IntellJ中。

創(chuàng)建布局文件

在WEB-INF / views目錄中,我創(chuàng)建了一個(gè)布局文件夾,在其中放置了第一個(gè)名為default.html的布局文件:$ {view}變量將包含@Controller返回的視圖名稱和$ {view}中的內(nèi)容片段文件將放置在這里。

創(chuàng)建視圖文件

我編輯了WEB-INF / views / homeNotSignedIn.html,并按如下方式定義了內(nèi)容片段:因此,唯一的更改是定義名為content的片段并刪除重復(fù)的片段包含。 無需其他更改。 @Controller返回原始視圖名稱,與之前一樣:

@Controller class HomeController {@RequestMapping(value = "/", method = RequestMethod.GET)String index(Principal principal) {return principal != null ? "home/homeSignedIn" : "home/homeNotSignedIn";} }

我相應(yīng)地改變了其他觀點(diǎn)。

創(chuàng)建攔截器并與Spring MVC集成

為了完成“新布局框架”,我創(chuàng)建了一個(gè)處理程序攔截器來完成工作:

public class ThymeleafLayoutInterceptor extends HandlerInterceptorAdapter {private static final String DEFAULT_LAYOUT = "layouts/default";private static final String DEFAULT_VIEW_ATTRIBUTE_NAME = "view";@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {if (!modelAndView.hasView()) {return;}String originalViewName = modelAndView.getViewName();modelAndView.setViewName(DEFAULT_LAYOUT);modelAndView.addObject(DEFAULT_VIEW_ATTRIBUTE_NAME, originalViewName);} }

ThymeleafLayoutInterceptor獲取從處理程序的方法返回的原始視圖名稱,并將其替換為布局名稱(在WEB-INF / views / layouts / default.html中定義)。 原始視圖作為視圖變量放置在模型中,因此可以在布局文件中使用它。 我覆蓋了postHandle方法,因?yàn)樗窃诔尸F(xiàn)視圖之前執(zhí)行的。

添加攔截器很容易:

@Configuration public class WebMvcConfig extends WebMvcConfigurationSupport {@Overrideprotected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new ThymeleafLayoutInterceptor());} }

這就是基本配置。 此后沒有火箭。 轉(zhuǎn)到localhost:8080后的結(jié)果。 這是我所期望的。 奇跡般有效。 因此,我嘗試注冊一個(gè)帳戶以及提交表單后看到的內(nèi)容:

500 returned for /signup with message Error resolving template "redirect:/", template might not exist or might not be accessible by any of the configured Template Resolvers

當(dāng)然,
重定向:/提交表單后。 我需要像這樣修改攔截器:

public class ThymeleafLayoutInterceptor extends HandlerInterceptorAdapter {private static final String DEFAULT_LAYOUT = "layouts/default";private static final String DEFAULT_VIEW_ATTRIBUTE_NAME = "view";@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {if (!modelAndView.hasView()) {return;}String originalViewName = modelAndView.getViewName();if (isRedirectOrForward(originalViewName)) {return;}modelAndView.setViewName(DEFAULT_LAYOUT);modelAndView.addObject(DEFAULT_VIEW_ATTRIBUTE_NAME, originalViewName);} private boolean isRedirectOrForward(String viewName) {return viewName.startsWith("redirect:") || viewName.startsWith("forward:");} }

它按預(yù)期工作。 但是我意識(shí)到我需要定義和附加布局,因?yàn)镾ignup和Signin之前(而不是在應(yīng)用上述更改之后)使用了此布局。

創(chuàng)建其他布局

我創(chuàng)建了一個(gè)名為blank.html的新布局,并將其放置到WEB-INF / views / layouts文件夾中。 但是如何使用選擇布局? 可能有很多方法可以做到這一點(diǎn)。 我最簡單的方法之一就是通過簡單地添加一個(gè)名為layout的模型屬性來從@Controller返回布局名稱。 如果未給出布局,則使用默認(rèn)布局,否則使用給定布局。 簡單。 但是我想要一個(gè)更強(qiáng)大的解決方案。 所以我想也許我可以這樣使用注釋:

@Controller class SigninController {@Layout(value = "layouts/blank")@RequestMapping(value = "signin")String signin() {return "signin/signin";} }

對我來說,這聽起來像是一個(gè)很好的解決方案。 所以我實(shí)現(xiàn)了它。

選擇布局

我創(chuàng)建了一個(gè)方法級別@Layout批注,并將其放置在org.thymeleaf.spring.support包中(與ThymeleafLayoutInterceptor一起):

package org.thymeleaf.spring.support;import java.lang.annotation.*;@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Layout {String value() default ""; }

我將攔截器更改如下:

public class ThymeleafLayoutInterceptor extends HandlerInterceptorAdapter {private static final String DEFAULT_LAYOUT = "layouts/default";private static final String DEFAULT_VIEW_ATTRIBUTE_NAME = "view";@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {if (!modelAndView.hasView()) {return;}String originalViewName = modelAndView.getViewName();if (isRedirectOrForward(originalViewName)) {return;}String layoutName = getLayoutName(handler);modelAndView.setViewName(layoutName);modelAndView.addObject(DEFAULT_VIEW_ATTRIBUTE_NAME, originalViewName);}private boolean isRedirectOrForward(String viewName) {return viewName.startsWith("redirect:") || viewName.startsWith("forward:");}private String getLayoutName(Object handler) {HandlerMethod handlerMethod = (HandlerMethod) handler;Layout layout = handlerMethod.getMethodAnnotation(Layout.class);if (layout == null) {return DEFAULT_LAYOUT;} else {return layout.value();}} }

現(xiàn)在,當(dāng)使用@Layout注釋對處理程序方法進(jìn)行注釋時(shí),它將獲得其value屬性。 效果很好。 但是,當(dāng)我開始更改SignupController時(shí),我意識(shí)到我需要注釋這兩種方法。 如果可以通過對@Controller類進(jìn)行注釋,將我的注釋一次用于所有方法,那就更好了:

@Controller @Layout(value = "layouts/blank") class SignupController {}

所以我做了。

最后的修飾

首先,我更改了注釋,以便可以將其定位為類型級別:

@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Layout {String value() default ""; }

和攔截器:

public class ThymeleafLayoutInterceptor extends HandlerInterceptorAdapter {private static final String DEFAULT_LAYOUT = "layouts/default";private static final String DEFAULT_VIEW_ATTRIBUTE_NAME = "view";private String defaultLayout = DEFAULT_LAYOUT;private String viewAttributeName = DEFAULT_VIEW_ATTRIBUTE_NAME;public void setDefaultLayout(String defaultLayout) {Assert.hasLength(defaultLayout);this.defaultLayout = defaultLayout;}public void setViewAttributeName(String viewAttributeName) {Assert.hasLength(defaultLayout);this.viewAttributeName = viewAttributeName;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {if (!modelAndView.hasView()) {return;}String originalViewName = modelAndView.getViewName();if (isRedirectOrForward(originalViewName)) {return;}String layoutName = getLayoutName(handler);modelAndView.setViewName(layoutName);modelAndView.addObject(this.viewAttributeName, originalViewName);}private boolean isRedirectOrForward(String viewName) {return viewName.startsWith("redirect:") || viewName.startsWith("forward:");}private String getLayoutName(Object handler) {HandlerMethod handlerMethod = (HandlerMethod) handler;Layout layout = getMethodOrTypeAnnotation(handlerMethod);if (layout == null) {return this.defaultLayout;} else {return layout.value();}}private Layout getMethodOrTypeAnnotation(HandlerMethod handlerMethod) {Layout layout = handlerMethod.getMethodAnnotation(Layout.class);if (layout == null) {return handlerMethod.getBeanType().getAnnotation(Layout.class);}return layout;} }

如您所見,方法級別注釋比類型級別注釋更重要,這提供了一定的靈活性。 此外,我還添加了配置攔截器的可能性。 我認(rèn)為,設(shè)置默認(rèn)布局名稱和視圖屬性名稱可能會(huì)很有用。

摘要

提出的解決方案可能需要一些改進(jìn)才能在生產(chǎn)中使用,但是它顯示了我們可以簡單地構(gòu)建模板布局而無需在項(xiàng)目中添加額外的庫并僅利用Thymeleaf的核心功能。 請分享您對解決方案的評論和意見。

  • 請?jiān)贕itHub上找到源代碼: https : //github.com/kolorobot/thymeleaf-custom-layout

參考: Spring MVC應(yīng)用程序中的Thymeleaf模板布局,在Codeleak.pl博客上沒有 JCG合作伙伴 Rafal Borowiec的擴(kuò)展 。

翻譯自: https://www.javacodegeeks.com/2013/11/thymeleaf-template-layouts-in-spring-mvc-application-with-no-extensions.html

總結(jié)

以上是生活随笔為你收集整理的Spring MVC应用程序中的Thymeleaf模板布局,无扩展的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。