Thymeleaf decorator (#747)
* Expression-Based Access Control PermitAll, hasRole, hasAnyRole etc. I modified classes regards to Security * Added test cases for Spring Security Expressions * Handler Interceptor - logging example * Test for logger interceptor * Removed conflicted part * UserInterceptor (adding user information to model) * Spring Handler Interceptor - session timers * Spring Security CSRF attack protection with Thymeleaf * Fix and(); * Logger update * Changed config for Thymeleaf * Thymeleaf Natural Processing and Inlining * Expression Utility Objects, Thymeleaf * listOfStudents edited * Thymeleaf layout decorators
This commit is contained in:
parent
15f5a9eca1
commit
08c9791cb4
|
@ -67,6 +67,12 @@
|
|||
<artifactId>thymeleaf-spring4</artifactId>
|
||||
<version>${org.thymeleaf-version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/nz.net.ultraq.thymeleaf/thymeleaf-layout-dialect -->
|
||||
<dependency>
|
||||
<groupId>nz.net.ultraq.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf-layout-dialect</artifactId>
|
||||
<version>2.0.4</version>
|
||||
</dependency>
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
|
|
|
@ -22,6 +22,9 @@ import org.thymeleaf.templateresolver.ITemplateResolver;
|
|||
import com.baeldung.thymeleaf.formatter.NameFormatter;
|
||||
import com.baeldung.thymeleaf.utils.ArrayUtil;
|
||||
|
||||
import nz.net.ultraq.thymeleaf.LayoutDialect;
|
||||
import nz.net.ultraq.thymeleaf.decorators.strategies.GroupingStrategy;
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
|
@ -70,6 +73,7 @@ public class WebMVCConfig extends WebMvcConfigurerAdapter implements Application
|
|||
|
||||
private TemplateEngine templateEngine(ITemplateResolver templateResolver) {
|
||||
SpringTemplateEngine engine = new SpringTemplateEngine();
|
||||
engine.addDialect(new LayoutDialect(new GroupingStrategy()));
|
||||
engine.setTemplateResolver(templateResolver);
|
||||
return engine;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.thymeleaf.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@Controller
|
||||
public class LayoutDialectController {
|
||||
|
||||
@RequestMapping(value = "/layout", method = RequestMethod.GET)
|
||||
public String getNewPage(Model model) {
|
||||
return "content.html";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{template.html}">
|
||||
<head>
|
||||
<title>Layout Dialect Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<section layout:fragment="custom-content">
|
||||
<p>This is a custom content that you can provide</p>
|
||||
</section>
|
||||
<footer>
|
||||
<p layout:fragment="custom-footer">This is some footer content
|
||||
that you can change</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
|
@ -6,7 +6,7 @@
|
|||
</head>
|
||||
<script type="text/javascript"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
|
||||
<script th:inline="javascript">
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$.ajax({
|
||||
url : "/spring-thymeleaf/js",
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
<head>
|
||||
<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Baeldung</title>
|
||||
<script type="text/javascript"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>New dialect example</h1>
|
||||
</header>
|
||||
<section layout:fragment="custom-content">
|
||||
<p>Your page content goes here</p>
|
||||
</section>
|
||||
<footer>
|
||||
<p>My custom footer</p>
|
||||
<p layout:fragment="custom-footer">Your custom footer here</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,58 @@
|
|||
package com.baeldung.thymeleaf.controller;
|
||||
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.RequestPostProcessor;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import com.baeldung.thymeleaf.config.InitSecurity;
|
||||
import com.baeldung.thymeleaf.config.WebApp;
|
||||
import com.baeldung.thymeleaf.config.WebMVCConfig;
|
||||
import com.baeldung.thymeleaf.config.WebMVCSecurity;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = { WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class })
|
||||
public class LayoutDialectControllerTest {
|
||||
|
||||
@Autowired
|
||||
WebApplicationContext wac;
|
||||
@Autowired
|
||||
MockHttpSession session;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private Filter springSecurityFilterChain;
|
||||
|
||||
protected RequestPostProcessor testUser() {
|
||||
return user("user1").password("user1Pass").roles("USER");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilters(springSecurityFilterChain).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDates() throws Exception{
|
||||
mockMvc.perform(get("/layout").with(testUser()).with(csrf())).andExpect(status().isOk()).andExpect(view().name("content.html"));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue