티스토리 뷰

Spring

[Spring]ResponseEntity

Xion 2020. 3. 11. 23:52

 

ResponseEntity를 배우기 전에 먼저 Controller와 RestController의 차이점을 알고 가보겠습니다.

 

| Spring MVC Controller와 Restful Web Service Controller의 차이점

-가장 큰 차이점은 HTTP Response Body가 생성되는 방식입니다.

 

 

| 기존 MVC Controller

  • view 기술을 사용
  • 주로 view(화면)을 return 합니다.

 

| Restful 웹 서비스 Controller

 

  • 객체를 반환하기만 하면 객체 데이터는 JSON/XML 형식의 HTTP 응답을 직접 작성합니다.
  • Data를  return하는 것이 주 용도입니다.

 

대표적인 Controller 입니다.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
@RequestMapping("/hi/*")
public class Controller {
    @RequestMapping("/hello")
    public String Hello(){
        return "hello";
    }
}

Controller를 통한 view(hello.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
    hello world
</body>
</html>

 

간략한 Spring MVC의 흐름(work Flow)

 

1.client는 URI 형식으로 web service에 요청(request)를 보냅니다.

2.요청(request)는 Handler Mapping과 그 type을 찾는 DispatcherServlet에 의해 인터셉트 됩니다.

3.요청(request)는 Controller에 의해 처리되고 응답은 DispatcherServlet으로 리턴된 후 DispatcherServlet은 View로 디스패치 됩니다.

 

 

Spring MVC WorkFlow는 모델앤 뷰(ModelAndView) 객체가 Controller에서 Client로 전달되는 것을 알 수 있습니다.

단,@ResponseBody 어노테이션을 사용하면 View를 return하지 않고 Controller에서 직접 Data를 return할 수 있습니다.

(Spring 4.0 version 부터는 @RestController 어노테이션을 통해 더 쉽게 사용할 수 있습니다.)

 

 

@ResponseBody

Spring 3.x MVC Restful Web Service Work Flow

 

 

@ResponseBody를 통한 예시

@RequestMapping("/hi/*")
public class hello 
{
    @RequestMapping("/sendVO")
    
    //@ResponseBody <- 메서드 상단 또는 리턴타입 앞에 어노테이션 추가할 수 있습니다.
    public @ResponseBody BoardVO Hello(){
        BoardVO vo = new BoardVO();
        vo.setBno(1);
        vo.setWriter("testuser");
        vo.setContent("testContent");
        vo.setTitle("testtitle");
        vo.setUserName("user");
        
        return vo;
    }
}

 

브라우저 화면

 

 

 

@ResponseBody을 사용하면, Spring은 HTTP 응답에 리턴 값을 자동으로 변환해줍니다.

대신에 컨트롤러 클래스의 각 메서드에 @ResponseBody 어노테이션을 작성해줘야 합니다.

 

 

 

| @RestController

Spring 4.x MVC Restful Web Service Work Flow

RestController(RestController)

 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import com.example.spring02.model.board.dto.BoardVO;
 
@RestController
@RequestMapping("/basic/*")
public class ControllerRest {
    
    // json객체 리턴
    @RequestMapping("/sendVO2")
    public BoardVO sendVO2(){
        BoardVO vo = new BoardVO();
        vo.setBno(1);
        vo.setWriter("DoubleS");
        vo.setContent("게시글 내용입니다");
        vo.setRecnt(1);
        vo.setTitle("게시글 1");
        vo.setUserName("DoubleS");
        return vo;
    }
    
    // json 객체 배열 리턴
    @RequestMapping("/sendList")
    public List<BoardVO> sendList(){
        // ArrayList 객체 생성
        List<BoardVO> items = new ArrayList<>();
        for(int i=1; i <=10; i++){
            BoardVO vo = new BoardVO(); //vo 객체 생성
            vo.setBno(i);
            vo.setWriter("DoubleS"+i);
            vo.setContent("게시글 내용입니다"+i);
            vo.setRecnt(i);
            vo.setTitle("게시글"+i);
            vo.setUserName("DoubleS"+i);
            items.add(vo); // 리스트에 vo추가
        }
        return items; // 리스트를 리턴함
    }
    
    // json객체를 map에 저장하여 
    @RequestMapping("/sendMap")
    public Map<Integer, BoardVO> sendMap(){
        // Map<Key자료형, Value자료형>
        Map<Integer, BoardVO> map = new HashMap<Integer, BoardVO>();
        for(int i=1; i <=10; i++){
            BoardVO vo = new BoardVO(); //vo 객체 생성
            vo.setBno(i);
            vo.setWriter("DoubleS"+i);
            vo.setContent("게시글 내용입니다"+i);
            vo.setRecnt(i);
            vo.setTitle("게시글"+i);
            vo.setUserName("DoubleS"+i);
            map.put(i, vo); // 맵에 vo추가
        }
        return map;
    }
}
 

브라우저 화면

 

 

Spring4.0에서는 @RestController 어노테이션을 선언해주면

 컨트롤러 클래스의 각 메서드마다 @ResponseBody을 추가할 필요가 없어졌고, 모든 메서드는 @ResponseBody 애노테이션이 기본으로 작동이 됩니다.

 

| ResponseEntity

RestController는 별도의 View를 제공하지 않는 형태로 서비스를 실행하기 때문에, 때로는 결과데이터가 예외적인 상황에서 문제가 발생할 수 있습니다.

ResponseEntity는 개발자가 직접 결과 데이터와 HTTP 상태 코드를 직접 제어할 수 있는 클래스로 개발자는 404나 500같은 HTTP 상태 코드를 전송하고 싶은 데이터와 함께 전송할수 있기 때문에 좀더 세밀한 제어가 필요한 경우 사용할 수 있습니다.

// ResponseEntity : 데이터 + http status code
@RequestMapping("/sendMap2")
public ResponseEntity<Map<Integer, BoardVO>> sendMap2(){
    // Map<Key자료형, Value자료형>
    //Map<Integer, BoardVO> map = new HashMap<Integer, BoardVO>();
    Map<Integer, BoardVO> map = new HashMap<Integer, BoardVO>();
    for(int i=1; i <=10; i++){
        BoardVO vo = new BoardVO(); //vo 객체 생성
        vo.setBno(i);
        vo.setWriter("DoubleS"+i);
        vo.setContent("게시글 내용입니다"+i);
        vo.setRecnt(i);
        vo.setTitle("게시글"+i);
        vo.setUserName("DoubleS"+i);
        map.put(i, vo); // 맵에 vo추가
    }
    // 리턴시 map과 상태메시지를 함께 전송
    return new ResponseEntity<>(map, HttpStatus.INTERNAL_SERVER_ERROR);
}
    
@RequestMapping("/sendErrorAuth")
public ResponseEntity<Void> sendListAuth(){
    return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

'Spring' 카테고리의 다른 글

커맨드 객체란?  (0) 2020.07.25
@RequestParam과 @PathVariable?  (0) 2020.07.25
[Spring]@Autowired와 @AllArgsConstructor의 차이  (0) 2020.03.11
[Spring Test]-IntStream의rangeClosed  (0) 2020.03.10
[Spring]- UriComponentsBuilder란?  (0) 2020.03.09