본문 바로가기
Spring/Spring

[Spring] @ResponseBody, @RequestBody와 Ajax, JSON

오늘은 여러 어노테이션 중 @ResponseBody와 @RequestBody에 대해서 알아보고자 합니다. 이 두개의 어노테이션은 가장 대표적인 @Service, @Controller와 같은 대장급(?) 어노테이션을 제외한다면 가장 많이 사용하는 어노테이션이고 또 사용하는 방법도 무척이나 간단하여 한 번 알아두고 기억하고 있는다면 웹 개발에 있어서 많은 도움이 되리라 생각합니다.

 

우선 이 두개의 어노테이션의 공통 접점은 JSON이라는 데이터 타입입니다. JAVA에서는 JSON이라는 데이터 타입이 없기 때문에 프론트단에서 자바에게 JSON타입의 데이터를 전달해주거나 혹은 반대로 JAVA의 객체데이터를 JSON형태로 프론트단에 전달해야 하는 경우 각각 @RequestBody와 @ResponseBody가 그 역할을 해주고 있습니다.

 

 

 

 

 

라이브러리 추가

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

앞서 이야기 했던것처럼 JAVA에는 JSON이라는 데이터 타입이 없습니다. 따라서 JSON데이터에 대한 처리를 하는 라이브러리를 추가해야만 하는데 대표적으로 Jackson, Gson, SimpleJSON과 같은 라이브러리가 있고 개인적으로는 Jackson라이브러리를 추천드리고 싶습니다. 그 이유는 대용량데이터를 처리하는 경우 가장 빠른 속도을 보여주었으며 스프링부트에서 공식적으로 사용하고 있기 때문입니다.

 

 

 

 

 

JSP에서 Controller로 JSON데이터 전달

<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<button onclick="ajaxTest()">test</button>

<script>

function ajaxTest() {
	
var json = {"id" : "아이디", "pw" : "1234"};
	
    $.ajax({
        url: "ajaxTest.do",
        type:"post",
        data: JSON.stringify(json),
        contentType: "application/json",
        success: function(data) {
            alert("통신성공");
        },
        error: function() {
            alert("error");
        }
    })
}

</script>

JSP페이지에서 Ajax를 통해 컨트롤러로 JSON데이터를 보내는 코드입니다. 객체를 전달하기 때문에 당연히 전송방식은 'POST'로 하며 여기서 추가적으로 주의해야 할 점은 ajax의 contentType속성과 data 속성입니다.

 

 

var json = {"id" : "아이디", "pw" : "1234"};
data: JSON.stringify(json)

멀쩡한 json데이터를 JSON.stringify를 이용하여 String으로 형변환을 하고 있습니다. 당연히 컨트롤러는 String타입의 데이터를 받게 되며 이때 전달한 String데이터는 JSON형태로 이루어진 데이터임을 알려주기위하여 contentType 속성값을 "application/json"로 지정하는 것입니다.

 

 

@RequestMapping(value = "/ajaxTest.do")
public String ajaxTest(@RequestBody UserVO getUserVO) throws Exception {

  System.out.println(getUserVO.getId());
  
  return "test/login.tiles";
}



@RequestMapping(value = "/ajaxTest.do")
public String ajaxTest(@RequestBody HashMap<String, String> map) throws Exception {

  System.out.println(map.get("id"));
  
  return "test/login.tiles";
}

컨트롤러 부분입니다. @RequestBody를 통해 사전에 만들어둔 UserVO를 통해서 데이터를 받고 정상적으로 데이터가 파싱되었는지 System.out.println으로 확인해 보니 정상적으로 데이터가 들어 옵니다.

 

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<button onclick="ajaxTest()">test</button>

<script>

function ajaxTest() {

  var json = {"id" : "아이디", "pw" : "1234"};

  $.ajax({
    url: "ajaxTest.do",
    type:"post",
    data: json,
    success: function(data) {
    	alert(data.address1);
    },
    error: function() {
    	alert("error");
    }
  })
}

</script>

그런데 여기서 신기하게도... 요즘 나온 스프링버전(저는 5.xx버전대에서 테스트 했습니다)에서는 json을 String으로 파싱할필요도 없고 contentType도 지정을 안해줘도 정상적으로 동작하는 것을 확인했습니다 ㄷㄷㄷ...

 

 

@RequestMapping(value = "/ajaxTest.do")
public String ajaxTest(UserVO getUserVO) throws Exception {

  System.out.println(getUserVO.getId());
  
  return "test/login.tiles";
}

심지어 컨트롤러에서는 @RequestBody를 사용하지 않아도 정상적으로 맵핑되어 데이터가 입려되더군요... 그렇다면 사실상 최신버전의 Spring에서는 @RequestBody를 사용할 이유가 없어진것 같습니다. 다만 VO가 아니라 Map으로 받고싶다면 @RequestBody를 사용해야 합니다.

 

 

 

 

 

Countroller에서 JSP로 JSON데이터 전달

$.ajax({
  url : "ajaxTest.do",
  type : "post",
  success : function(data) {
  	alert(data.id);
  },
  error : function() {
  	alert("error");
  }
})

이번에는 반대로 @ResponseBody어노테이션을 이용하여 컨트롤러에서 JSP로 JSON데이터를 전달해 보도록 하겠습니다.  컨트롤러를 호출하는 Ajax를 간단하게 만들어 봤습니다.

 

 

@ResponseBody
@RequestMapping(value = "/ajaxTest.do")
public UserVO ajaxTest() throws Exception {

  UserVO userVO = new UserVO();
  userVO.setId("아이디테스트");

  return userVO;
}

컨트롤러 부분입니다 특별한 설정없이 @ResponseBody어노테이션을 추가해줬고 리턴타입으로 VO만을 지정해줬는데 JSON타입으로  데이터가 파싱되어 전달되는 것을 확인할 수 있습니다.

 

 

@ResponseBody
@RequestMapping(value = "/ajaxTest.do")
public HashMap<String, String> ajaxTest() throws Exception {

  HashMap<String, String> map = new HashMap<String, String>();
  map.put("id", "testId");

  return map;
}

물론 hashmap으로도 JSON타입으로 데이터 전달이 가능합니다.

 

 

 

 

 

 

 

@ResponseBody 없이 컨트롤러에서 JSP로 JSON데이터 전달하기

@RequestMapping(value = "/ajaxTest.do")
public void ajaxTest(HttpServletResponse response) throws Exception {

  HashMap<String, String> map = new HashMap<String, String>();
  map.put("id", "아이디");

  response.setContentType("application/json");
  response.setCharacterEncoding("UTF-8");
  //new ObjectMapper().writeValueAsString(map) -> map데이터를 JSON형태의 데이터로 파싱
  response.getWriter().write(new ObjectMapper().writeValueAsString(map));
}

추가적으로 @ResponsBody가 없다면 어떻게 JSON타입의 데이터를 전달하는지 한번 샘플로 컨트롤러를 만들어 보았습니다.

댓글