- Реализовал возможность загрузки файлов с клиента в директорию на сервере.
- Настроил доступ к статическим файлам, таким как картинки, стили, и т.д. https://www.youtube.com/watch?v=bmMWrTMB5uo&list=PLU2ftbIeotGpAYRP9Iv2KLIwK36-o_qYk&index=10
This commit is contained in:
@@ -1,13 +1,27 @@
|
|||||||
package net.sytes.kashey.sweater.config;
|
package net.sytes.kashey.sweater.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class MvcConfig implements WebMvcConfigurer {
|
public class MvcConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Value("${upload.path}")
|
||||||
|
private String uploadPath;
|
||||||
|
|
||||||
public void addViewControllers(ViewControllerRegistry registry) {
|
public void addViewControllers(ViewControllerRegistry registry) {
|
||||||
|
|
||||||
registry.addViewController("/login").setViewName("login");
|
registry.addViewController("/login").setViewName("login");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
registry.addResourceHandler("/img/**")
|
||||||
|
.addResourceLocations("file://" + uploadPath + "/");
|
||||||
|
registry.addResourceHandler("/static/**")
|
||||||
|
.addResourceLocations("classpath:/static/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ public class WebSecurityConfig {
|
|||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeHttpRequests((requests) -> requests
|
.authorizeHttpRequests((requests) -> requests
|
||||||
.requestMatchers("/", "/registration").permitAll()
|
.requestMatchers("/", "/registration","/static/**").permitAll()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
)
|
)
|
||||||
.formLogin((form) -> form
|
.formLogin((form) -> form
|
||||||
|
|||||||
@@ -1,27 +1,32 @@
|
|||||||
package net.sytes.kashey.sweater.controller;
|
package net.sytes.kashey.sweater.controller;
|
||||||
|
|
||||||
import net.sytes.kashey.sweater.domain.Message;
|
import net.sytes.kashey.sweater.domain.Message;
|
||||||
import net.sytes.kashey.sweater.domain.User;
|
|
||||||
import net.sytes.kashey.sweater.repository.MessageRepository;
|
import net.sytes.kashey.sweater.repository.MessageRepository;
|
||||||
import net.sytes.kashey.sweater.repository.UserRepository;
|
|
||||||
import net.sytes.kashey.sweater.security.CustomUserDetails;
|
import net.sytes.kashey.sweater.security.CustomUserDetails;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
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.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 org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class MainController {
|
public class MainController {
|
||||||
|
|
||||||
private final MessageRepository messageRepository;
|
private final MessageRepository messageRepository;
|
||||||
private final UserRepository userRepository;
|
|
||||||
|
|
||||||
public MainController(MessageRepository messageRepository, UserRepository userRepository) {
|
@Value("${upload.path}")
|
||||||
|
private String uploadPath;
|
||||||
|
|
||||||
|
public MainController(MessageRepository messageRepository) {
|
||||||
this.messageRepository = messageRepository;
|
this.messageRepository = messageRepository;
|
||||||
this.userRepository = userRepository;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
@@ -42,18 +47,28 @@ public class MainController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/main")
|
@PostMapping("/main")
|
||||||
public String addMessage(@AuthenticationPrincipal CustomUserDetails details,
|
public String addMessage(@AuthenticationPrincipal CustomUserDetails customUserDetails,
|
||||||
@RequestParam String text,
|
@RequestParam String text,
|
||||||
@RequestParam String tag,
|
@RequestParam String tag,
|
||||||
Model model) {
|
@RequestParam("file") MultipartFile file,
|
||||||
|
Model model) throws IOException {
|
||||||
|
|
||||||
User author = userRepository.findByUsername(details.getUsername())
|
Message newMessage = new Message(text, tag, customUserDetails.getUser());
|
||||||
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + details.getUsername()));
|
|
||||||
|
|
||||||
messageRepository.save(new Message(text, tag, author));
|
if (file != null && !Objects.requireNonNull(file.getOriginalFilename()).isEmpty()) {
|
||||||
|
File uploadDir = new File(uploadPath); // Директория на сервере, куда помещаем пришедший файл
|
||||||
|
if (!uploadDir.exists()) {
|
||||||
|
uploadDir.mkdirs();
|
||||||
|
}
|
||||||
|
String uuidFile = UUID.randomUUID().toString();
|
||||||
|
String resultFilename = uuidFile + "." + file.getOriginalFilename(); // случайный уид + имя файла с клиента
|
||||||
|
file.transferTo(new File(uploadPath + "/" + resultFilename)); // помещаем переименованный файл с клиента в директорию сервера
|
||||||
|
newMessage.setFilename(resultFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
messageRepository.save(newMessage);
|
||||||
model.addAttribute("messages", messageRepository.findAll());
|
model.addAttribute("messages", messageRepository.findAll());
|
||||||
model.addAttribute("tag", "");
|
model.addAttribute("tag", "");
|
||||||
return "main";
|
return "main";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,8 @@ public class Message {
|
|||||||
private String text;
|
private String text;
|
||||||
private String tag;
|
private String tag;
|
||||||
|
|
||||||
|
private String filename;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.EAGER)
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
@JoinColumn(name = "user_id")
|
@JoinColumn(name = "user_id")
|
||||||
private User author;
|
private User author;
|
||||||
@@ -58,4 +60,12 @@ public class Message {
|
|||||||
public String getAuthorName() {
|
public String getAuthorName() {
|
||||||
return author == null ? "<none>" : author.getUsername();
|
return author == null ? "<none>" : author.getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getFilename() {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilename(String filename) {
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,4 +52,8 @@ public class CustomUserDetails implements UserDetails {
|
|||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return user.isEnabled();
|
return user.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,3 +5,5 @@ 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.freemarker.expose-request-attributes=true
|
spring.freemarker.expose-request-attributes=true
|
||||||
spring.freemarker.suffix=.ftl
|
spring.freemarker.suffix=.ftl
|
||||||
|
upload.path=/home/kashey/soft/sweater/uploads
|
||||||
|
|
||||||
|
|||||||
3
src/main/resources/static/style.css
Normal file
3
src/main/resources/static/style.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
body {
|
||||||
|
color: #191970;
|
||||||
|
}
|
||||||
@@ -7,9 +7,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<form method="post">
|
<form method="post" enctype="multipart/form-data">
|
||||||
<input type="text" name="text" placeholder="Enter message" />
|
<input type="text" name="text" placeholder="Enter message" />
|
||||||
<input type="text" name="tag" placeholder="tag">
|
<input type="text" name="tag" placeholder="tag">
|
||||||
|
<input type="file" name="file">
|
||||||
<input type="hidden" name="_csrf" value="${_csrf.token}" />
|
<input type="hidden" name="_csrf" value="${_csrf.token}" />
|
||||||
<button type="submit">Add message</button>
|
<button type="submit">Add message</button>
|
||||||
</form>
|
</form>
|
||||||
@@ -30,6 +31,11 @@
|
|||||||
<span>${message.text}</span>
|
<span>${message.text}</span>
|
||||||
<i>${message.tag}</i>
|
<i>${message.tag}</i>
|
||||||
<strong>${message.authorName}</strong>
|
<strong>${message.authorName}</strong>
|
||||||
|
<div>
|
||||||
|
<#if message.filename??>
|
||||||
|
<img src="/img/${message.filename}">
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<#else>
|
<#else>
|
||||||
No messages found
|
No messages found
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Sweater</title>
|
<title>Sweater</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<link href="/static/style.css" rel="stylesheet" type="text/css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user