ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 학원 day94. Ajax요청 처리, 자바스크립트 배열
    기록 2023. 1. 16. 10:25

    HandlerAdapter가 Controller를 실행하면 최종적으로 ModelAndView를 만들어서 DispatcherServlet에 전달한다. 

    DispatcherServlet은 언제나 View를 실행하여 클라이언트에게 응답을 제공한다. 

    특정 컨텐츠타입으로 변환해주는 뷰만 있으면 다양한 형태의 컨텐츠를 응답으로 보내줄 수 있다.

    서버로 사용자아이디를 보내지 말라고 한 건, 사용자가 작성하거나 등록할 때를 말하는 것이고, 사용자의 제한적인 정보를 조회할 때는 사용자의 아이디를 넘겨줘도 된다.

     

    controller 안에서 modelandview를 만들고 model에 사용자정보를 담고, view에 jsonView를 넣어서 전해지도록 함.

    DispatcherServlet은 JsonView의 render메소드를 실행하게 됨. 

    JsonView에서는 model에서 사용자정보를 조회하고, 사용자정보를 json형식의 텍스트로 변환하여 응답으로 보낼 것임.

     

    Maven Repository 에서 Jackson Databind 2.14.1의 의존성주입코드 가져와서 pom.xml 에 붙여주기.

    Controller에서 @GetMapping("/detail.json")이라고 적고, @ResponseBody어노테이션을 추가한다.
    @ResponseBody가 붙으면 UserDetailDto객체를 Json이나 xml형태로 변환해서 응답으로 보낸다.
    @ResponseBody가 붙으면 요청핸들러가 반환하는게 JSP의 이름(view name)으로 판단하는게 아니라 응답메세지의 바디부에 포함되어서 내려가는 것으로 판단한다. (원래는 응답메세지의 바디부에 jsp의 실행결과인 html이 응답으로 내려감)

    즉, ResponseBody가 붙으면 html이 아닌 요청핸들러 메소드가 반환하는것을 응답메세지의 바디에 담겨서 내려간다.
    또한, jackson-databind 라는 라이브러리를 포함시키놨기 때문에 요청핸들러가 반환한것을 json형식으로 변환해준다. 내부적으로 JsonView라는게 들어있는 것이다.

    json 형식의 데이터를 응답으로 제공하는 이유
    * json 형식의 텍스트는 자바스크립트 객체나 배열로 쉽게 변환할 수 있기 때문이다.
    자바스크립트의 객체, 배열로 변경되기 때문에 값을 쉽게 꺼내 쓸 수 있기 때문이다.

    json에서 제공해주는 다양한 어노테이션을 활용할 수 있다.

    @JsonFormat으로 날짜 형식을 정해줄수도 있고, @JsonIgnore로 민감한 정보는 뺄 수도 있다.

    a태그가 많기 때문에 앞에 아이디를 적어주고 a태그의 속성을 적어준다

    중간중간 alert(변수명);로 제대로 작동하는지 확인할 것!

    // http://localhost/user/detail.json?userId=hong

    $.getJSON('/user/detail.json', {userId: id}, function(user) {

    }) 

    위 코드의 {userId: id} 에서 앞에 적은 건 요청파라미터의 이름, 뒤에 적은게 값이 됨.

    function은 성공적인 응답이 왔을 때 실행되는 것임. 

    user라는 매개변수에는 응답으로 받은게 들어있음.


    json형식의 텍스트는 두가지 형태가 있다.

    json 형식

    - JSON Object 표기법 : name/value 쌍의 집합
    ' {"name1":value1, "name2":value2, "name3":value3, "name4":value4} '
    let obj = JSON.parse(jsonText);

    예시
    let jsonText = '{"name":"홍길동", "email":"hong@gmail.com", "roles":["사용자":"관리자"]}';
    let obj = JSON.parse(jsonText);

    * 자바스크립트의 객체와 대응
    * 자바의 VO, Map과 대응

    - JSON Array 표기법 : 값들의 순서화된 리스트
    '[ value1, value2, value3, value4 ]'
    * 자바스크립트의 배열과 대응
    * 자바의 배열, 콜렉션과 대응

    <!-- 사용자 정보 표시 모달창 -->
    <div class="modal" tabindex="-1" id="modal-user-detail">
       <div class="modal-dialog modal-md">
          <div class="modal-content">
             <div class="modal-header">
                <h5 class="modal-title">사용자 정보</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
             </div>
             <div class="modal-body">
                <table class="table" id="table-user">
                   <colgroup>
                      <col width="15%">
                      <col width="35%">
                      <col width="15%">
                      <col width="35%">
                   </colgroup>
                   <tbody>
                      <tr>
                         <th>아이디</th><td><span id="user-id"></span></td> 
                         <th>이름</th><td><span id="user-name"></span></td>
                      </tr>
                      <tr>
                         <th>이메일</th><td><span id="user-email"></span></td>
                         <th>등록일</th><td><span id="user-created-date"></span></td>
                      </tr>
                      <tr>
                         <th>보유권한</th><td colspan="3"><span id="user-role"></span></td>
                      </tr>
                   </tbody>
                </table>
             </div>
             <div class="modal-footer">
                <button type="button" class="btn btn-secondary btn-xs" data-bs-dismiss="modal">확인</button>
             </div>
          </div>
       </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
    <script>
    $(function() {
    	let modal = new bootstrap.Modal('#modal-user-detail');
    	
    	// 아이디가 table-posts인 엘리먼트의 자손 중에서 a엘리먼트이고 data-user-id 속성을 가지고 있는 것을 선택하고, 
    	// 선택된 엘리먼트에서 클릭이벤트가 발생했을 때 실행될 이벤트 핸들러함수를 등록한다.
    	$("#table-posts a[data-user-id]").click(function(event) {
    		// a 태그에서 클릭이벤트 발생했을 링크로 이동하는 기본동작이 실행되지 않게 한다.
    		event.preventDefault();   /// a태그의 기본동작이 일어나지 않게 하려고 event를 매개변수로 받고, preventDefault();를 실행한다. 
    		//alert("조회");   /// 테스트용
    		
    		let id = $(this).attr('data-user-id'); /// $(this)는 내가 지금 클릭한 것
    		//alert(id);
    		
    		// 서버로 ajax 요청을 보낸다.
    		// http://localhost/user/detail.json?userId=hong
    		$.getJSON('/user/detail.json', {userId: id}, function(user) {
    			// 모달창의 엘리먼트에 값을 표현한다.
    			$("#user-id").text(user.id);
    			$("#user-name").text(user.name);
    			$("#user-email").text(user.email);
    			$("#user-created-date").text(user.createdDate);
    			
    			// user.userRoles -> [{"userId":"leess","roleName":"ROLE_GUEST"}, {"userId":"leess","roleName":"ROLE_USER"}]
    			// .map() -> ["ROLE_GUEST", "ROLE_USER"] 
    			// .join() -> "ROLE_GUEST, ROLE_USER"
    			// roles -> "ROLE_GUEST, ROLE_USER"
    			let roles = user.userRoles.map(function(item, index) { 
    				return item.roleName}).join(', ');
    			$("#user-role").text(roles);
    			
    			// 모달창을 표시한다.
    			modal.show();
    			/*
    			user 변수에 대입되어 있는 객체는 아래와 같다.
    			{
    				"id":"leess",
    					"name":"이순신",
    					"email":"leess@gmail.com",
    					"createdDate":"2023-01-16",
    					"userRoles":[
    								{"userId":"leess","roleName":"ROLE_GUEST"},
    								{"userId":"leess","roleName":"ROLE_USER"}
    		  					]
    			}
    		    */
    		})
    		
    	});
    })
    </script>

    .forEach(function(value, index) { ... })
    배열의 저장된 값의 갯수만큼 지정된 함수를 실행한다.
    forEach 메소드의 콜백함수는 배열의 값을 소비하는 함수다. (소비한다 -> 반환값이 없다는 의미이다.)

    아래 코드는 화살표함수를 사용함. function 대신 사용할 수 있음.

    수행문이 여러개일 경우 {} 안에 적는다. 

     

    .filter(function(value, index) { ... })
    지정된 함수가 true를 반환하는 값으로만 구성된 배열을 반환한다.
    filter 메소드의 콜백함수는 배열의 값을 필터링하는 함수다.

    .map(function(value, index) { ... })
    지정된 함수가 반환하는 값으로 구성된 새로운 배열을 반환한다.
    map 메소드의 콜백함수는 배열의 값을 다른 형태로 변환하는 함수다.

    필터는 걸러내는 것이고 맵은 바꾸는 것이다.

    -> 위의 배열을 바탕으로 새로운 배열을 반환한다.

    filter와 map을 사용해서 배열에서 내가 원하는 값을 가공할 수 있다.

    .reduce(function(total, currentValue, currentIndex))
    지정된 함수가 반환하는 값의 총합계를 반환한다.
    reduce 메소드의 콜백함수는 배열의 값에 대한 합계를 반환한다.

    빅데이터 hadoop에서도 map과 reduce가 사용된다.

    @RequestBody는 요청메시지의 body에 들어있는 것을 넣으라는 의미이다. 쿼리스트링 형식일 때는 안붙임.

    json타입의 텍스트를 자바 객체로 바꿔주는 것임.  

    RequestBody를 쓸 일은 별로 없다. Rest라는걸 쓸 때는 쓸 수 있음.

    @RequestBody는 요청메시지의 바디부를 요청핸들러메소드의 매개변수에 매핑시키는 것이고, 

    @ResponseBody는 요청핸들러메소드의 반환값을 응답메시지의 바디부와 매핑시켜서 json형식의 응답을 보내는 것임.

     

    JSON 형식의 데이터로 응답을 받는 이유는 JSON형식의 텍스트는 json.parse를 사용해 자바스크립트의 객체나 배열로 아주 쉽게 바꿀 수 있기 때문이다. 점(.) 찍어서 꺼내기만 하면 된다.

    댓글

Designed by Tistory.