1-3 네트워크 통신의 이해(Request, Model, Session)

Request, Model, Session
홍윤's avatar
Aug 19, 2024
1-3 네트워크 통신의 이해(Request, Model, Session)
 

1. 게시판 Request, Model, Session 연습 및 해설

BoardController (Request 이용)

 
// get, post //Model model Request 객체이다. @GetMapping("/board") public String list(HttpServletRequest request) { //view에 데이터를 전달 한 게 아니라 request 객체에서 보관되어있다가 musatche에서 찾아낸거다. List<Board> boardList = boardRepository.findAll(); request.setAttribute("models", boardList); //session //HttpSession session = request.getSession(); //session.setAttribute("num", 1); return "board/list"; }
  • 게시판 목록을 데이터베스에서 조회하여 ‘boardList’ 라는 리스트를 만든다.
  • 리스트를 ‘request’ 객체에 ‘models’라는 이름으로 저장한다.
  • (주석 처리된) 코드로 session을 사용하여 데이터를 저장 할 수 있지만, 현재는 사용하지 않음.
  • view 이름으로 ‘board/list’ 를 반환하여, 해당 뷰 파일(’board/list.jsp’)을 렌더링한다.

 

list.mustache

 
{{#models}} <div class="card mb-3"> <div class="card-body"> <h4 class="card-title mb-3">{{title}}</h4> <a href="/board/{{id}}" class="btn btn-primary">상세보기</a> </div> </div> {{/models}}
💡
Handlebars/Mustache:
  • 사용한 문법이 {{#models}}로 데이터 반복을 처리합니다.
  • ’{{#models}}’와 ‘{{models}}’는 ‘models’ 리스트의 각 항목을 반복하여 출력한다.
  • 각 항목의 ‘title’ 과 ‘id’를 사용하여 카드 형태로 표시하며, 상세보기 링크를 생성한다.
 

 

3. Spring Framework의 애플리케이션 구성(application.properties)

  • 더미 데이터 생성하기!
notion image
insert into board_tb(title, content, created_at) values ('제목1', '내용1', now()); insert into board_tb(title, content, created_at) values ('제목2', '내용2', now()); insert into board_tb(title, content, created_at) values ('제목3', '내용3', now()); insert into board_tb(title, content, created_at) values ('제목4', '내용4', now()); insert into board_tb(title, content, created_at) values ('제목5', '내용5', now());
# 4. Dummy spring.sql.init.data-locations=classpath:db/data.sql # 5. Mustache Setting spring.mustache.servlet.expose-request-attributes=true spring.mustache.servlet.expose-session-attributes=true
  • 데이터베이스 초기화: ‘spring.sql.init.data-locations’ 설정을 통해 애플리케이션 시작 시 특정 SQL 파일을 실행하여 데이터베이스를 초기화 한다.
  • Mustache 설정: ‘spring.mustache.servlet.expose-request-attributes’는 요청 속성을 Mustache 템플릿에서 사용 가능하게 한다.
  • ’spring.mustache.servlet.expose-session-attributes’는 세션 속성을 Mustache 템플릿에서 사용 가능하게 한다.
 

4. 상세보기 만들기

 

BoardController

// 1. 메서드 : Get // 2. 주소 : /board/1 // 3. 응답 : board/detail @GetMapping("/board/{id}") public String detail(@PathVariable("id") Integer id, HttpServletRequest request) { Board board = boardRepository.findById(id); request.setAttribute("model", board); return "board/detail"; }
 
  • 경로 변수 추출: ‘@GetMapping(”board/{id}”)’ 과 ‘@Pathvariable(”id”)’을 사용해 URL의 ‘id’ 값을 추출한다.
  • 데이터 조회: ‘boardRepository.findById(id)’를 사용해 데이터베이스에서 해당 ‘id’의 게시글을 조회한다.
  • 데이터 전달: 조회한 ‘board’ 객체를 ‘request.settAttribute(”model”, board) ‘ 로 ‘request’ 객체에 저장해서 뷰에 접근 가능하게 한다.
  • 뷰 렌더링: ‘return “board/detail”; ‘ 을 통해 ‘board/detail’ 뷰를 반환하여 템플릿이 클라이언트에게 렌더딩됩니다.
 

 

detail.mustache

<div class="d-flex justify-content-end"> <a href="/board/{{model.id}}/update-form" class="btn btn-warning me-1">수정</a> <!-- post를 쓰는 이유는 ajax,자바스크립트를 사용 하지 않고 기초적인 CRUD를 하기 위해 주소 설계 규칙 찾아보기 post로 쓰기,삭제,수정을 하기 위해 동사를 쓰지 않고 post를 쓴다. --> <form action="/board/{{model.id}}/delete" method="post"> <button class="btn btn-danger">삭제</button> </form> </div> <div class="d-flex justify-content-end"> <b>작성자</b> : 익명 </div> <!-- 게시글내용 --> <div> <h2><b>{{model.title}}</b></h2> <hr/> <div class="m-4 p-2"> {{model.content}} </div> </div> </div>
 
  • ‘{{model.title}}’: 서버에서 전달된 ‘model’ 객체의 ‘title’ 속성 값을 HTML에 출력합니다.
  • 템플릿 엔진: Mustache를 사용하여 동적이 콘턴체를 생성한다.
  • 사용위치: 이와 같은 표현은 ‘{{model.title}}’, ‘{{model.content}}’ 등 다양한 데이토 속성에 사용되고, 템플릿에서 서버 데이터를 쉽게 표시할 수 있게 해준다.!
 

 

BoardRepository

//Board class 자동으로 오브젝트 맵핑을 해준다. public Board findById(int id){ Query query = em.createNativeQuery("select * from board_tb where id=?", Board.class); query.setParameter(1, id); try { Board board = (Board) query.getSingleResult(); return board; } catch (Exception e) { //내가 예외를 설정 할 수 있다. 익세션을 내가 잡은것 까지 배움 - 처리 방법은 v2에서 배우기 //자기가 처리 하기 싫으면 throw로 넘길 수 있다. throw new RuntimeException("게시글 아이디를 찾을 수 없습니다."); } }
 
  • 네이티브 SQL 쿼리를 사용해 ‘board_tb’ 테이블에서 주어진 ‘id’에 해당하는 레코드를 조회하며, 조회된 결과는 ‘Board’ 클래스의 인스턴스로 자동 매핑된다.
  • 조회 과정에서 예외가 발생한다면, 사용자에게 “게시글을 찾을 수 없습니다.라는 메세질르 포함한 ‘RuntimeException’이 던져진다.
 

BoardRepositoryTest

@Test public void findById_test() { //given (가짜로 id를 만들어본다.) int id = 110; //when Board board = boardRepository.findById(id); //eye (잘 하지 못 해서 눈으로 확인 했습니다.) System.out.println(board.getTitle()); System.out.println(board.getContent()); System.out.println(board.getContent()); } }
  • 테스트의 목적은 ‘findById’ 메소드가 특정 ‘id’를 통해 ‘board’ 객체를 올바르게 조회하는지 확인 하기 위해 작성
  • Given(가짜 id를 만들어본다): 테스트할 가상의 ‘id’ 값(110)으로 설정
  • When: ‘findById(id) 메소드를 호출해서 해당 ‘id’에 해당하는 ‘board’ 객체를 조회한다.
  • Eye: 조회된 ‘Board’ 객체의 제목(’title’)과 내용(’content’)을 콘솔에 출력하여 수동으로 결과를 확인 할 수 있다.
Share article

Uni