Spring MyBatis (6) REST api와 AJAX

강서진·2024년 2월 5일
0

Spring

목록 보기
17/18
post-custom-banner

2번째 필수강의 pt.4 9강 요약

JSON

JSON (Java Script Object Notation)
: 자바스크립트 객체 표기법

stringify()
: JS 객체를 서버로 전송하기 위해 필요한 직렬화(=from data to 문자열 변환) 과정. HTTP는 요청과 응답을 전부 텍스트로 주고받기 때문에 직렬화 과정이 필요하다.

parse()
: 역직렬화로, 서버가 보낸 데이터(=JSON 문자열)를 JS객체로 변환할 때 사용한다.

JS 에서 객체를 생성하는 데에는 생성자로 만드는 방법과 자바에서 배열을 만들듯이 리터럴로 생성하는 방법 두 가지가 있다.

let obj = {}
----
let obj2 = new Object();

JS에는 상속이라는 개념이 없는 대신 Prototype이라는 객체를 참조하게 해 상속과 비슷한 효과를 낸다. 또, JS는 동적으로 프로퍼티를 추가해줄 수도 있다.

obj = { name:"abc", age:10 }
obj.hp="010-1234-1234" // -> obj에 hp 추가됨

JS 상에서 stringify를 사용하면 JSON 객체를 문자열로 바꿀 수 있다. 반대로 문자열에 parse를 쓰면 다시 JSON 객체로 변환된다.

let strObj = JSON.stringify(obj); // '{ "name":"abc", "age":"10", "hp":"010-1234-1234" }'
---
let obj2 = JSON.parse(strObj); // { name:'abc', age:10, hp:'010-1234-1234' }

AJAX

AJAX (Asynchronous Javascript And XML)
: JS와 XML을 이용해 비동기 통신으로 데이터를 주고 받기 위한 기술

동기 방식은 클라이언트에서 요청을 보내면 서버에서 처리하고 응답을 받을 때까지 대기해야 한다. 반대로 비동기 방식은 클라이언트가 요청을 해놓고 응답이 오기를 기다리지 않고, 응답이 오지 않았는데 요청을 또 보내거나 할 수 있다. 브라우저에서 탭 하나는 싱글 스레드이지만 브라우저는 멀티 스레드인 것처럼, 동기 방식은 탭 하나, 비동기 방식은 브라우저라고 생각하면 된다.
다만, 비동기 방식은 처리가 언제 끝났는지 알 수가 없어 콜백함수로 처리가 끝났다는 것을 알려주어야 한다.

옛날에는 xml 문서를 많이 사용했으나, 이제는 JSON을 더 많이 사용하고 있다. AJAX를 사용하면 웹페이지 전체(data+UI)가 아닌 일부 data만 업데이트가 가능하다.
MyBatis로 만들었던 게시판 프로젝트에서 댓글이 달리면 이를 갱신하는 데 사용하게 된다.

jQuery 없이 자바 스크립트만으로도 AJAX를 사용할 수 있지만 사용하는 편이 간편하기 때문에 주로 사용하게 된다.

Controller 패키지에 SimpleRestController 클래스를 만들고, domain 패키지에 ajax 를 사용해서 받아올 Person 클래스를 만든다. JS에서 만들었던 것처럼 name, age를 만들고 getter, setter, 생성자를 만들어준다.

ajax를 사용해보기 위해 ajax.jsp를 작성하고, ajax에 사용할 url을 맵핑해줄 SimpleRestController를 만든다.

ajax.jsp
---
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="https://code.jquery.com/jquery-1.11.3.js"></script>
</head>
<body>
    <h2>{name:"abc", age:10}</h2>
    <button id="sendBtn" type="button">SEND</button>
    <h2>Data From Server :</h2>
    <div id="data"></div>
    <script>
        $(document).ready(function(){
            let person = {name:"abc", age:10};
            let person2 = {};

            $("#sendBtn").click(function(){
                $.ajax({
                    type:'POST',       // 요청 메서드
                    url: '/ch4/send',  // 요청 URI
                    headers : { "content-type": "application/json"}, // 요청 헤더
                    dataType : 'text', // 전송받을 데이터의 타입
                    data : JSON.stringify(person),  // 서버로 전송할 데이터. stringify()로 직렬화 필요.
                    success : function(result){
                        person2 = JSON.parse(result);    // 서버로부터 응답이 도착하면 호출될 함수
                        alert("received="+result);       // result는 서버가 전송한 데이터
                        $("#data").html("name="+person2.name+", age="+person2.age);
                    },
                    error   : function(){ alert("error") } // 에러가 발생했을 때, 호출될 함수
                }); // $.ajax()

                alert("the request is sent")
            });
        });
    </script>
</body>
</html>
  • SEND 버튼을 누르면 아래 script 태그 안 #sendBtn 함수가 실행된다.
  • { name: "abc", age: 10 } 이라는 JSON을 POST 방식으로 /ch4/send로 보낸다. 이 때 이 JSON은 stringify로 직렬화하여 서버로 보내진다.
  • 콜백 함수로, 실행이 성공한 경우에는 success의 함수가 실행된다. 역시 String으로 된 result를 받아 parse 하여 역직렬화한 후 이를 화면에 출력한다.
  • 실행에 실패한 경우에는 error 부분의 함수가 실행되어, error 라는 메시지의 팝업창이 뜬다.
@Controller
public class SimpleRestController {
  @GetMapping("/ajax")
  public String ajax() {
    return "ajax";
  }

  @PostMapping("/send")
  @ResponseBody
  public Person test(@RequestBody Person p) {
    System.out.println("p = " + p);
    p.setName("ABC");
    p.setAge(p.getAge() + 10);

    return p;
  }
}
  • /ajax url은 GET 요청을 받아 "ajax.jsp" 뷰를 띄운다.
  • /send는 POST 요청으로 Person 객체를 받고, 이 Person 객체의 나이에 10을 더한 후 다시 이 객체를 응답에 실어 보낸다.

다음으로 해당 의존성을 추가한다.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.14.2</version>
</dependency>

@RequestBody와 @ResponseBody 애너테이션이 붙어있기 때문에 request에 담겨오는 JSON 문자열을 받아올 수 있고, 마찬가지로 response에 Java 객체를 담아보낼 수 있다. 이 jackson-databind는 문자열을 자바객체로 변환하여 SimpleRestController에 매개변수로 넘겨주는 역할을 한다.

의존성을 추가한 후 서버를 켜서 실행해보면 다음과 같이 잘 작동하는 것을 확인할 수 있다. 또, 반대로 Java 객체를 JSON 문자열로 바꿔주는 역할도 한다.

@RestController 애너테이션을 사용하면 @ResponseBody를 매번 붙여줄 필요 없이 객체를 반환할 때 JSON을 실어 보낼 수 있도록 해준다.


REST

  • 2000년에 Roy Fielding이 제안한 웹 서비스 디자인 아키텍쳐 접근 방식
  • 프로토콜에 독립적이며, 주로 HTTP를 사용해 구현(=HTTP가 아니어도 구현할 수 있다)
  • 리소스 중심의 API 디자인: HTTP 메서드로 수행할 작업을 정의
  • 하나의 리소스(=url)에 요청을 보내는 메서드에 따라 수행하는 작업이 달라짐 -> 유지보수 편리, 가독성
  • 리소스는 명사, 메서드는 동사로 수행할 작업을 정의

REST API

Representational State Transfer API
: REST 규약을 준수하는 API

REST 규약을 따르는 것에 장점이 있는 것도 맞지만, 상황과 서비스의 목적, 그리고 사용자의 편의성 역시도 고려해야 한다.

post-custom-banner

0개의 댓글