AJAX : 게시글 작성하기

Feb 22, 2024
AJAX : 게시글 작성하기

1. saveForm.mustache에서 하기

  • 프론트와 같이 협업을 할 때, 주도권은 백엔드한테 있음
  • 데이터타입 json이면 form태그 못 씀
x-www-form-urlencoded로 바꿔 달라고 해야 함
  • form태그는 발동을 안하니 껍데기 상태
껍데기는 놔둬도 됨, submit이 필요 없음
 
  • name → id로 변경하기
  • id로 찾아서 데이터 꺼내기
{{> layout/header}} <div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글쓰기 화면입니다</b></div> <div class="card-body"> <form action="#"> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content"></textarea> </div> <button type="submit" class="btn btn-primary form-control">글쓰기완료</button> </form> </div> </div> </div> {{> layout/footer}}
  • onclick해서 button 클릭해서 btnWrite() 실행 확인하기
  • 되는지 확인하고 코드 짜야 함!
{{> layout/header}} <div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글쓰기 화면입니다</b></div> <div class="card-body"> <form action="#"> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content"></textarea> </div> <button onclick="btnWrite()" class="btn btn-primary form-control">글쓰기완료</button> </form> </div> </div> </div> <script> function btnWrite(){ alert("클릭되나?") // 되는지 확인하고 코드 짜야 함! } </script> {{> layout/footer}}
  • form 태그안에 있는 button의 디폴트 값이 submit
onclick을 해도 submit이 발동됨
notion image
notion image
  • form태그를 지우던지 type=”button”추가하기
{{> layout/header}} <div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글쓰기 화면입니다</b></div> <div class="card-body"> <form action="#"> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content"></textarea> </div> <button type="button" onclick="btnWrite()" class="btn btn-primary form-control">글쓰기완료</button> </form> </div> </div> </div> <script> function btnWrite(){ alert("클릭되나?") // 되는지 확인하고 코드 짜야 함! } </script> {{> layout/footer}}
notion image
notion image
 

2. json으로 받을 DTO 만들기

package shop.mtcoding.blog.board; import lombok.Data; public class BoardRequest { @Data public static class WriteDTO{ // json으로 받을 DTO private String title; private String content; private String author; } }
 

3. json으로 전송할 서버(write) 만들기

package shop.mtcoding.blog.board; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.List; @RequiredArgsConstructor @RestController // 데이러틀 리턴 public class BoardApiController { private final BoardRepository boardRepository; // DI @PostMapping("/api/boards") public ApiUtil<?> write(@RequestBody BoardRequest.WriteDTO requestDTO){ boardRepository.insert(requestDTO); return new ApiUtil<>(null); } // 삭제하기 @DeleteMapping("api/boards/{id}") // 보드 중에 몇번을 삭제할게 public ApiUtil<?> deleteById(@PathVariable Integer id, HttpServletResponse response) { Board board = boardRepository.selectOne(id); if (board == null) { response.setStatus(404); return new ApiUtil<>(404, "해당 데이터를 찾을 수 없습니다"); } boardRepository.deleteById(id); return new ApiUtil<>(null); // 삭제는 데이터를 줄 것이 없음 } // 주소 만들기 @GetMapping("api/boards") // 보드 줘라는 주소, 복수는 보드들 줘, 보드들 중에 1번 줘해서 복수형을 씀 public ApiUtil<List<Board>> findAll(HttpServletResponse response) { //response.setStatus(401); List<Board> boardList = boardRepository.selectAll(); // 상태코드랑 메세지랑 같이 줘야함 return new ApiUtil<>(boardList); // MessageConverter라는 클래스가 오브젝트를 응답할때 자동 발동함 } }
 
  • insert 수정하기
package shop.mtcoding.blog.board; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import java.util.List; @RequiredArgsConstructor @Repository public class BoardRepository { private final EntityManager em; public List<Board> selectAll() { Query query = em.createNativeQuery("select * from board_tb order by id desc ", Board.class); List<Board> boardList = query.getResultList(); // 못찾으면 빈 컬렉션을 준다 (크기=0) return boardList; } public Board selectOne(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) { return null; } } @Transactional public void insert(BoardRequest.WriteDTO requestDTO){ Query query = em.createNativeQuery("insert into board_tb(title, content, author) values(?, ?, ?)"); query.setParameter(1, requestDTO.getTitle()); query.setParameter(2, requestDTO.getContent()); query.setParameter(3, requestDTO.getAuthor()); query.executeUpdate(); } @Transactional public void deleteById(Integer id) { Query query = em.createNativeQuery("delete from board_tb where id = ?"); query.setParameter(1, id); query.executeUpdate(); // insert, update, delete는 커밋이 발동 } }
 
  • JUNUIT에서 insert_test() 수정하기
package shop.mtcoding.blog.board; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; import org.springframework.test.annotation.Rollback; import java.util.List; @Import(BoardRepository.class) // 내가 만든 클래스는 import 해줘야 함. @DataJpaTest // DB 관련 객체들이 IoC에 뜬다. public class BoardRepositoryTest { @Autowired // Test에서 DI 하는 코드 private BoardRepository boardRepository; @Test public void selectAll_test(){ // given // when List<Board> boardList = boardRepository.selectAll(); System.out.println(boardList.size()); // then (id=1, title=제목1, content=내용1, author=홍길동) // System.out.println(boardList); Assertions.assertThat(boardList.get(0).getTitle()).isEqualTo("제목1"); Assertions.assertThat(boardList.get(0).getContent()).isEqualTo("내용1"); Assertions.assertThat(boardList.get(0).getAuthor()).isEqualTo("홍길동"); Assertions.assertThat(boardList.size()).isEqualTo(8); } @Test public void selectOne_test(){ // given int id = 1; // when Board board = boardRepository.selectOne(id); // then (상태 검사) // System.out.println(board); Assertions.assertThat(board.getTitle()).isEqualTo("제목1"); Assertions.assertThat(board.getContent()).isEqualTo("내용1"); Assertions.assertThat(board.getAuthor()).isEqualTo("홍길동"); } @Test public void insert_test(){ // 테스트 메서드는 파라미터가 없다. 리턴도 없다. BoardRequest.WriteDTO requestDTO = new BoardRequest.WriteDTO(); // given String title = "제목10"; String content = "내용10"; String author = "이순신"; // when boardRepository.insert(requestDTO); // then -> 눈으로 확인 (쿼리) } // Rollback (자동) }
notion image
 
 
{{> layout/header}} <div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글쓰기 화면입니다</b></div> <div class="card-body"> <form action="#"> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content"></textarea> </div> <button type="button" onclick="btnWrite()" class="btn btn-primary form-control">글쓰기완료</button> </form> </div> </div> </div> <script> function btnWrite(){ let board = { // js 오브젝트 title: $("#title").val(), // value값 들고 옴 content: $("#content").val(), // value값 들고 옴 author: $("#author").val() // value값 들고 옴 }; console.log(board); // 잘 들고 오는지 확인 } </script> {{> layout/footer}}
notion image
 
$.ajax({ }).done((res)=>{ }).fail((res)=>{ })
notion image
notion image
notion image
 
 
{{> layout/header}} <div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글쓰기 화면입니다</b></div> <div class="card-body"> <form action="#"> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content"></textarea> </div> <button type="button" onclick="btnWrite()" class="btn btn-primary form-control">글쓰기완료</button> </form> </div> </div> </div> <script> function btnWrite() { let board = { // js 오브젝트 title: $("#title").val(), // value값 들고 옴 content: $("#content").val(), // value값 들고 옴 author: $("#author").val() // value값 들고 옴 }; console.log(board); // 잘 들고 오는지 확인 // 통신해서 보내기 위해 json으로 변경 let boardJson = JSON.stringify(board); console.log(boardJsond); $.ajax({ url: "api/boards/", type: "post", data: JSON.stringify(board), contentType: "application/json; charset=utf-8" }).done((res) => { location.href = "/"; }).fail((res) => { alert(res.responseJSON.msg); }); } </script> {{> layout/footer}}
notion image
notion image
notion image
notion image
 
Share article

vosw1