
제목 폼 데이터, 내용 폼 데이터를 클라이언트에게 받아서 submit 해서 날릴거다. 이 화면을 봤을 때, PostMapping, x-form 타입이란 걸 알 수 있다
1. saveForm.mustache
처음엔 view에 가서 체크를 하자! 화면이 완벽한지 확인하고 가자!

boardController에... PostMapping을 /board/save로 받는 save 메소드가 있나? 없다!!!! 만들어 주자
[ BoardController ]

다 만들어줬으면 DTO 만들어서 BODY 데이터 받자
[ BoardRequest 클래스 생성 ]

아까 메서드 이름이 save 였으니까 SaveDTO로 만들어준다
package shop.mtcoding.blog.board; import lombok.Data; public class BoardRequest { @Data public static class SaveDTO { private String title; private String content; } }
[ Http Body 데이터 받기 테스트 ]

BoardController 에서 save 메소드에 DTO를 request 로 받는다
3. 유효성 검사
[ Board ]

[ BoardController ]

만약, 회사에서 일하는데 30 글자 이상이 들어왔다?
그럼 postman 같은 걸로 우회해서 지속적으로 요청하는 거니까…
우리에 대한 공격으로 간주하고 ip 블락하면 된다
[ 글쓰기 유효성 검사 테스트 ]

제목을 한 100자 정도로 넣어봤다.

에러 페이지 뜸
5. 에러 페이지를 동적페이지로 만들기

[ 40x.mustache ]
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h1>{{msg}} : {{status}}</h1> </body> </html>
가방에 넣었다가 꺼내쓰게 request를 매개변수로 받아줬다.

내가 메세지랑 상태코드만 담으면
String 오브젝트로 만들어진 해쉬맵?

error/40x 페이지가 뜬다
지금까지 검증해오면서 코드를 짰으면, 앞으로 오류가 나면 이후에 코드짠게 잘못된 거란걸 바로 알 수 있다.
꼭 검증하면서 코드를 짜자
6. DB insert 하기

title, content는 클라이언트로부터 (DTO) 받기 userId 는 세션에서 가져온다. **세션의 user객체의 아이디**를 들고 와야 한다 createAt 자동생성
순서
1. 인증체크 : 인증이 안되어있으면 바로 내보내야함.
→ 처음에 세션에 접근해야함. 그 이후로 null인지 null 아닌지

2. 바디 데이터 확인 및 유효성 검사

3. 모델 위임

BoardRepository에 save 메소드 만들어주자 alt + enter
[ BoardController ]
@PostMapping("/board/save") public String save(BoardRequest.SaveDTO requestDTO, HttpServletRequest request) { // 1. 인증 체크 User sessionUser = (User) session.getAttribute("sessionUser"); if (sessionUser == null) { return "redirect:/loginForm"; } // 2. 바디 데이터 확인 및 유효성 검사 System.out.println(requestDTO); if (requestDTO.getTitle().length() > 30) { request.setAttribute("status", 400); request.setAttribute("msg", "title의 길이가 30자를 초과해서는 안되요"); return "error/40x"; // BadRequest } // 3. 모델 위임 // insert into board_tb(title, content, user_id, created_at) values(?,?,?, now()); boardRepository.save(requestDTO, sessionUser.getId()); return "redirect:/"; }
[ BoardRepository ]
@Transactional public void save(BoardRequest.SaveDTO requestDTO, int userId) { Query query = em.createNativeQuery("insert into board_tb(title, content, user_id, created_at) values(?,?,?, now())"); query.setParameter(1, requestDTO.getTitle()); query.setParameter(2, requestDTO.getContent()); query.setParameter(3, userId); query.executeUpdate(); }
write하는 건 무조건 @Transactional을 걸어주자. 고립에 걸리니까!
user_id는 게시글을 작성한 사용자의 ID를 나타내며, 현재 로그인한 사용자의 ID를 전달받아서 저장한다. 이렇게 하면 게시글 작성자의 ID를 게시글과 함께 저장할 수 있다. 그래서 user_id를 받는 것!
7. 게시글 쓰기 최종 테스트
1. 로그인 없이 게시글 쓰기 테스트

[ 로그인 함 ]

세션키 나왔죠?


정상 작동!
[ NullPointException ]

만약, title을 안 쓰면 유효성 검사 통과가 안돼서 NullPointException이 뜬다
Share article