logoStephen's 기술블로그

포스트 검색

제목, 태그로 포스트를 검색해보세요

#블로그만들기_12 #게시글 쓰기

#블로그만들기_12 #게시글 쓰기
SpringWebApp
성훈 김
2024년 2월 7일
목차

1️⃣ 게시글 쓰기 화면확인

💡
🔹 게시글을 쓸 때 필요한 정보들을 확인 🔹 title, content, button필요!
notion image
 
 

🔹 View 확인

💡
🔹폼 태그가 실행되면 /board/save를 호출한다. 🔹 method는 post요청 🔹 x-www-form-urlencoded 데이터 타입 🔹 button 에 submit확인 → 버튼 내부에 submit은 버튼을 누르면 양식을 전송한다.
notion image
 
 
💡
🔹 DB변경요청이기 때문에 PostMapping으로 어노테이션 설정 🔹 BoardController 내부에 구현
notion image
Java
@PostMapping("/board/save")
public String save () {
		  return "redirect:/"
}
 
 
 

2️⃣ DTO 만들기

💡
🔹 프론트에서 분석하였듯이 필요한 정보는 title, content이다.
Java
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를 클릭
Java
// 테스트 코드
@PostMapping("/board/save")
public String save (BoardRequest.SaveDTO requestDTO) {
			System.out.println(requestDTO); // 콘솔에 내용을 출력
		  return "redirect:/"
}
 
💡
포스트맨을 사용해서 아래와 같이 정보전송
notion image
 
🛠
 
 
💡
테스트 확인 완료
notion image
 
 
 

3️⃣ 유효성 검사

💡
🔹 바디데이터가 있으니까 유효성검사를 해야 DB의 안전성이 높아진다. 🔹 Entity에서 어노테이션으로 유효성 검사 🔹 @Column어노테이션을 활용하면 쉽게 적용할 수 있다. 🔹 @Column(length = 30) 은 제목에 문자열 30자 이상은 허용하지 않겠다는 뜻이다.
notion image
 
 
💡
🔹 비정상적 접근이 존재할 수도 있기 때문에, 유효성 검사는 프론트, 컨트롤러, DTO 모두 적용해주는 것이 데이터의 무결성을 유지할 수 있다. 🔹 컨트롤러에서 유효성 검사 구현, 유효성 검사는 컨트롤러의 주책임이다.
Java
@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:/";
}
 
 

🔹 유효성 검사 테스트

💡
테스트를 해보기 위해서 일부러 넉넉하게 오타를 내본다
notion image
 
 
💡
테스트 확인. 정상작동! 의도된 반응을 얻었다.
notion image
 
 
 

4️⃣ 에러페이지를 동적으로 만들기

💡
🔹 Mustache문법으로 에러페이지를 동적으로 연출할 수 있다. 🔹 아래처럼 에러가 발생시 경로를 error/40x 로 설정하고 40x.mustache 에러메시지 파일을 만든다.
Java
@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파일 하나로 에러메시지를 관리할 수 있다.
HTML
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
<h1>{{msg}}. {{status}}</h1>

</body>
</html>
💡
🔹 테스트 확인 🔹 title길이가 30자를 넘을 수 없다고 구체적으로 에러메시지를 관리할 수 있다.
notion image
 
 

5️⃣ DB에 insert하기

💡
🔹 DB랑 연동하기 위해서는 각 항목을 정확히 일치 시켜야 된다. 🔹 Board 테이블의 값으로 id, title, content, userId, createdAt을 잘 기억하고 BoardRepository로 간다.
notion image
 
 

🔹 BoardController

💡
🔹 아래가 컨트롤러 내부에 /board/save와 연동되는 save메소드 전체 코드이다. 🔹 인증 체크 >> 바디 데이터 확인 및 유효성 검사 >> 핵심 로직코드 🔹 boardRepository.save 코드로 DB와 연동코드 연결, 아까 각 항목을 보면서 만든 쿼리를 잘 기억한다. 해당 메소드 save 단어 위에서 alt + enter를 치면 자동으로 레퍼지토리에 메소드의 틀을 만들어 준다.
Java
@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 로 현 메소드 전체를 최소 작업단위로 만들어, 완료될 때까지 다른 작업이 끼어들지 못하게 한다.
Java
//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요청이 진행된다.
notion image
 
 
💡
글쓰기 테스트 확인 완료.
notion image