API

Sunny·2022년 6월 7일
0

✨ 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술


🔅 목차


✅스프링 웹 개발 기초

#1 정적 컨텐츠
#2 MVC와 템플릿 엔진
#3 API


🔅 API 실습

📌 HelloController.java (1)

  • 경로 : /src/main/java/hello.hellospring.controller.HelloController.java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {

    @GetMapping("hello-string")
    @ResponseBody
    public String helloString(@RequestParam("name") String name) {
  		
        // View가 없고 데이터가 그대로 넘어간다
        return "Hello. My name is " + name; 
    }
    
}

📌 HelloController.java (1) 결과

📌 HelloController.java(1) 소스 설명

  1. @Controller
  • 클래스를 Spring MVC 컨트롤러로 표시하는데 사용
  • View에 표시될 데이터가 있는 Model 객체를 만들고, 올바른 View를 선택하는 일을 담당
  1. @GetMapping
  • @GetMapping 어노테이션은 HTTP GET 요청을 처리하는 메서드를 맵핑(@RequestMapping)하는 어노테이션으로, 주어진 URL 표현식과 일치하는 HTTP GET 요청을 처리
	http://localhost:8080/hello-string?name=sunny
	@GetMapping("hello-string")
  • 위와 같이 웹 어플리케이션에서 /hello-string 이라고 들어오면 @GetMapping("hello-string")을 보고 해당 메소드로 이동
  1. @ResponseBody
  • HTTP에서 응답 Body 부에 직접 데이터를 넣어주겠다는 의미
  • View가 없어도 데이터가 그대로 넘어감

📌 HelloController.java (2)

  • 경로 : /src/main/java/hello.hellospring.controller.HelloController.java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {

    @GetMapping("hello-api")
    @ResponseBody	
    public Hello helloApi(@RequestParam("name") String name) {
       
        Hello hello = new Hello();  // 객체 만들기
        hello.setName(name);
        
        return hello; // 객체 반환
    }

    // 객체 만들기
    static class Hello {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
    
}

📌 HelloController.java (2) 결과

  • JSON 방식으로 결과가 출력

📌 @ResponseBody 동작 원리

  1. 웹 브라우저에서 url 전송 (http://localhost:8080/hello-api)
  2. 내장 톰캣 서버가 이를 인식하고 스프링에게 전송
  3. 스프링은 /hello-api를 보고 해당 메소드에 매칭
  4. 스프링은 @ResponseBody를 보고 HTTP의 Body에 문자를 직접 반환함
    • 'viewResolver' 대신에 'HttpMessageConverter'가 동작
    • 반환하는 것이 문자이면 StringHttpMessageConverter가 동작
    • 반환하는 것이 객체이면 MappingJackson2HttpMessageConverter가 동작

🔅 @ResponseBody를 이해하기 위한 사전지식

📌 클라이언트와 서버의 비동기 통신

  • 요청(request) 메세지 : 클라이언트에서 서버로 통신하는 메세지
  • 응답(response) 메세지 : 서버에서 클라이언트로 통신하는 메세지
  • 웹에서 화면전환(새로고침) 없이 이루어지는 동작들은 대부분 비동기 통신으로 이루어짐
  • 비동기통신을 하기 위해서는 클라이언트에서 서버로 요청 메세지를 보낼 때, 본문에 데이터를 담아 보내야하고, 서버에서 클라이언트로 응답을 보낼 때에도 본문에 데이터를 담아서 보내야 함. 이 본문이 바로 body 이다.
  • 요청 본문 : requestBody / 응답 본문 : responseBody

📌 본문에 담겨야 하는 데이터의 형식, JSON(JavaScript Object Notation)

"속성-값" (attribute-value) 쌍 또는 "키-값" (key-value) 쌍으로 이루어진 데이터 오브젝트를 전달하기 위해 인간이 읽을 수 있는 텍스트를 사용하는 개방형 표준 포맷. 비동기 브라우저/서버 통신(AJAX)을 위해, 넓게는 XML(AJAX가 사용)을 대체하는 주요 데이터 포맷. 특히, 인터넷에서 자료를 주고 받을 때 그 자료를 표현하는 방법으로 알려져 있음.


📌 요청 본문에 담긴 값을 자바 객체로 Conversion

@RequestBody를 통해서 자바 객체로 conversion을 할 때 그냥 변환되는 것이 아니라 HttpMessageConverter를 사용하는데 아래의 메서드에 각종 메시지 컨버터가 설정되어 있음

WebMvcConfigurationSupport.addDefaultHttpMessageConverters

만약 요청이 JSON으로 들어 온 경우, 요청 헤더(request header)에 컨텐츠 타입(Content-Type)을 알려줘야 함. 헤더에 있는 컨텐츠 타입을 보고 HttpMessageConverter가 어떤 메시지 컨버터를 사용할 것인지 판단하여 요청 본문에 담긴 값을 자바 객체로 변환. JSON을 컨버팅 할 수 있는 컨버터는 Jackson2ObjectMapperBuilder.

Jackson2ObjectMapperBuilder 는 스프링부트에서 JacksonAutoConfiguration 클래스에서자동으로 설정하기 때문에 별다른 설정없이 JSON을 자바 객체로변환하는 ObjectMapper를 사용할 수 있음.

Jackson2ObjectMapperBuilder 내부를 보면 autoDetectGettersSetters() 라는 메서드를 사용합니다. 즉, JSON 타입으로 변환하기 위한 객체(DTO)에 getter 와 setter 메서드가 존재해야 하다는 뜻.

만약 getter/setter 가 존재하지 않으면 응답 메시지를 내보낼때 Jackson2ObjectMapperBuilder 를 제대로 사용하지 못해서 JSON 타입으로 변환이 제대로 되지않아 클라이언트(JS) 단에서 success() 함수로 결과값(res) 를 받아올 수 없음.

스프링부트의 pom.xml 을 보면 spring-boot-starter-web 이 존재하는데 내부에 들어가보면 jackson-databind 의존성이 자동으로 잡혀있는 것을 볼 수 있습니다. 해당 의존성이 있어야 JSON 타입으로 제대로 변환이 됨.


📌 @RequestBody

  • HTTP 요청 본문에 담긴 값들을 자바 객체로 변환 시켜, 객체에 저장

📌 @ResponseBody

  • 자바 객체를 HTTP 응답 본문의 객체로 변환하여 클라이언트로 전송

📌 @RequestBody / @ResponseBody 정리

클라이언트에서 서버로 필요한 데이터를 요청하기 위해 JSON 데이터를 요청 본문에 담아서 서버로 보내면, 서버에서는 @RequestBody 어노테이션을 사용하여 HTTP 요청 본문에 담긴 값들을 자바객체로 변환시켜, 객체에 저장.

서버에서 클라이언트로 응답 데이터를 전송하기 위해 @ResponseBody 어노테이션을 사용하여 자바 객체를 HTTP 응답 본문의 객체로 변환하여 클라이언트로 전송.

출처: https://cheershennah.tistory.com/179 [Today I Learned. @cheers_hena 치얼스헤나]

출처 :
1. https://cheershennah.tistory.com/179
2. https://medium.com/webeveloper/reqeustbody%EC%99%80-responsebody-%EC%96%B8%EC%A0%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C-2efcab364edb


profile
개발에 재미를 붙여보기 :)

0개의 댓글