What to do?
게시글 작성
게시글 작성 기능 및 뷰 구현하기
구현내용
- 네비게이션 바에 Write 버튼을 누르면 게시글 작성 페이지로 이동
- 제출하면 게시판 페이지로 redirection되며, 방금 작성한 게시물이 보임
Security Config
게시글 쓰기를 하는 경우 /articles/write 경로로 post요청을 보내도록 하기 때문에, 테스트를 할 수 없었다.
인증기능을 완전히 구현하기 전까지는 다음과 같이 모든 요청을 허용하도록 바꾸었다.
@Bean
public SecurityFilterChain securityFilterChain(
HttpSecurity http
) throws Exception {
http.csrf().disable();
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.anyRequest()
.permitAll()
)
.formLogin(withDefaults())
.logout(logout -> logout.logoutSuccessUrl("/"))
.build();
// TODO : 테스트를 위해 임시로 주석처리
// return http
// .authorizeHttpRequests(auth -> auth
// .requestMatchers(PathRequest.toStaticResources().atCommonLocations())
// .permitAll()
// .mvcMatchers(
// HttpMethod.GET,
// "/",
// "/articles",
// "/articles/**", // TODO : 제거 (테스트를 위해 열어놓음)ㄴ
// "/articles/search-hashtag")
// .permitAll()
// .anyRequest()
// .authenticated()
// )
// .formLogin(withDefaults())
// .logout(logout -> logout.logoutSuccessUrl("/"))
// .build();
}
Security Config에서 모든 요청을 허용하도록 수정하였는데, 403 에러가 발생했다.
이는 http.csrf().disable() 를 넣어주면 해결된다.
Request
- Parameter : 제목, 본문, 해쉬태그
- 생성자는 private로, protected 명령어 사용, of 메써드 작성 → 외부에서 of method로만 생성 가능
- to 메써드 : Request → Entity
@Data
public class WriteArticleRequest {
private String title;
private String content;
private String hashtags;
private WriteArticleRequest(String title, String content, String hashtags) {
this.title = title;
this.content = content;
this.hashtags = hashtags;
}
protected WriteArticleRequest(){}
public static WriteArticleRequest of(String title, String content, String hashtags){
return new WriteArticleRequest(title, content, hashtags);
}
// Request → Entity
public static Article to(WriteArticleRequest writeArticleRequest){
return Article.of(
writeArticleRequest.getTitle(),
writeArticleRequest.getContent(),
writeArticleRequest.getHashtags()
);
}
}
Service
ArticleService.java
- 이전에 작성했던 코드와 동일
public ArticleDto saveArticle(Article article) {
Article savedArticle = articleRepository.save(article);
return ArticleDto.from(savedArticle);
}
Controller
ArticleController.java
- articles/write로 GET요청 → resources/articles/write/index.html 렌더링
- articles/write로 POST요청 → 게시글 저장
@PostMapping("/write")
public String saveArticle(WriteArticleRequest req){
Article article = WriteArticleRequest.to(req);
articleService.saveArticle(article);
return "redirect:/articles";
}
HTML
resources/articles/write/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Write</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
</head>
<body>
<header id="header"/>
<div class="container mt-3">
<form id="write-article-form" method="post" action="/articles/write">
<div class="row mt-3 mb-3 align-items-center">
<div class="col"><h1>Write Article</h1></div>
<!--Submit-->
<div class="col">
<button id="btn-download" type="submit" class="btn btn-success" style="float:right;">Submit</button>
</div>
</div>
<hr/>
<!--Title-->
<div class="row mt-3 mb-3">
<div class="col-md-1">
<span class="input-group-text">Title</span>
</div>
<div class="col">
<input id="title" name="title" type="text" class="form-control" placeholder="Title..."/>
</div>
</div>
<!--Content-->
<div class="row mt-3 mb-3">
<div class="col-md-1">
<span class="input-group-text">Content</span>
</div>
<div class="col">
<textarea class="form-control" id="content" name="content"
placeholder="Content..." rows="15" style="resize:none;"></textarea>
</div>
</div>
<!--Hashtag-->
<div class="row mt-3 mb-3">
<div class="col-md-1">
<span class="input-group-text">Hashtag</span>
</div>
<div class="col">
<input id="hashtags" name="hashtags" type="text" class="form-control" placeholder="#hashtag"/>
</div>
</div>
</form>
</div>
<footer id="footer"/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</body>
</html>
Thymeleaf Template
resources/articles/write/index.th.xml
- 헤더와 풋터만 가져오는 것 외에 다른 설정은 안했다.
<?xml version="1.0"?>
<thlogic xmlns:th="http://www.thymeleaf.org">
<!--Header&Footer-->
<attr sel="#header" th:replace="header :: #header"/>
<attr sel="#footer" th:replace="footer :: #footer"/>
</thlogic>
'Java > Spring' 카테고리의 다른 글
[Spring] 게시판 만들기 #12 (0) | 2022.11.26 |
---|---|
[Spring] 게시판 만들기 #11 (0) | 2022.11.24 |
[Spring] 게시판 만들기 #9 (0) | 2022.11.23 |
[Spring] 게시판 만들기 #8 (0) | 2022.11.23 |
[Spring] 게시판 만들기 #7 (0) | 2022.11.22 |