클라이언트가 서버에게 요청하는 것을 Request라 하면 서버가 그에 대한 응답을 Response라고한다.
Response 응답 데이터에는 HTML 응답도 있고 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 ..;
}
}
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 메서드가 필요하다.
클라이언트에서 서버로 HTTP 요청을 보낼 때, 데이터와 함께 보낼 수 있다.
PathVariable 같은 경우에 이러한 방식으로 데이터를 URL 경로에 추가할 수 있다.
GET http://localhost:8080/hello/request/star/Robbie/age/95
@GetMapping("/star/{name}/age/{age}")
@ResponseBody
public String test(@PathVariable("name") String name, @PathVariable("age") int age) {
return ...;
}
이런식으로 데이터를 받기 위해 @GetMapping 어노테이션을 사용하여 해당 URL 경로를 받고 데이터 위치 경로에는 { } 중괄호를 사용해준다.
@PathVariable 어노테이션과 함께 해당 { } 중괄호에 선언한 변수명과 변수타입을 선언하면 데이터를 받을 수 있다.
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);
}
@RequestParam(required = false) 이렇게 설정하면 해당 값이 포함하지 않아도 오류가 발생하지 않는다.
다만, default 값이 true이기 때문에 없으면 오류가 발생한다.
@PathVariable 또한 해당 옵션이 가능하며 , 전달 받지 못한 해당 변수의 값은 null로 초기화 된다.
// [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 에 대한 필드가 존재한다.
다만 주의할 점은 해당 데이터를 담을 객체의 오버로딩 된 생성자 혹은 Setter 메서드를 통해 값이 담겨지게 된다
@ModelAttribute 은 생략이 가능하다.
다만 @RequestParam 도 생략이 가능하다.따라서 이 두 어노테이션을 구분하는 방법은 Spring에서는 해당 파라미터(매개변수)가 SimpleValueType 인 원시타입(int), Wrapper 타입(Integer), Date 등의 타입이라면 @RequestParam으로 간주하고 아니라면 @ModelAttribute로 판단하게 된다.