본문 바로가기
Spring

[Spring] @RequestBody, @ResponseBody로 JSON 전송하기

by Amy IT 2022. 9. 9.

 

목차

     

    클라이언트에서 서버로 HTTP 요청(Request) 메시지를 보내면 서버에서는 클라이언트로 HTTP 응답(Response) 메시지를 보냅니다. HTTP Request와 Response 메시지에는 body, 즉 본문이 존재하는데요, 스프링이 제공하는 @RequestBody, @ResponseBody 어노테이션을 이용하면 body에 JSON 데이터를 담아 데이터를 손쉽게 주고 받을 수 있습니다.

     

    라이브러리 추가

    자바에서 JSON 데이터에 대한 처리를 하기 위해 라이브러리를 추가합니다. 대표적으로 Jackson, Gson, SimpleJSON 등의 라이브러리가 있는데, 저는 Jackson 라이브러리를 사용하겠습니다. 

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.13.4</version>
    </dependency>

     

    @RequestBody

    @RequestBody 어노테이션을 컨트롤러 메소드의 파라미터로 설정하면, HttpMessageConverter가 HTTP Request body를 읽고 이를 역직렬화(deserialization)하여 자바 객체로 변환해 줍니다. 이때 @RequestBody로 선언한 파라미터 타입과 클라이언트에서 보낸 데이터가 일치해야 합니다.

     

    서버측에 ajax 비동기로 JSON 데이터를 전송한 후,  200 상태값과 함께 전송했던 데이터를 문자열로 응답받아 출력해 보겠습니다. 전송할 데이터를 JSON 객체로 작성한 후 문자열로 변환하여 전송하되, 해당 데이터가 JSON 형태임을 알려주기 위해 Content-Type을 application/json으로 지정합니다.

    <button id="aaa">aaa</button><br>
    
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script type="text/javascript">
    	$(function () {
    		$('#aaa').on('click', function () {
    			$.ajax({
    				url:'aaa',
    				type:'post',  //post방식전송 - request의 body부분에 데이터가 전달됨
    				dataType:'text',  //응답 데이터 타입
    				headers: {
    					"Content-Type":"application/json"  //전달하는 데이터가 JSON형태임을 알려줌
    				},
    				data: JSON.stringify( {'userid':'amy', 'passwd':'1234'} ),  //String으로 변환하여 전달 (JSON.stringify: JSON->String / JSON.parse: String->JSON)
    				success: function (data, status, xhr) {
    					console.log(data)
    				},
    				error: function (xhr, status, error) {
    					console.log(error)
    				}
    			})
    		})
    	})
    </script>
    @RequestMapping("/aaa")
    public ResponseEntity<String> aaa(@RequestBody LoginDTO login) {
    	String info = login.getUserid()+" "+login.getPasswd();
    	return ResponseEntity.status(HttpStatus.OK).body(info);
    }

    @RequestBody 어노테이션을 통해 요청 본문에 담긴 JSON 데이터를 자동으로 파싱하여 해당하는 DTO클래스로 담아주는 것을 확인할 수 있습니다.

     

    JSON 객체의 배열로 데이터를 전송하면 자동으로 데이터를 파싱하여 List에 담아줍니다. 

    <button id="aaa2">aaa2</button><br>
    
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script type="text/javascript">
    	$(function () {
    		$('#aaa2').on('click', function () {
    			let json1 = {'userid':'amy', 'passwd':'1234'}
    			let json2 = {'userid':'jack', 'passwd':'5678'}
    			$.ajax({
    				url:'aaa2',
    				type:'post',  //post방식전송 - request의 body부분에 데이터가 전달됨
    				dataType:'text',  //응답 데이터 타입
    				headers: {
    					"Content-Type":"application/json"  //전달하는 데이터가 JSON형태임을 알려줌
    				},
    				data: JSON.stringify([json1, json2]),  //JSON의 배열을 문자열로 변형시켜서 전송 
    				success: function (data, status, xhr) {
    					console.log(data)
    				},
    				error: function (xhr, status, error) {
    					console.log(error)
    				}
    			})
    		})
    	})
    </script>
    @RequestMapping("/aaa2")
    public ResponseEntity<Integer> aaa2(@RequestBody ArrayList<LoginDTO> list) {
    	return ResponseEntity.status(HttpStatus.OK).body(list.size());
    }

     

     

    @ResponseBody

    @ResponseBody 어노테이션을 메소드 레벨이나 메소드의 리턴 타입으로 붙이면, 메소드가 리턴하는 값을 HttpMessageConverter를 통해 Response body로 직렬화(serialization)하게 됩니다.

     

    이번에는 서버측으로부터 JSON 데이터를 응답받아 보겠습니다. 응답받는 데이터의 타입을 json으로 지정합니다.

    <button id="bbb">bbb</button><br>
    
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script type="text/javascript">
    	$(function () {
    		$('#bbb').on('click', function () {
    			$.ajax({
    				url:'bbb',
    				type:'post',  //post방식전송 - request의 body부분에 데이터가 전달됨
    				dataType:'json',  //응답 데이터 타입
    				success: function (data, status, xhr) {
    					console.log(data)
    				},
    				error: function (xhr, status, error) {
    					console.log(error)
    				}
    			})
    		})
    	})
    </script>
    @RequestMapping("/bbb")
    @ResponseBody 
    public LoginDTO bbb() {
    	LoginDTO login = new LoginDTO("amy", "1234");
    	return login;
    }

    자바 객체가 자동으로 JSON 형태로 변환되어 응답된 것을 확인할 수 있습니다.

     

    HashMap을 사용하여 JSON 데이터를 응답받을 수도 있습니다.

    <button id="bbb2">bbb2</button><br>
    
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script type="text/javascript">
    	$(function () {
    		$('#bbb2').on('click', function () {
    			$.ajax({
    				url:'bbb2',
    				type:'post',  //post방식전송 - request의 body부분에 데이터가 전달됨
    				dataType:'json',  //응답 데이터 타입
    				success: function (data, status, xhr) {
    					console.log(data)
    				},
    				error: function (xhr, status, error) {
    					console.log(error)
    				}
    			})
    		})
    	})
    </script>
    @RequestMapping("/bbb2")
    @ResponseBody 
    public HashMap<String, String> bbb2() {
    	HashMap<String, String> map = new HashMap<String, String>();
    	map.put("userid", "amy");
    	map.put("address", "seoul");
    	return map;
    }

     

    마찬가지로 여러 개의 데이터를 List에 담아 JSON으로 응답받을 수도 있습니다.

    <button id="bbb3">bbb3</button><br>
    
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script type="text/javascript">
    	$(function () {
    		$('#bbb3').on('click', function () {
    			$.ajax({
    				url:'bbb3',
    				type:'post',  //post방식전송 - request의 body부분에 데이터가 전달됨
    				dataType:'json',  //응답 데이터 타입
    				success: function (data, status, xhr) {
    					console.log(data)
    				},
    				error: function (xhr, status, error) {
    					console.log(error)
    				}
    			})
    		})
    	})
    </script>
    @RequestMapping("/bbb3")
    @ResponseBody 
    public ArrayList<LoginDTO> bbb3() {
    	ArrayList<LoginDTO> list = new ArrayList<LoginDTO>();
    	list.add(new LoginDTO("amy", "1234"));
    	list.add(new LoginDTO("jack", "5678"));
    	return list;
    }

     

    @RestController 

    스프링 4에서부터는 @Controller 외에 @RestController라는 어노테이션을 추가해서 해당 Controller의 모든 메소드 리턴 타입을 @ResponseBody로 처리한다는 것을 명시할 수 있습니다. 기존에 @Controller와 @ResponseBody 어노테이션을 함께 사용했던 것과 동일한 기능으로서 @ResponseBody 어노테이션을 생략할 수 있게 됩니다.

    @RestController
    public class TestController {
    	@RequestMapping("/bbb")
    	public LoginDTO bbb() {
    		return new LoginDTO("amy", "1234");
    	}
    }

     

     

    @JsonIgnore

    보안상 노출되면 안 되는 데이터의 경우(ex. 비밀번호) 필드에 @JsonIgnore 어노테이션을 붙이면 해당 값을 무시합니다.

    public class LoginDTO {
    	private String userid;
    	@JsonIgnore
    	private String passwd;
        //Constructors, Getters and Setters
    }
    @RestController
    public class TestController {
    	@RequestMapping("/bbb")
    	public LoginDTO bbb() {
    		return new LoginDTO("amy", "1234");
    	}
    }

     

     

    참고

     

    댓글