5 lab нужно еще делать (CRUD комментов полностью) (у постов удаление, добавление сделать с выбором клиента(с 1 id работает), и чтобы картинки отображались) (сделать вывод как в 4 лабе)

This commit is contained in:
Павел Сорокин 2023-04-21 18:06:43 +04:00
parent cbd7fa1127
commit cf4869f664
11 changed files with 411 additions and 3 deletions

View File

@ -184,3 +184,64 @@ Wrong user name or password [28000-210]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:529)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
... 50 more
2023-04-21 13:55:26 database: wrong user or password; user: "SA"
org.h2.message.DbException: Неверное имя пользователя или пароль
Wrong user name or password [28000-210]
at org.h2.message.DbException.get(DbException.java:227)
at org.h2.message.DbException.get(DbException.java:203)
at org.h2.message.DbException.get(DbException.java:192)
at org.h2.engine.Engine.openSession(Engine.java:154)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.util.JdbcUtils.getConnection(JdbcUtils.java:288)
at org.h2.server.web.WebServer.getConnection(WebServer.java:807)
at org.h2.server.web.WebApp.login(WebApp.java:1033)
at org.h2.server.web.WebApp.process(WebApp.java:226)
at org.h2.server.web.WebApp.processRequest(WebApp.java:176)
at org.h2.server.web.JakartaWebServlet.doGet(JakartaWebServlet.java:129)
at org.h2.server.web.JakartaWebServlet.doPost(JakartaWebServlet.java:166)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
at org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:66)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:859)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1734)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: org.h2.jdbc.JdbcSQLInvalidAuthorizationSpecException: Неверное имя пользователя или пароль
Wrong user name or password [28000-210]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:529)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
... 53 more

View File

@ -5,11 +5,12 @@ import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Comment.model.CommentDto;
import ru.ulstu.is.sbapp.Post.model.PostDto;
import ru.ulstu.is.sbapp.Post.service.PostService;
import ru.ulstu.is.sbapp.WebConfiguration;
import java.util.List;
@RestController
@RequestMapping("/post")
@RequestMapping(WebConfiguration.REST_API + "/post")
public class PostController {
private final PostService postService;
public PostController(PostService postService) {

View File

@ -0,0 +1,102 @@
package ru.ulstu.is.sbapp.Post.controller;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Comment.model.CommentDto;
import ru.ulstu.is.sbapp.Comment.service.CommentService;
import ru.ulstu.is.sbapp.Post.model.PostDto;
import ru.ulstu.is.sbapp.Post.service.PostService;
import ru.ulstu.is.sbapp.User.model.UserDto;
import ru.ulstu.is.sbapp.User.service.UserService;
@Controller
@RequestMapping("/post")
public class PostMvcController {
private final PostService postService;
private final UserService userService;
private final CommentService commentService;
public PostMvcController(PostService postService,UserService userService,CommentService commentService)
{
this.postService = postService;
this.userService = userService;
this.commentService=commentService;
}
@GetMapping("/{id}")
public String getPost(@PathVariable Long id,Model model)
{
model.addAttribute("post",
new PostDto(postService.findPost(id)));
model.addAttribute("users",
userService.findAllUsers().stream()
.map(UserDto::new)
.toList());
model.addAttribute("comments",
postService.GetPostComments(id).stream()
.map(CommentDto::new)
.toList());
return "post-page";
}
@GetMapping
public String getPosts(Model model) {
model.addAttribute("posts",
postService.findAllPosts().stream()
.map(PostDto::new)
.toList());
model.addAttribute("users",
userService.findAllUsers().stream()
.map(UserDto::new)
.toList());
return "post";
}
@GetMapping(value = {"/add/{userId}", "/edit/{id}"})
public String editPost(@PathVariable(required = false) Long id,
@PathVariable(required = false) Long userId,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("userId",userId);
model.addAttribute("postDto", new PostDto());
return "post-create";
} else {
model.addAttribute("postId", id);
model.addAttribute("postDto", new PostDto(postService.findPost(id)));
return "post-edit";
}
}
@PostMapping(value = {"user/{userId}", "/{id}"})
public String savePost(@PathVariable(required = false) Long id,
@PathVariable(required = false) Long userId,
@ModelAttribute @Valid PostDto postDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "post-edit";
}
if (id == null || id <= 0 && userId!=null) {
userService.addNewPost(userId,postDto);
} else {
postService.updatePost(id, postDto);
}
return "redirect:/post";
}
@PostMapping("/delete/{id}/{postId}")
public String deletePost(@PathVariable Long id,
@PathVariable Long postId) {
userService.deletePost(id,postId);
return "redirect:/post";
}
@PostMapping("/deleteComment/{id}/{commentId}")
public String deleteComment(@PathVariable Long id,
@PathVariable Long commentId) {
postService.removeCommentFromPost(id,commentId);
return "redirect:/post";
}
}

View File

@ -14,6 +14,7 @@ public class PostDto {
private String content;
private Long userId;
private List<CommentDto> comments = new ArrayList<>();
private String image;
@ -28,6 +29,7 @@ public class PostDto {
comments = post.getComments().stream()
.map(CommentDto::new).toList();
}
userId=post.getUser().getId();
}
@ -51,4 +53,22 @@ public class PostDto {
public String getImage() {
return image;
}
public void setHeading(String Heading)
{
this.heading=Heading;
}
public void setContent(String content) {
this.content = content;
}
public void setComments(List<CommentDto> comments) {
this.comments = comments;
}
public void setImage(String image) {
this.image = image;
}
}

View File

@ -17,7 +17,7 @@ public class UserMvcController {
this.userService=userService;
}
@GetMapping
public String getUser(Model model) {
public String getUsers(Model model) {
model.addAttribute("users",
userService.findAllUsers().stream()
.map(UserDto::new)

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form>
<div class="mb-3">
<select id="selectBox">
<option th:each="value: ${users}" th:selected="${selectBox} == ${value}">
<span th:text="${value.firstName}"></span>
</option>
</select>
<input className="form-control" id="commentText" type="text" defaultValue="" required/>
<a class="btn btn-outline-primary text-center mx-2">
+
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -28,7 +28,7 @@
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<a class="btn btn-outline-light mx-1" href="/user"> Авторизация </a>
<a class="btn btn-outline-light mx-1" href="/news">Новости</a>
<a class="btn btn-outline-light mx-1" href="/post">Новости</a>
</ul>
</div>
</nav>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/post/user/{userId}(userId=${userId})}" th:object="${postDto}" method="post">
<div class="mb-3">
<label for="image" class="form-label">Картинка</label>
<input type="file" class="form-control" id="image" th:field="${postDto.image}" required="true">
</div>
<div class="mb-3">
<label for="heading" class="form-label">Заголовок</label>
<input type="text" class="form-control" id="heading" th:field="${postDto.heading}" required="true">
</div>
<div class="mb-3">
<label for="content" class="form-label">Содержание</label>
<input type="text" class="form-control" id="content" th:field="${postDto.content}" required="true">
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary button-fixed">
<span th:if="${userId != null}">Добавить</span>
</button>
<a class="btn btn-secondary button-fixed" th:href="@{/post}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/post/{id}(id=${id})}" th:object="${postDto}" method="post">
<div class="mb-3">
<label for="image" class="form-label">Картинка</label>
<input type="file" class="form-control" id="image" th:field="${postDto.image}" required="true">
</div>
<div class="mb-3">
<label for="heading" class="form-label">Заголовок</label>
<input type="text" class="form-control" id="heading" th:field="${postDto.heading}" required="true">
</div>
<div class="mb-3">
<label for="content" class="form-label">Содержание</label>
<input type="text" class="form-control" id="content" th:field="${postDto.content}" required="true">
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary button-fixed">
<span th:if="${id != null}">Обновить</span>
</button>
<a class="btn btn-secondary button-fixed" th:href="@{/post}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div class="da d-flex my-2">
<div><img class="imga img-fluid float-start mx-2" style="width:500px;height:300px" src=${post.image}/></div>
<div class="container-fluid my-2 mx-1">
<h1 th:text="${post.heading}"></h1>
<p>[[${post.content}]]</p>
</div>
</div>
<!--Вот тут кнопка для добавления комментариев (для будущего тебя)-->
<a class="btn btn-outline-primary text-center mx-2">
+
</a>
<div className="d-flex mx-2">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Пользователь</th>
<th scope="col">Содержимое</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="comment, iterator: ${comments}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${comment.user}" style="width: 60%"/>
<td th:text="${comment.text}" style="width: 60%"/>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<!--НУЖНО СДЕЛАТЬ!!!-->
<a class="btn btn-outline-light text-center mx-2">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-outline-light text-center mx-2"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${comment.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/post/deleteComment/{id}(id=${post.id})/{commentId}(commentId=${comment.id}}" method="post">
<button th:id="'remove-' + ${comment.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
<th:block layout:fragment="scripts">
<script>
</script>
</th:block>
</html>

View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div class="d-flex float-start my-1">
<div class="mx-3"><input type="text" id="search" class="form-control" required /></div>
<div class="mx-3">
<select id="selectBox">
<option th:each="value: ${users}" th:selected="${selectBox} == ${value}">
<span th:text="${value.firstName}"></span>
</option>
</select>
</div>
<div>
<a class="btn btn-outline-primary text-center mx-2"
th:href="@{/post/add/{userId}(userId=${6352})}">
<!--Сам понимаешь что здесь надо сделать-->
+
</a>
</div>
</div>
<div class="my-5">
<!--здесь тоже надо сделать нормальный вывод-->
<div class="container-fluid">
<div th:each="post, iterator: ${posts}" class="card border-dark mb-3 d-flex flex-row text-black justify-content-between">
<div>
<img class="col" style="width:300px;height:200px" th:src="${post.image}"/>
</div>
<div class="d-flex flex-grow-1 flex-column">
<div class="flex-grow-1 mx-2">
<h th:text="${post.heading}"></h>
</div>
<div class="flex-grow-1 mx-2">
<p th:text="${post.content}"></p>
</div>
<div class="flex-grow-1 mx-2">
<table class="table"></table>
</div>
<div class="d-flex flex-row justify-content-end ">
<a class="btn btn-outline-primary text-center mx-2"
th:href="@{/post/edit/{id}(id=${post.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button href="#"
class="btn btn-outline-primary mx-3"><i class="fa-sharp fa-solid fa-trash"></i></button>
<a th:href=@{/post/{id}(id=${post.id})} class='btn btn-outline-primary mx-2'><i class="fa-solid fa-envelopes-bulk"></i></a>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<th:block layout:fragment="scripts">
<script>
</script>
</th:block>
</html>