이틀동안 매달렸던 기능 구현 작업이 우리팀 팀장님 덕분에 12분만에 해결됐다. (48시간 -> 12분 팀장님의 마법 )
코드를 따오더라도 '스프링'을 제대로 이해하고 있어야 따와서 그대로 적용하든 활용을 하든 하는구나..
게시판 모양새까지는 잘 구현해내길래 나는 내가 스프링을 잘 이해하고 코드를 잘 따오는 줄 알았다.
그러나...
백날 스프링 레이어 구조 외우면 뭐하나... 게시판에서 상세 게시글로 넘어가지 못하는 오류가 발생하고...
팀장님이 자세히 설명해주며 오류를 해결해주셨기에 TIL을 남긴다. (진짜 오랜만에 real TIL)
(유독 '팀장님' 단어가 밝게 보인다면 그저 '빛'이기 때문이다)
1. 우선, 클라이언트의 명령을 받아 서비스로 전달하는 컨트롤러.
프론트단에서 명령을 받아 수행하는 컨트롤러인
FrontController에 view함수를 추가한다.
@GetMapping("/view")
public String view(){
return "view";
}
클라이언트께서 view 페이지(상세 게시글 페이지)를 보겠다 하시면 view 페이지를 보여드리는 것이다..
2. 그리고 게시판의 컨트롤러.
(내가 맡은 기능인 게시판의 컨트롤러를 잘 확인했어야 했는데... 내 멍청의 한계는 어디인가?)
BoardController를 확인한다.
@RequiredArgsConstructor
@RestController
public class BoardController {
private final BoardService boardService;
@PostMapping("/board") // /board url이 들어오면 setBoard 함수 실행해라
public Board setBoard(BoardRequestDto boardRequestDto) throws IOException {
return boardService.setBoard(boardRequestDto); //게시판의 Service가 setBoard 실행한 값(물론 Dto인자로) 리턴
// (왜 Dto 인자냐면 원래 변수의 값을 함부로 망치면 안되니까.. 설명이 저렴해도 이해하라)
}
@GetMapping("/boards")
public List<Board> getBoards(@RequestParam(required = false) String searchTag){ //게시글 리스트 불러오기
return boardService.getBoards(searchTag);
}
@GetMapping("/view/{idx}") // /view/{idx}이 들어오면 getBoard 함수 실행해라 -> 상세 게시글을 확인하는 함수~!~!~!~!
public Board getBoard(@PathVariable Long idx){
return boardService.getBoard(idx);
}
@PostMapping("/board/comment")
public void setBoardComment(@RequestBody BoardCommentRequestDto boardCommentRequestDto){
boardService.setBoardComment(boardCommentRequestDto);
}
}
3. 컨트롤러에서 클라이언트에게 명령을 받을 시(url로 받는다) 어떤 함수를 실행시켜줄지 정의했으므로,
게시판의 Service로 가서 확인해보자.
BoardService.java를 일부 발췌했다.
@RequiredArgsConstructor
@Service
public class BoardService {
private final BoardRepository boardRepository; //서비스가 DB를 건드려야할 때는, 레포지터리를 거쳐 명령한다. (SQL문을 쉽게! 이것이 JPA)
public Board getBoard(Long id){
return boardRepository.findById(id).orElseThrow( //boardRepository.findById(id)를 통해 id로 게시글을 찾아준다.
() -> new NullPointerException("해당 아이디가 존재하지 않습니다.") //이건 뭔지 모르겠다. 추후 공부 예정 ^_^;>
);
//다른 여러 함수가 많지만 일부만 발췌함
}
}
참고로 게시글에 사용될 테이블은 (Domain은)
아래와 같이 명시되어 있으며,
package com.weling.we_are_traveling_java.domain;
import com.weling.we_are_traveling_java.dto.BoardRequestDto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.util.List;
import java.util.Set;
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
@Entity
public class Board extends Timestamped {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long idx;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String content;
@Column(nullable = true)
private String imageUrl;
@OneToMany(mappedBy="board")
private List<Comment> comments;
@OneToMany(mappedBy="board")
private Set<Tag> tags;
public Board(BoardRequestDto requestDto, String imageUrl) {
this.title = requestDto.getTitle();
this.content = requestDto.getContent();
this.imageUrl = imageUrl;
}
public Board(BoardRequestDto requestDto) {
this.title = requestDto.getTitle();
this.content = requestDto.getContent();
}
}
Dto는 아래와 같이 정의되어 있다.
package com.weling.we_are_traveling_java.dto;
import lombok.Getter;
import lombok.Setter;
import org.springframework.web.multipart.MultipartFile;
@Setter
@Getter
public class BoardRequestDto {
private String title;
private String content;
private String tags;
private MultipartFile image;
}
3. 자 그럼...
게시판에서 게시글을 작성하는 부분으로 가보자..
(코드 에러를 고치고, 리뷰하는 사람들이 ...을 많이 쓰는 이유를 알겠다. 컴퓨터를 못 믿은 내 자신이 한심해서이다.)
Board_insert.html 의 script - postingBoard() 함수이다.
function postingBoard() {
var data = new FormData();
data.append("title", $("#title").val());
data.append("content", $("#content").val());
data.append("tags", $("#tags").val());
data.append("image", $("#image")[0].files[0]);
if( typeof $("#image")[0].files[0] != 'undefined') data.append( "image", $("#image")[0].files[0] );
$.ajax({
type: "POST", //1. 생성하겠다.
url: "/board", //2. 요청이 /board로 들어온다면.
processData: false,
contentType: false,
data: data,
success: function (response) {
location.href= "/view?idx="+response["idx"];
//3. 생성하고 나서, 생성된 게시글의 아이디, response로 받은 "idx"로 이동하겠다.
}
})
}
그리고...
상세 게시글 html인 view.html이다.. (일부 발췌)
let idx = '';
$(document).ready(function () {
idx = getParam('idx');
getBoard(idx); //html이 실행되자마자 idx에 맞는 상세게시글을 불러올 것이다
});
function getParam(name) { //얜 도대체 뭐냐? 추후 공부 예정
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
return results[1] || 0;
}
function getBoard(idx) {
$.ajax({
type: "GET", //1. 가져올 것이다
url: `/view/${idx}`, //2. 이렇게 명령이 들어온다면..
contentType: "application/json",
success: function (response) {
$("#title").html(response['title']);
$("#content").html(response['content']);
$("#image").attr("src",response['imageUrl']);
$("#comment-list").empty();
for (let i = 0; i < response['comments'].length; i++) {
makeListComment(response['comments'][i])
}
}
})
}
4. 마지막으로 내가 오류를 겪었을 때 가장 헷갈렸으며 중요한 부분
(중요하지 않다. 그냥 내가 스프링을 모르고 자바스크립트를 모르니까 일어난 문제다)
Board.java이며 게시판의 게시글 리스트를 불러오는 부분이다.
function makeListPost(board, index) {
let tags = '';
for (let i = 0; i < board['tags'].length; i++) {
console.log(board['tags'][i]);
tags += " #" + board['tags'][i]['name'];
}
let tempHtml = ` <tr>
<th scope="row">${index}</th>
<td><a href="view?idx=${board['idx']}">${board['title']}</td>
<td>${board['comments'].length}</td>
<td>${tags}</td>
<td>${board['createdAt']}</td>
</tr>
`;
$("#list-post").append(tempHtml);
}
<td><a href="view?idx=${board['idx']}">${board['title']}</td> 이 부분에서,
나는 계속 view.html?idx=${board['idx']} 로 넘어오게 했다.
팀장님이 이 부분을 고쳐주신 순간(위 부분들도 다 고쳐주신 것) 머리를 맞은 기분이었다...
(자꾸 상세 게시글을 불러도 작성할때 넣은 내용들이 안나왔다 ㅠㅠ)
내가 이 글과 같은 부분으로 인해 뻘뻘대는 동안
팀장님이 새로운 기능을 구현하셔서 main을 끌어다 내 브랜치에 merge하려니 오류가 났다.
FrontController에서 아래에 코드가 추가되었는데, main 브랜치의 코드를 복사해 내 브랜치에 복사해넣어도
자꾸 충돌했다.
그래서 그냥 내 브랜치에서 추가된 부분/내가 추가할 부분을 싹다 지우고 커밋 후 merge하니 오류 해결!
오류를 해결해주신 팀장님덕분에 스프링에 감이 잡혔다.
앞으로 남은 댓글 기능/게시글 수정, 삭제 기능/지도 첨부 기능을 구현할 예정이고
그리고 시간이 남는다면 메인페이지에 위젯도 넣어보고 싶다..
아무튼 유익한 하루!
'Today I Learned' 카테고리의 다른 글
KPT_3차 프로젝트 회고하기 (0) | 2021.12.13 |
---|---|
TIL1014_JWT (0) | 2021.12.13 |
Git 되돌리기 (0) | 2021.12.09 |
Spring 게시판 만들기 (0) | 2021.12.07 |
211130TIL_API (0) | 2021.12.02 |