-
Spring:댓글(ajax.ver)JAVA 2021. 7. 26. 23:17
1. ajax비동기!!!!
RestController 는 WebService 의 일종이다. java 객체와 html,js 의 속성값과 매핑시 , 객체의 멤버변수 이름이 속성값이다!
객체의 이름이 속성값이 아니므로 주의!
Content content - 매핑 - board.no : content의 board멤버변수의 no 멤버변수1) 사전작업
>> pom.xml (다운받을 라이브러리)
spring 의 restControlle 들이 json 으로 데이터를 주고 받게 도와주는 라이브러리 정도로 기억하면 된다!
(ajax 는 json 을 주고 받기 때문에 필수)
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.1</version> </dependency>
클라이언트에게 응답으로 view 를 주는 표준의 Controller 와 달리 restController 는 데이터만 갱신하거나 더해준다.
그래서 ajax 를 이용해 restController 로 비동기식 데이터로 전달한다.
(이를 동기식으로하면 기존은 날라가고(화면이 새로고침됨) 전달한것만 보여지기 때문에)
컨트롤러들은 항상
@Configuration 인 컨트롤 전체를 관리하는 클래스의 (web.xml 에서 설정해놓음- 현재 MvcConfig클래스!)
@ComponentScan("패키지명") 안에 들어와있는지 늘 확인
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.stone")//이부분 public class MvcConfig implements WebMvcConfigurer { //중략...}
비지니스 서버로 ajax 를 따로 사용했으나 굉장히 비싸며 운영에 어려움이 있었다.
그래서 현재 방식은 WebServer 에 비지니스 서버까지 넣어서 WebService 라는 이름의 서버로 ajax를 WebServer 안에서 다 할 수 있도록 하는 추세다.
2) ajax 전용인 restController 와 그에 사용되는 어노테이션들
>> TestController
// 예시를 위한 객체 class Car{ int no; String model; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getModel() { return model; } public void setModel(String model) { this.model = model; } } // 완전 중요!!!!! @RestController public class TestController { @RequestMapping("work1") @ResponseBody public String process1(@RequestBody Car myCar) { System.out.println(myCar.getModel()); return "welcome"; } // 객체를 return 가능 ( 받는 쪽에서 json 으로 잘 변환 ) @RequestMapping("work2") @ResponseBody public Car process2() { Car myCar = new Car(); myCar.setModel("kia"); myCar.setNo(7); // IN javascript : {no:7, model:"kia"} json 문자열로 변환 return myCar; } // 배열로 보내도 가능 @RequestMapping("work3") @ResponseBody public List<Car> process3() { Car myCar = new Car(); myCar.setModel("kia"); myCar.setNo(7); Car myCar2 = new Car(); myCar2.setModel("hd"); myCar2.setNo(8); List<Car> cars = new ArrayList<Car>(); cars.add(myCar); cars.add(myCar2); // IN javascript : [{no:7, model:"kia"}, {no:8, model:"hd"}] 대괄호가 배열을 나타낸다. return cars; } // produces : return 이 String 이지만 이 값을 text/plain 으로 보냄 @RequestMapping(value = "work4", method= {RequestMethod.POST}, produces="text/plain;charset=utf-8") @ResponseBody public String process4() { String html = "<input type='text' value='값' />"; html+="<p><h1>이 문단은 보일까</h1></p>"; return html; } }
@RestController VS. @Controller
@RestController
매핑과 응답(생략가능) 어노테이션!
= @RequestMapping (매핑)
= @ResponseBody (응답)
하지만 @ResponseBody 생략가능하다.
@RestController 자체가 이미 json 으로 받겠다는 의미이기 때문이다.
@Controller
매핑과 응답까지 어노테이션!
= @RequestMapping (매핑)
= @ResponseBody (응답)
@Controller 은 기본적으로 javascript 의 json 이 아닌 jsp 의 form 같은 html 내에 것을 받는 컨트롤들의 집합체다.
어떤 컨트롤이 json 을 받을 경우 @ResponseBody 을 달아줘야 js 의 json 으로 받아준다.@RequestMapping
: produces 속성 = return값(응답받는 값) 의 자료형을 막론하고(주로 String임) 설정한 값으로 보냄
(ex. html, xml, json 등등)
charset=UTF-8 로 해줘야 한글이 안깨진다!
: method = RequestMethod.POST 을 써주지 않으면 POST 방식을 못 받을때도 있으니 오류나면 실험해 볼것@RequestBody
: 요청으로 오는 값 매핑
json 문자열 -> 객체로 resolving 시켜줌
(@Controller 는 @RequestParam 이였다.)요청의 경우 'json -> 객체' , 응답의 경우 '객체 -> json' 가능하다.
요청: @RequestBody 의 매핑된 요청의 param 이 json 이면 객체로 매핑가능하다.
응답: return 값이 객체이면 받는곳에서 json 으로 변환 가능하다.3) javascript 에서(기본적으로 jquery 이용) ajax 로 요청해보기
꼭 ajax 용의 jquery 를 script 삽입해야함!!
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js">
- 기본문법
jquery 홈페이지 : https://api.jquery.com/jquery.ajax/#jQuery-ajax-url-settings
w3 의 jquery 부분에서도 ajax 속성들 확인가능함
url : 수신 측이 외부시스템이니 풀주소로 요청, html을 받아온다는게 아니고 그 안의 데이터들을 return 해옴 success : result = 수신측에서 보낸 JSON 객체이므로 그 객체의 속성명을 사용해 속성값을 얻어낸 것이다.
status = ajax가 송수신 측 통신이 잘되었는지 결과를 저장한 변수type : url 보낼 때 method 타입 dataType : return 데이터타입 (요청 받아오는 애 타입, result 의 타입이다. )
가져오는 측에서 보니까 sendJSONObject 라고 보냈음. 즉 JSON 객체로 저장한 데이터를 가져오는 거니까 dataType 이 json 인 것이다.contentType : 요청보내는 데이터타입 data : 수신 측에 보내는 데이터로, 이 데이터에 맞는 데이터를 수신측에서 get 하여 put 으로 결과를 보내는 것이다.
JSON.stringify() 은 JSON 객체를 String 으로 변환
JSON.parse() 는 반대로 String 객체를 JSON 으로 변환
"pno" 는 $("#pno").val() 과 똑같음.<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script type="text/javascript"> function 요청보내다(){ var mycar = {no:1, model:"hd"}; $.ajax({ url:"work1", type:"POST", contentType:"application/json; charset=utf-8", data: JSON.stringify(mycar), dataType:"json", success:function(result){ alert(result); } }); } function 요청보내다2(){ $.ajax({ url:"work4", type:"POST", dataType:"text", success:function(result){ //html = 자바스크립트에 있는 속성이며 해당 div 태그안에 받아오는 값들을 html 형식으로 출력 $("#여기").html(result); } }); } </script> </head> <body> <div id="여기"></div> <button onclick="요청보내다()">요청</button> <button onclick="요청보내다2()">요청2</button> </body> </html>
댓글 ajax 통신
1. 비동기방식으로 댓글목록화면 주기적 갱신 2. 비동기방식으로 댓글등록요청 게시물컨트롤 ,게시물상세창.jsp (부속:Board, BoardDAO) 만 있으면 됨! 3. 게시물상세창에 들어가는 컨트롤(요청)
1) 게시물에 대한 정보 DB 에서 얻어오는 컨트롤
2) 게시물번호로 댓글들을 DB 에서 얻어오는 컨트롤 ( 이쪽은 ajax 통신 )
3) 게시물번호로 댓글을 DB 에 저장하는 컨트롤 ( 이쪽도 ajax 통신 )>> 게시물컨트롤
1) = 게시물상세를출력하다() // 먼저실행
2) = 게시물댓글을출력하다() // view 에서 수시로 ajax 통신 실행중
3) = 게시물댓글을등록하다() // 등록시 ajax 통신으로 바로 업데이트
@GetMapping("board/{no}") //spring 은 getSession()으로 (false) 가 아니라서 null 인 경우 null 로 나오는게 아니라 새로만들어줌 public ModelAndView 게시물상세를출력하다(@PathVariable int no, HttpSession session) { Board board = boardDAO.findByNo(no, true); ModelAndView mv = new ModelAndView(); mv.addObject("board",board); mv.addObject("writer_no",session.getAttribute("no")); mv.setViewName("/board/게시물상세창"); return mv; } @RequestMapping(value = "board/comment", method= {RequestMethod.POST}) @ResponseBody public String 게시물댓글을등록하다(@RequestBody Comment comment) { commentDAO.save(comment); ModelAndView mv = new ModelAndView(); return "ok"; } @RequestMapping(value="board/comments/{no}", method = RequestMethod.POST, produces = "text/plain;; charset=UTF-8") @ResponseBody public String 게시물댓글을출력하다(@PathVariable int no) { RefInteger totalSize = new RefInteger(); int size = 3; List<Comment> comments = commentDAO.selectByBoardNo(no, size, totalSize); ModelAndView mv = new ModelAndView(); String html=""; html+="<p>댓글수는 "+totalSize.value +"</p>"; html+="<ul>"; for(Comment comment : comments) { html += "<li>"; html += String.format("<p>%s</p>", comment.getWriter().getName()); html += String.format("<p>%s</p>", comment.getWdate().toString()); html += String.format("<textarea cols=20 rows=5 readonly>%s</textarea><br>", comment.getContents()); html += "<button>좋아요</button><button>싫어요</button>"; html += "</li>"; } html+="</ul>"; return html; }
>> 게시물상세창.jsp
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script> function 화면갱신(){ $.ajax({ url:"/board/comments/${board.no}", type:"POST", success:function(result){ $("#comments").html(result); } }); } //비동기로 화면갱신! setInterval(화면갱신, 3000); function 댓글등록하다(){ //로그인하지않아 writer_no 가 없을 수도 있다. 그때는 댓글등록을 막는다. <c:choose> <c:when test="${empty writer_no}"> alert("로그인 후 이용가능합니다."); location.href="/login"; </c:when> <c:otherwise> var comment = {"board":{no:${board.no}},"contents":$("#contents").val(),"writer":{no:${writer_no}}}; $.ajax({ url:"/board/comment", success:function(result,status){ alert("등록되었습니다."); $("#contents").val(""); 화면갱신(); }, type:"POST", contentType:"application/json", data:JSON.stringify(comment) }); </c:otherwise> </c:choose> } </script> </head> <body> <h1>게시물 상세</h1> 제 목 : ${board.title} <br> 내 용 : <textarea rows="1" cols="5" readonly="readonly">${board.contents}</textarea><br> 작성자 : ${board.writer.name}<br> 작성일 : ${board.wdate}<br> 조회수 : ${board.views}<br> <c:if test="${not empty board.attachs}"> 첨부 : <br /> <ul> <c:forEach var="attach" items="${board.attachs}" varStatus="status"> <li> ${status.count} ${attach.name} ${attach.size} </li> </c:forEach> </ul> </c:if> <!--댓글 쓰기 부분 --> 댓글 <textarea cols=40 rows=5 id="contents"></textarea> <button type="button" onclick="댓글등록하다()">보내기</button><br> <!-- 댓글들 출력 부분 --> <div id="comments"></div> </body> </html>
{"board":{no:${board.no}}}
= content객체의 board멤버변수의 no 멤버변수 에다가 현재 board 상세보기여서 실행된
'1) 게시물에 대한 정보 DB 에서 얻어오는 컨트롤' 의 mv.addObject("board",board) 의 no 를 넣는것이다.'JAVA' 카테고리의 다른 글
BLOB 이미지파일업로드 (0) 2021.07.27 Spring:댓글더보기(ajax.ver) (0) 2021.07.26 Spring: 댓글(iframe.ver) (0) 2021.07.26 Spring:댓글 (0) 2021.07.26 Spring:resolver (0) 2021.07.26