[Spring] 스프링 입문 (3)

이병수·2024년 1월 19일
0

스프링 정리

목록 보기
3/24
post-thumbnail

스프링 입문 (3)


데이터를 Client에 반환하는 방법

Response

업로드중..

클라이언트가 서버에게 요청하는 것을 Request라 하면 서버가 그에 대한 응답을 Response라고한다.

Response 응답 데이터에는 HTML 응답도 있고 JSON 형태로 응답을 해주기도 한다.

  • 요즘은 JSON형태로 응답을 하면 프론트엔드 쪽에서 해당 JSON 데이터를 가지고 활용하기 때문에 백엔드는 JSON 형태로 데이터를 보통 반환한다.

자바 문자열 -> JSON으로 변환

@GetMapping("/response/json/data")
@ResponseBody
public String getJsonData() {
	return "{\"name\":\"Robbie\",\"age\":95}";
}

이런 식으로 json 형식을 만들어서 문자 그대로 반환을 하거나

자바 객체 -> JSON으로 변환하는 방법인

@GetMapping("/response/json/data")
@ResponseBody
public Star getJsonData() {
	return new Star("Robbie", 95);

이런 식으로 변환을 해서 보내주게 된다면

{"name":"Robbie", "age":95} 

이런식의 JSON 형태로 반환을 하게 된다.


추가적인 참고 사항

@Controller 어노테이션 + @ResponseBody 어노테이션을 사용하게 된다면

해당 모든 메서드가 @ResponseBody이 추가되는 효과를 볼 수 있다.

@Controller
@RequestMapping("/api")
public class Test {
	
    @GetMapping("/test")
    @ResponseBody
    public String getName() {
    	return ..;
    }
}
  • @Controller 어노테이션을 사용하게 되면 @ResponseBody 어노테이션이 없는 메서드라면, String으로 반환하는 값이 templates 폴더 안의 해당 return 값의 html 파일 이름을 찾게 된다.

  • 하지만 @ResponseBody 어노테이션을 사용한다면 templates 폴더를 찾는 것이 아닌, 해당 반환 값 그대로 메시지 바디에 올려 데이터를 보낸다.

@RestController
@RequestMapping("/api")
public class Test {
	
    @GetMapping("/test")
    public String getName() {
    	return ..;
    }
}
  • @RestController를 사용하면 위의 코드와 똑같이 동작을 하며, 모든 메서드들이 다 @ResponseBody 어노테이션 효과를 받는다.


Jackson이란 무엇일까?

  • Jackson은 JSON 데이터 구조를 처리해주는 라이브러리이다.

  • Object를 JSON 타입의 String으로 변환할 수 있으며 JSON타입을 String으로 변환해줄 수 있다.

  • 스프링 3.0 버전 이후부터 Jackson과 관련된 API를 제공한다.

  • 직접 JSON 데이터를 처리해야할 때는 Jackson 라이브러리의 ObjectMapper를 사용한다.


ObjectMapper objectMapper = new ObjectMapper();

String text = objectMapper.writeValueString(??);

ObjectMapper를 통해 Object 타입을 JSON타입으로 writeValueString() 메서드를 이용하여 변환할 수 있다.


String json = "{\"name\":\"Robbie\",\"age\":95}";

ObjectMapper objectMapper = new ObjectMapper();

Star star = objectMapper.readValue(json, Star.class);

System.out.println("star.getName() = " + star.getName());

ObjectMapper 안의 readValue 메서드를 통해 JSON 타입의 내용을 Object 타입으로 변환할 수 있다.

예시에서는 Star 클래스 타입의 내용 그대로 만들어주었다.

readValue 메서드의 첫 번째 파라미터는 JSON 타입의 String을, 두 번째 파라미터에는 변환할 Object의 class 타입을 주면 된다.

주의 : JSON 타입의 String을 Object로 변환하기 위해서는 해당 Object에 기본 생성자와 getter나 setter 메서드가 필요하다.



PathVariable 과 RequestParam


클라이언트에서 서버로 HTTP 요청을 보낼 때, 데이터와 함께 보낼 수 있다.

PathVariable

PathVariable 같은 경우에 이러한 방식으로 데이터를 URL 경로에 추가할 수 있다.

GET http://localhost:8080/hello/request/star/Robbie/age/95
  • 즉, /star/Robbie/age/95 처럼, Robbie와 95 데이터를 서버에 보내주기 위해 URL 경로에 추가했다.
@GetMapping("/star/{name}/age/{age}")
@ResponseBody
public String test(@PathVariable("name") String name, @PathVariable("age") int age) {
	return ...;
}
  • 이런식으로 데이터를 받기 위해 @GetMapping 어노테이션을 사용하여 해당 URL 경로를 받고 데이터 위치 경로에는 { } 중괄호를 사용해준다.

  • @PathVariable 어노테이션과 함께 해당 { } 중괄호에 선언한 변수명과 변수타입을 선언하면 데이터를 받을 수 있다.


RequestParam

PathVariable과는 다르게 들어오는 데이터 방식이 다르다.

GET http://localhost:8080/hello/request/form/param?name=Robbie&age=95

URL 경로 마지막에 ? 을 통해 쿼리문처럼 들어올 수 있으며 &를 통해 추가적인 데이터를 보낼 수 있다.

@GetMapping("/form/param")
@ResponseBody
public String test(@RequestParam("name") String name, @RequestParam("age") int age) {
    return String.format("name = %s, age = %d", name, age);
}
  • 이런식으로 ?name=Robbie&age=95 에서 key 부분에 선언한 name과 age를 사용해서 value에 선언된 Robbie와 95 데이터를 받아올 수 있다.

@RequestParam(required = false) 이렇게 설정하면 해당 값이 포함하지 않아도 오류가 발생하지 않는다.
다만, default 값이 true이기 때문에 없으면 오류가 발생한다.
@PathVariable 또한 해당 옵션이 가능하며 , 전달 받지 못한 해당 변수의 값은 null로 초기화 된다.



HTTP 데이터를 객체로 처리하는 방법

ModelAttribute

// [Request sample]
// POST http://localhost:8080/hello/request/form/model
// Header
//  Content type: application/x-www-form-urlencoded
// Body
//  name=Robbie&age=95

// @ModelAttribute 애노테이션을 사용하면 @Post방식으로 들어오는 메세지 바디 부분의 내용을
// 쿼리 스트링 방식의 데이터를 객체에 매핑해서 가지고 올 수 있다.

@PostMapping("/form/model")
@ResponseBody
public String helloRequestBodyForm(@ModelAttribute Star star) {
    return String.format("Hello, @ModelAttribute.<br> (name = %s, age = %d) ", star.getName(), star.getAge());
}

@ModelAttribute 어노테이션을 사용하게 된다면 해당 HTTP Body에 담겨져 오는 데이터를 Java의 객체 형태로 받아와서 사용할 수 있게 된다.

예시에서는 Java의 Star 객체에 해당 데이터들이 담겨지게 된다.

물론, Star 객체 안에는 name , age 에 대한 필드가 존재한다.


  • @ModelAttribute를 통해서 데이터가 한개 뿐만 아니라 여러개의 데이터를 보내게 될 경우 @RequestParam 에노테이션만 사용하기에는 힘들기 때문에, 객체 데이터로 받아오면 된다.

다만 주의할 점은 해당 데이터를 담을 객체의 오버로딩 된 생성자 혹은 Setter 메서드를 통해 값이 담겨지게 된다

참고!

@ModelAttribute 은 생략이 가능하다.
다만 @RequestParam 도 생략이 가능하다.

따라서 이 두 어노테이션을 구분하는 방법은 Spring에서는 해당 파라미터(매개변수)가 SimpleValueType 인 원시타입(int), Wrapper 타입(Integer), Date 등의 타입이라면 @RequestParam으로 간주하고 아니라면 @ModelAttribute로 판단하게 된다.

profile
백엔드 개발자가 되고 싶어요

0개의 댓글