I have my main layouts in /src/main/webapp/WEB-INF/layouts/layouts.xml with examples, for example:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd"> <tiles-definitions> <definition name="default" template="/WEB-INF/layouts/default.jspx"> <put-attribute name="menu" value="/WEB-INF/views/menu.jspx"/> <put-attribute name="sidebar" value="/WEB-INF/views/sidebar.jspx"/> <put-attribute name="header" value="/WEB-INF/views/header.jspx" /> <put-attribute name="footer" value="/WEB-INF/views/footer.jspx" /> </definition> <definition name="public" template="/WEB-INF/layouts/default.jspx"> <put-attribute name="menu" value="/WEB-INF/views/menu.jspx"/> <put-attribute name="sidebar" value="/WEB-INF/views/sidebar.jspx"/> <put-attribute name="header" value="/WEB-INF/views/header.jspx" /> <put-attribute name="footer" value="/WEB-INF/views/footer.jspx" /> </definition> </tiles-definitions>
And then more specific fragment definitions in /src/main/webapp/WEB-INF/views/views.xml with examples, for example:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd"> <tiles-definitions> <definition extends="default" name="index"> <put-attribute name="body" value="/WEB-INF/views/index.jspx"/> </definition> <definition extends="public" name="login"> <put-attribute name="sidebar" value=""></put-attribute> <put-attribute name="body" value="/WEB-INF/views/login.jspx"/> </definition> </tiles-definitions>
Then you need your configuration class:
@EnableWebMvc @Configuration public class RootMvcConfiguration extends WebMvcConfigurerAdapter { ... @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/login").setViewName("login"); } ... }
Beans in this class that are interlaced are dependent - if you want to use JSP or Thymeleaf.
For JSP you should have:
@Bean public UrlBasedViewResolver tilesViewResolver(){ UrlBasedViewResolver tilesViewResolver = new UrlBasedViewResolver(); tilesViewResolver.setViewClass(TilesView.class); return tilesViewResolver; } @Bean public TilesConfigurer tilesConfigurer(){ String[] definitions = new String[] { "/WEB-INF/layouts/layouts.xml", "/WEB-INF/views/**/views.xml" }; TilesConfigurer tilesConfigurer = new TilesConfigurer(); tilesConfigurer.setDefinitions(definitions); return tilesConfigurer; }
If you are using Thymeleaf, you should have something like this:
@Bean public MessageSource messageSource(){ ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasenames("classpath:META-INF/i18n/messages"); messageSource.setFallbackToSystemLocale(false); return messageSource; } @Bean public ServletContextTemplateResolver templateResolver() { ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(); resolver.setPrefix("/WEB-INF/"); resolver.setSuffix(".html"); resolver.setTemplateMode("HTML5"); resolver.setOrder(2); resolver.setCacheable(false); return resolver; } @Bean public SpringTemplateEngine templateEngine() throws Exception { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.setTemplateResolver(templateResolver()); engine.setTemplateEngineMessageSource(messageSource()); engine.addDialect(new TilesDialect()); engine.addDialect(new SpringSecurityDialect()); engine.afterPropertiesSet(); return engine; } @Bean public TilesConfigurer tilesConfigurer(){ String[] definitions = new String[] { "/WEB-INF/layouts/layouts.xml", "/WEB-INF/views/**/views.xml" }; ThymeleafTilesConfigurer tilesConfigurer = new ThymeleafTilesConfigurer(); tilesConfigurer.setDefinitions(definitions); return tilesConfigurer; }
Then you can expand your views.xml and point view names in your jsp or html files, and an example controller might be the following:
@RequestMapping("/roles") @Controller public class RoleController { @RequestMapping(value = "/{id}", method = RequestMethod.GET) public String show(@PathVariable("id") Integer id, Model uiModel) { uiModel.addAttribute("role", Role.findRole(id)); uiModel.addAttribute("itemId", id); return "roles/show"; } }
If you are using Maven, here are some examples of lib versions:
<properties> <thymeleaf.version>2.0.19</thymeleaf.version> <thymeleaf.extras.version>2.0.0</thymeleaf.extras.version> <thymeleaf.extras.security.version>2.0.0</thymeleaf.extras.security.version> <tiles.version>2.2.2</tiles.version> </properties> ... <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <dependency> <groupId>org.apache.tiles</groupId> <artifactId>tiles-core</artifactId> <version>${tiles.version}</version> </dependency> <dependency> <groupId>org.apache.tiles</groupId> <artifactId>tiles-jsp</artifactId> <version>${tiles.version}</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>${thymeleaf.version}</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring3</artifactId> <version>${thymeleaf.version}</version> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity3</artifactId> <version>${thymeleaf.extras.security.version}</version> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-tiles2</artifactId> <version>${thymeleaf.extras.version}</version> </dependency>