ABOUT ME

  • 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

    댓글

Designed by Tistory.