티스토리 뷰
매번 프로젝트를 할 때마다 느끼는건데, '과연 이걸 구현할 수 있을까?', '못하면 어떡하지?' 싶은 기능들을 어찌저찌 잘 구현해가고 있다. 오늘은 프로젝트를 하면서 구글링을 했었지만 만족할만한 결과가 없어서 혼자 이 코드 저 코드 봐가며 완성한 기능을 정리하려고 한다. 혹시 비슷한 기능을 만들 누군가에게 도움이 되기를. (제 방법이 제일 효율적이라거나 그런 것은 아닙니다. 저는 이렇게 구현했고, 혹시 다른 더 좋은 방법이 있다면 알려주시면 감사하겠습니다.)
우선 상황을 설명하자면 이랬다.
위 화면은 숙소정보 상세조회화면이다. 아래의 리스트는 리뷰리스트인데, 저 리스트의 제목을 누르면 그 리스트의 내용이 보여야 한다. 보여야 하는 내용에는 리뷰의 이미지들도 포함되어 있는데, 테이블구조상 리뷰와 리뷰이미지는 분리되어 있다. 즉, 리뷰DTO와 리뷰사진DTO를 가져와도 리뷰DTO와 리뷰사진DTO의 연관성을 찾아서 모달에 그 리뷰만의 이미지들을 뿌려주기 힘들다. jstl로 리뷰DTO에서 seq을 뽑아 리뷰사진DTO의 seqReview(리뷰의 seq는 리뷰사진의 외래키이다.)와 비교해서 일치하면 모달에 이미지로 넘겨주면 되지 않겠나 생각하겠지만, seq이 확정되는 건 이미 페이지가 렌더링되고 사용자가 목록을 하나 선택했을 때이다.(서버가 JSTL 처리를 완료하면 HTML, JavaScript와 함께 JSTL에서 생성된 HTML이 렌더링된다. 즉, jstl이 이미 처리되고 난 한참뒤에 seq이 확정되는 것이다.) 그렇기 때문에 나는 ajax를 이용해서 선택한 리뷰글번호를 보내서 그 리뷰글에 해당하는 이미지들을 가져와서 html태그를 건드리는 방법을 선택했다.
아래는 HTML태그이다. 제목(rdto.title)을 누르면 모달이 열리게 되어 있다.
<td id="todetail">
<a data-toggle="modal" data-target="#detailModal" data-seq="${rdto.seq}" data-content="${rdto.content}">
${rdto.title} <!-- 리뷰제목 -->
</a>
</td>
<!--
클릭하면 모달이 열려야 하는 리뷰제목이다.
rdto는 리뷰DTO이고, rdto.seq는 리뷰글번호, rdto.content는 리뷰내용이다.
리뷰내용은 이미지들과 함께 모달로 보내야하기 때문에 위처럼 설정해준다.
-->
// 모달창 modal-body 안쪽의 구성
<div class="modal-body" style="text-align:center;">
<p id="modalcontent"></p>
<div id="reviewimgbox"></div>
</div>
// 제목을 누르면 아래의 코드가 실행된다.
// 이때 태그는 a태그에 id를 주고 그 id로 잡으면 안되고, 꼭 상위태그에서 내려가는 방향으로 줘야 개별적으로 인식된다.
// 그냥 a태그에 id를 주고 그 id로 잡으면 어떤 리뷰제목을 눌러도 제일 위에 있는 항목의 내용이 뜬다.
$("#todetail > a").on('click', function(){
// 리뷰내용을 모달창으로 옮긴다.
$('#modalcontent').text($(this).data("content"));
// 리뷰번호에 따른 이미지도 모달로 넣는다.
// 아래는 리뷰번호에 따라 그 리뷰번호의 이미지들 가져오는 ajax
$.ajax({
url: "/bnna/member/bnbsearch/getreviewpic.action",
data: {seq: $(this).data("seq")},
dataType:"json",
success: function(data) {
var content=""; // 채워질 모달내용
// 받아온 data(json)를 for문을 돌려 꺼내서 모달내용을 채운다.
// data는 { 번호 : 이미지파일명(ex. test.png) } 이런 형식으로 되어 있다.
for(var key in data) {
content+='<div><img src="/bnna/resources/image/board/review/'+data[key]+'" style="max-width:350px; margin:10px;"></div>';
}
// 모달내용을 다 채웠다면 이미지를 넣을 태그에 내용을 채워준다.
// append로 하면 태그가 계속 추가되기 때문에 html로 해줘야 한다.
// 그렇기 때문에 리뷰내용과 리뷰이미지를 구분해놓은 것이기도 하고.
$(".modal-body > #reviewimgbox").html(content);
// 끝!
console.log("complete");
},
error: function() {
console.log("error!");
}
});
});
ajax를 호출하면 자바단으로 옮겨가게 되고, 아래와 같이 처리된다.
@RequestMapping(value="/member/bnbsearch/getreviewpic.action", method={RequestMethod.GET})
public void getReviewPic(HttpServletRequest req, HttpServletResponse resp, HttpSession session, String seq (****)) {
// ajax에서 보낸 data(seq:$(this).data("seq")는 key를 파라미터로 넣어서 받는다. (****) 부분.
// 비즈니스 로직을 처리하고 난 결과를 HashMap으로 만들어서
// JSON으로 다시 돌려줘야 하는데, 이 때 Gson을 사용해서 자바 오브젝트를 JSON으로 변환한다.
Gson gson=new Gson();
// 리뷰 이미지들을 넣어줄 HashMap을 만든다.
// 난 어차피 String이라서 Object가 아니라 String으로 해도 상관없었을 것 같다.
Map<String, Object> data=new HashMap<String, Object>();
// 받아온 리뷰번호로 그 리뷰의 이미지들을 찾는다.
List<ReviewPicDTO> rplist=rpdao.list(seq); // list() : 리뷰번호에 따라 그 리뷰이미지찾는 메서드
// 리뷰이미지 리스트들을 풀어서 HashMap에 넣는다.
for (int i=0;i<rplist.size();i++) {
data.put(i+"", rplist.get(i).getImage());
// data에 { 번호 : 파일명 } 이런 식으로 저장된다고 생각하면 된다.
}
try {
// 이제 만든 data를 JSON형식으로 보낸다.
resp.getWriter().print(gson.toJson(data));
} catch (IOException e) {
e.printStackTrace();
}
}
그럼 아래와 같이 각 리뷰에 해당하는 이미지들을 리뷰내용과 함께 모달창으로 볼 수 있다.
'공부흔적' 카테고리의 다른 글
프레임워크와 라이브러리 (0) | 2021.04.08 |
---|---|
Git 로컬 merge 되돌리기 (0) | 2021.04.03 |
pom.properties? MANIFEST.MF? (0) | 2021.03.16 |
400 Bad Request (0) | 2021.03.15 |
스프링에서 Bean을 설정하는 세 가지 방법 (0) | 2021.03.10 |