- Заменил шаблонизатор Mustache на Freemarker.

https://www.youtube.com/watch?v=8MlXahJXLFg&list=PLU2ftbIeotGpAYRP9Iv2KLIwK36-o_qYk&index=7
This commit is contained in:
Leonid
2025-02-08 22:38:07 +03:00
parent c771dee930
commit 8d7cbcc165
14 changed files with 106 additions and 113 deletions

View File

@@ -24,7 +24,7 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mustache</artifactId> <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@@ -8,12 +8,11 @@ import net.sytes.kashey.sweater.security.CustomUserDetails;
import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import java.util.Map;
@Controller @Controller
public class MainController { public class MainController {
@@ -31,9 +30,14 @@ public class MainController {
} }
@GetMapping("/main") @GetMapping("/main")
public String findAllMessages(Map<String, Object> model) { public String findAllMessages(@RequestParam(required = false, defaultValue = "") String tag, Model model) {
model.put("messages", messageRepository.findAll()); if (tag == null || tag.isEmpty()) {
model.addAttribute("messages", messageRepository.findAll());
} else {
model.addAttribute("messages", messageRepository.findByTag(tag));
}
model.addAttribute("tag", tag);
return "main"; return "main";
} }
@@ -41,24 +45,15 @@ public class MainController {
public String addMessage(@AuthenticationPrincipal CustomUserDetails details, public String addMessage(@AuthenticationPrincipal CustomUserDetails details,
@RequestParam String text, @RequestParam String text,
@RequestParam String tag, @RequestParam String tag,
Map<String, Object> model) { Model model) {
User author = userRepository.findByUsername(details.getUsername()) User author = userRepository.findByUsername(details.getUsername())
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + details.getUsername())); .orElseThrow(() -> new UsernameNotFoundException("User not found: " + details.getUsername()));
messageRepository.save(new Message(text, tag, author)); messageRepository.save(new Message(text, tag, author));
model.put("messages", messageRepository.findAll()); model.addAttribute("messages", messageRepository.findAll());
model.addAttribute("tag", "");
return "main"; return "main";
} }
@PostMapping("filter")
public String filterByTag(@RequestParam String tag, Map<String, Object> model) {
if (tag == null || tag.isEmpty()) {
model.put("messages", messageRepository.findAll());
} else {
model.put("messages", messageRepository.findByTag(tag));
}
return "main";
}
} }

View File

@@ -17,11 +17,6 @@ public class Message {
public Message() { public Message() {
} }
public Message(String text, String tag) {
this.text = text;
this.tag = tag;
}
public Message(String text, String tag, User author) { public Message(String text, String tag, User author) {
this.text = text; this.text = text;
this.tag = tag; this.tag = tag;
@@ -61,6 +56,6 @@ public class Message {
} }
public String getAuthorName() { public String getAuthorName() {
return author == null ? "<none>": author.getUsername(); return author == null ? "&lt;none&gt;" : author.getUsername();
} }
} }

View File

@@ -3,5 +3,5 @@ spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/sweater_db
spring.datasource.username=user spring.datasource.username=user
spring.datasource.password=123456 spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.mustache.servlet.expose-request-attributes=true spring.freemarker.expose-request-attributes=true
spring.freemarker.suffix=.ftl

View File

@@ -0,0 +1,5 @@
<#import "parts/common.ftl" as com>
<@com.page>
<div>Hello there</div>
<a href="/main">Main page</a>
</@com.page>

View File

@@ -1,11 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div>Hello there</div>
<a href="/main">Main page</a>
</body>
</html>

View File

@@ -0,0 +1,8 @@
<#import "parts/common.ftl" as com>
<#import "parts/login.ftl" as l>
<@com.page>
Login page
<@l.login "/login" />
<a href="/registration">Add new user</a>
</@com.page>

View File

@@ -1,16 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Spring Security Example </title>
</head>
<body>
Login page
<form action="/login" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign In"/></div>
<input type="hidden" name="_csrf" value="{{_csrf.token}}" />
</form>
<a href="/registration">Add new user</a>
</body>
</html>

View File

@@ -0,0 +1,36 @@
<#import "parts/common.ftl" as com>
<#import "parts/login.ftl" as l>
<@com.page>
<div>
<@l.logout />
</div>
<div>
<form method="post">
<input type="text" name="text" placeholder="Enter message" />
<input type="text" name="tag" placeholder="tag">
<input type="hidden" name="_csrf" value="${_csrf.token}" />
<button type="submit">Add message</button>
</form>
</div>
<div>
<form method="get" action="/main">
Tag to filer
<br>
<input type="text" name="tag" value="${tag}">
<button>Find</button>
</form>
</div>
<div>Messages list</div>
<#list messages as message>
<div>
<b>${message.id}</b>
<span>${message.text}</span>
<i>${message.tag}</i>
<strong>${message.authorName}</strong>
</div>
<#else>
No messages found
</#list>
</@com.page>

View File

@@ -1,39 +0,0 @@
<html>
<body>
<div>
<form action="/logout" method="post">
<input type="hidden" name="_csrf" value="{{_csrf.token}}" />
<input type="submit" value="Sign Out"/>
</form>
</div>
<div>
<form method="post">
<input type="text" name="text" placeholder="Enter message"> </input>
<input type="text" name="tag" placeholder="tag"></input>
<input type="hidden" name="_csrf" value="{{_csrf.token}}" />
<button type="submit">Add message</button>
</form>
</div>
<div>
<form method="post" action="filter">
Tag to filer
<br>
<input type="text" name="tag">
<input type="hidden" name="_csrf" value="{{_csrf.token}}" />
<button>Find</button>
</form>
</div>
<div>Messages list</div>
{{#messages}}
<div>
<b>{{id}}</b>
<span>{{text}}</span>
<i>{{tag}}</i>
<strong>{{authorName}}</strong>
</div>
{{/messages}}
</body>
</html>

View File

@@ -0,0 +1,14 @@
<#macro page>
<!DOCTYPE HTML>
<html>
<head>
<title>Sweater</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<#nested>
</body>
</html>
</#macro>

View File

@@ -0,0 +1,15 @@
<#macro login path>
<form action="${path}" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign in"/></div>
<input type="hidden" name="_csrf" value="${_csrf.token}" />
</form>
</#macro>
<#macro logout>
<form action="/logout" method="post">
<input type="hidden" name="_csrf" value="${_csrf.token}" />
<input type="submit" value="Sign Out"/>
</form>
</#macro>

View File

@@ -0,0 +1,11 @@
<#import "parts/common.ftl" as com>
<#import "parts/login.ftl" as l>
<@com.page>
Registration page
<br>
<#if message??>
${message}
</#if>
<@l.login "/registration" />
</@com.page>

View File

@@ -1,20 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Spring Security Example </title>
</head>
<body>
Registration page
<br>
{{#message}}
{{message}}
{{/message}}
<form action="/registration" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Add user"/></div>
<input type="hidden" name="_csrf" value="{{_csrf.token}}" />
</form>
</body>
</html>