1️⃣ 게시글 쓰기 화면확인
🔹 게시글을 쓸 때 필요한 정보들을 확인
🔹 
title, content, button필요!
🔹 View 확인
🔹폼 태그가 실행되면 
/board/save를 호출한다.
🔹 method는 post요청
🔹 x-www-form-urlencoded 데이터 타입
🔹 button 에 submit확인 → 버튼 내부에 submit은 버튼을 누르면 양식을 전송한다.

🔹 DB변경요청이기 때문에  
PostMapping으로 어노테이션 설정
🔹 BoardController 내부에 구현
@PostMapping("/board/save")
public String save () {
		  return "redirect:/"
}2️⃣ DTO 만들기
🔹 프론트에서 분석하였듯이 필요한 정보는 
title, content이다. package shop.mtcoding.blog.board;
import lombok.Data;
public class BoardRequest {
    @Data
    public static class SaveDTO {
        private String title;
        private String content;
    }
}🔹 save (requestDTO) 테스트 확인
🔹 Post요청은 브라우저에서는 안되기 때문에 Postman 설치해서 테스트 해야된다. 
🔹 URL과 식별자 (/board/save)를 넣고,
🔹 
title, content값에 더미 값을 넣고 (asdf, asdf)
🔹 제일 왼쪽 ‘Post’를 확인한 뒤 send를 클릭// 테스트 코드
@PostMapping("/board/save")
public String save (BoardRequest.SaveDTO requestDTO) {
			System.out.println(requestDTO); // 콘솔에 내용을 출력
		  return "redirect:/"
}포스트맨을 사용해서 아래와 같이 정보전송

Postman 설치와 간단 사용방법은 클릭 👇
테스트 확인 완료

3️⃣ 유효성 검사
🔹 바디데이터가 있으니까 유효성검사를 해야 DB의 안전성이 높아진다.
🔹 
Entity에서 어노테이션으로 유효성 검사
🔹 @Column어노테이션을 활용하면 쉽게 적용할 수 있다.
🔹 @Column(length = 30) 은 제목에 문자열 30자 이상은 허용하지 않겠다는 뜻이다. 
🔹 비정상적 접근이 존재할 수도 있기 때문에, 유효성 검사는 프론트, 컨트롤러, DTO 모두 적용해주는 것이 데이터의 무결성을 유지할 수 있다. 
🔹 컨트롤러에서 유효성 검사 구현, 유효성 검사는 컨트롤러의 주책임이다.
@PostMapping("/board/save")
public String save(BoardRequest.SaveDTO requestDTO){
    System.out.println(requestDTO);
		//제목 30자 이상 제한
    if(requestDTO.getTitle().length() > 30){
        return "error/400"; // BadRequest
    }
    return "redirect:/";
}🔹 유효성 검사 테스트
테스트를 해보기 위해서 일부러 넉넉하게 오타를 내본다

테스트 확인. 정상작동! 의도된 반응을 얻었다.

4️⃣ 에러페이지를 동적으로 만들기
🔹 Mustache문법으로 에러페이지를 동적으로 연출할 수 있다. 
🔹 아래처럼 에러가 발생시 경로를 
error/40x 로 설정하고 40x.mustache 에러메시지 파일을 만든다.@PostMapping("/board/save")
public String save(BoardRequest.SaveDTO requestDTO, HttpServletRequest request){
    System.out.println(requestDTO);
    if(requestDTO.getTitle().length() > 30){
        request.setAttribute("status", 400);
        request.setAttribute("msg", "title의 길이가 30자를 초과해서는 안되요");
        return "error/40x"; // BadRequest
    }
    return "redirect:/";
}🔹 
40x.mustache 파일을 error폴더 내부에 생성한다.
🔹 위에서 request.setAttribute로 설정을 키값과 Object (”키값”, Object)로 할당할 수 있다.
🔹 위 처럼 설정한 키값을 mustache에 중괄호 두개{{ }}문법으로 사용하면 object가 매핑이 되어서 전달 된다. 
🔹 이로 인해 각 에러마다 페이지를 만들 필요가 없이 request.setAttribute를 잘 사용하면 40x파일 하나로 에러메시지를 관리할 수 있다. <!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
<h1>{{msg}}. {{status}}</h1>
</body>
</html>🔹 테스트 확인
🔹 title길이가 30자를 넘을 수 없다고 구체적으로 에러메시지를 관리할 수 있다.

5️⃣ DB에 insert하기
🔹 DB랑 연동하기 위해서는 각 항목을 정확히 일치 시켜야 된다. 
🔹 Board 테이블의 값으로 
id, title, content, userId, createdAt을 잘 기억하고 BoardRepository로 간다.
🔹 BoardController
🔹 아래가 컨트롤러 내부에 
/board/save와 연동되는 save메소드 전체 코드이다.
🔹 인증 체크 >> 바디 데이터 확인 및 유효성 검사 >> 핵심 로직코드
🔹 boardRepository.save 코드로 DB와 연동코드 연결, 아까 각 항목을 보면서 만든 쿼리를 잘 기억한다. 해당 메소드 save 단어 위에서 alt + enter를 치면 자동으로 레퍼지토리에 메소드의 틀을 만들어 준다. @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. 바디 데이터 확인 및 유효성 검사
    if (requestDTO.getTitle().length() > 30){
        request.setAttribute("status", 400);
        request.setAttribute("msg", "title의 길이가 30자를 초과해서는 안되요");
        return "error/40x"; // 잘못된 요청
    }
    //3. 모델 위임
    //insert into board_tb(title, content, user_id, created_at) values (?, ?, ?, now());
    boardRepository.save(requestDTO, sessionUser.getId());
    return "redirect:/";
}🔹 BoardRepository
🔹 BoardRepository 내부에 아래 코드를 구현한다.
🔹 DB를 변경하는 메소드는 
@Transactional 어노테이션을 붙여준다.
🔹 @Transactional 로 현 메소드 전체를 최소 작업단위로 만들어, 완료될 때까지 다른 작업이 끼어들지 못하게 한다.//DB를 변경하는 메소드는 항상 @Transactional을 붙여줘야 된다.
@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();
}🔹 최종 테스트
🔹 Postman을 켜고 프로그램 안에서 
localhost:8080/login 으로 들어가서 로그인 한다.
🔹 현재 테스트 중인 localhost:8080/board/save 을 주소창에 넣고 Post 요청으로 설정한다.
🔹 그리고 한 칸 아래줄에 Body 로 선택
🔹 Mime타입은 x-www-from-urlencoded 으로 선택
🔹 key 값에는 제목 777
🔹 content값에는 내용 777
🔹 그리고 나서 send를 클릭해야 정상적 post요청이 진행된다.

글쓰기 테스트 확인 완료.




