소설 제목과 내용을 form에 넣고 등록해서 db에 저장하는 기능을 구현했다. 이것저것 추가한 것도 있지만, 대부분 간단한 html이거나 아직 작성하지 않은 구현들이라 크게 Novel만 보려고 한다.
소설의 폼 객체이다. 소설에는 사실 여러 속성이 더 있지만, 일단 간단한 구현을 위해서 제목과 소개만 넣어줬다. 사실 장르도 넣고 싶었는데 이건 라디오 형식으로 구현하고 싶어서 일단 놔뒀다. 아마 내일 구현할 예정이다.
package web.novelPlatform.controller;
import lombok.Getter;
import lombok.Setter;
import web.novelPlatform.entity.Genre;
import javax.validation.constraints.NotEmpty;
@Getter
@Setter
public class NovelForm {
@NotEmpty(message = "제목은 필수입니다.")
private String title;
private String introduce;
}
소설 form을 등록할 때 이용하는 컨트롤러이다. 일단 form 화면을 열어봐야 하기 때문에 GetMapping으로 붙여주었다. 그리고 model에다가 빈 NovelForm을 넣어줬다. 그리고 실제 화면이 있는 html로 가도록 "novel/createNovelFrom"을 리턴했다.
@GetMapping(value = "/novels/new") //get은 form화면을 열어보고
public String createForm(Model model){
model.addAttribute("novelForm", new NovelForm());
return "novels/createNovelForm";
}
소설의 form을 받고 이걸 등록하려면 어떻게 해야 할까. 일단 어노테이션을 GetMapping이 아닌 PostMapping으로 해줘야 한다. 주소는 같지만, 실제로는 post이므로 데이터를 넣어주는데 사용한다. 그리고 NovelForm을 파라미터로 받아준 후 그 값을 일일히 넣어준다. 그리고 novelService에 있는 createNovel에다가 값을 넣어준 novel을 전달해 등록해주면된다.
아! 그리고 반환 값은 첫 페이지인 "redirect:/"로 해준다. 어제 배운 3xx번대 HTTP 상태코드가 생각난다.
@PostMapping("/novels/new") //데이터를 실제 등록
//NovelForm이 넘어온다.
//참고 꼭 넣어야 하는 게 있다면 form에다가 @Valid를 붙여준다.
public String create(NovelForm form){
Novel novel = new Novel();
novel.setTitle(form.getTitle());
novel.setIntroduce(form.getIntroduce());
novelService.createNovel(novel);
return "redirect:/";
}
소설의 form을 받는 html이다.
form 테그를 이용해서 action = "/novel/new"로 컨트롤러에 있는 novel/new로 가게 했다. 그리고 object는 novelFrom으로 컨트롤러에서 받았던 빈 객체 NovelForm()을 novelForm으로 들고 온다. 그리고 메소드는 post로 둔다.
제목과 내용을 적는데, for과 field는 각각 변수 명으로 맞춰준다. 그리고 밑에 submit 버튼을 만들어 준다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang = "ko">
<head>
<meta charset="UTF-8">
<title>웹소설 연재 페이지</title>
</head>
<body>
<form role="form" action="/novels/new" th:object="${novelForm}" method="post">
<div>
<label th:for="title">제목 : </label>
<input type="text" th:field="*{title}" placeholder="제목을 입력하세요"/>
</div>
<div>
<label th:for="introduce">내용 : </label>
<input type="text" th:field="*{introduce}" placeholder="내용을 입력하세요"/>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</body>
</html>
참고로 해당 프로젝트의 기반으로 하고 있는 김영한 님의 강의 html은 내가 알아보기가 좀 어려워서 새로운 티스토리를 찾았다. thymleaf를 이용한 html은 이곳에서 많은 도움을 받고 있다.
https://chb2005.tistory.com/82
저번에 실행했을 때 성공한 그대로 돌리려 하니 오류가 났다. 솔직히 당황했던 게 해결 책들이 html과 컨트롤러가 연결이 되지 않았기 때문이라며 반환값이나 GetMapping 등에서 값을 잘 보라고 했던 것이다. 하지만, 난 잘못 쓴 게 없는데?
그래서 문장을 찬찬히 읽어보니 [header/fragement]에서 답을 얻었다. 처음에 thymleaf로 html을 만들 때 김영한님의 강의의 html을 복붙을 했다. 그러니까 난 header에 fragement를 만들어 준 적이 없는데 그냥 복붙으로 해당 문장이 들어가 있으니까 오류가 난 것이었다. fragement 부분을 지워주니 문제가 해결이 됐다.
갑작스럽게 기본 키 오류 중복이 났다. 나는 분명 Novel의 id를 Generate로 자동으로 만들어 주라고 했는데..? 그래서 구글링을 해보니 역시 답은 stackoverflow에 있었다. 자동으로 증가하는 기능을 넣는 방식이다.
@GeneratedValue(strategy=GenerationType.AUTO)
이렇게 바꿔주니 해결이 됐다. id도 자동으로 올라감!