Spring/mvc

[Spring MVC] Controller 리턴 타입

dev_rosieposie 2023. 8. 28. 21:21

시작하기 전 ...

이미 누군가가 만들어 놓은 환경이나 세팅되어 있는 상태에서 '왜'라는 질문 없이 당연하게 받아들이면, 내가 그 상황에 놓여있을 때 정확하게 인지하지 못하면 그건 결국 '알고있다'라고 할 수 없으므로,, 이번 포스팅을 시작한다!!

 

Goal

  1. Spring mvc에서 컨트롤러의 리턴타입에 대해서 알아본다.
  2. Restful에 대해 알아본다.

리턴타입의 종류

  1. String
  2. void
  3. 객체 타입
  4. ResponseEntity
  5. 스프링의 모델 객체
    • ModelAndView vs Model vs ModelMap
  6. Map
  7. View
  8. @ResponseBody

 String 

Spring + View template을 사용할 때 흔히 사용하는 타입

@GetMapping("/test")
public String test(Model model) {
    model.addAttribute("data", data);
    return "/test/data";
}
  • Model 안에 데이터를 key, value 값으로 담고, return 타입을 String 값으로 뷰의 이름을 지정해주면 뷰로 데이터가 전송
  • 뷰에서는 해당 데이터의 key값을 객체 이름으로 하여 그 안에 데이터를 조회
  • 상황에 따라 다른 화면을 보여줄 필요가 있을 때 유용하게 사용
  • 키워드를 붙여 사용 가능
    • redirect : 리다이렉트 방식으로 처리하는 경우
    • forward : 포워드 방식으로 처리하는 경우

 void 

return 타입을 void로 지정하면 일반적으로 해당 URL 정보를 그대로 뷰이름으로 사용함

@GetMapping("/test2")
public void test2(l) {
	log.info("test2");
}
  • 해당 뷰 파일이 없다면 404 NOT FOUND ERROR 발생
  • 이는, servlet-context.xml 파일의 설정과 맞물려 URL경로를 view처리하여 발생
    • <beans:property name="prefix" value="/WEB-INF/views/"/>
    • <beans:property name="suffix" value=".jsp"/>

 객체 타입  

컨트롤러의 메서드 리턴 타입을 VO나 DTO 타입 등 복합적인 데이터가 들어간 객체 타입으로 지정할 수 있는데, 이 경우 주로 JSON 데이터를 만들어내는 용도로 사용

@GetMapping("/test3")
public @ResponseBody SampleDTO test3() {
	log.info("test3");
    SampleDTO dto = new SampleDTO();
    dto.setAge(10);
    dto.setName("홍길동");
    return dto;
}
  • 이를 위해서, pom.xml에 jackson-databind 라이브러리 추가해야함

URL 요청시 결과

{"name":"홍길동", "age":10}

 

 ResponseEntity 

HTTP 프로토콜의 헤더에 세팅이 필요한 경우 사용

@GetMapping("/test4")
public ResposneEntity<String> test4() {
	log.info("test4");
    String msg = "{\"name\": \"홍길동\"};
    
    HttpHeaders header = new HttpHeaders();
    header.add("Content-Type", "application/json;charset=UTF-8);
    
    return new ResposneEntity<>(msg, heaer.HttpStatus.OK);
}
  • ResposneEntity는 HttpHeaders 객체를 같이 전달할 수 있고 이를 통해 HTTP 헤더 메시지를 가공 가능

 스프링 모델 객체  

ModelAndView 

데이터와 이동하고자 하는 view페이지 같이 저장 

@GetMapping("/test5")
public ModelAndView test5() {
    ModelAndView mav = new ModelAndView("test5/viewPage");
    mav.addObject("data", "test5");
    return mav;
}
  • 생성자로 뷰의 이름을 저장하거나 setViewName() 매서드를 사용하여 뷰 네임을 지정
  • addObject() 메서드로 데이터를 저장

Model & ModelMap

  • 오로지 데이터만 저장후 view에서 사용 목적
  • Model은 인터페이스
  • ModelMap은 구현체
  • addAttribute() 메서드로 key-value형태 키에 값을 담아 Attribute로 넘겨준다

 Map 

Model 오브젝트와 동일하게 Map 형태로도 리턴이 가능

@GetMapping("/test6")
public Map<String, String> test6() {
    return data;
}
  • 모델과는 조금 다른 점은 개별로 모델이 등록되기 때문에 뷰에서 key.value 형태로 데이터에 접근했던 Model과는 다르게 value만으로 데이터에 접근해야 하며, 권장하는 방법 x

View 

  • 인터페이스
  • 스프링 내부의 view를 확장 or pdf, excel, rss 같은 다른 형태의 view 표현을 위하여 class를 확장

Restful한 스프링

  1. @ResponseBody
  2. @RestController

@ResponseBody

위의 방법들은 모두 전통적인 Spring MVC 컨트롤러인 @Controller를 사용한 형태로써 View를 반환하기 위해 사용했다. Spring MVC 컨트롤러에서는 데이터를 반환하기 위해서 @ResponseBody 애노테이션을 붙여줌으로써 JSON 형태로 데이터를 반환해줄 수 있게 된다.

@Controller
public class TestController {
	
	@GetMapping("/test7/account")
	@ResponseBody 
	public Account void(Account Account) {
  		return account;
	}
}
  • 주로 SPA나 ajax, 또는 모바일 어플리케이션 서버와 같은 REST SERVER로서의 역할을 할 때 사용하게 됨
  • 위 코드에서는 Account 객체를 반환하는 형태로서 클라이언트에서는 JSON 데이터로 Account 객체를 받게됨

@RestController 

RestController는 Restful Controller의 준말로써, Spring MVC Controller에 @ResponseBody가 추가된 것이다.

@RestController
@RequestMapping("/test8")
public class TestController {

    @GetMapping
    public Account test(Account account) {
        return account;
    }
}
  • 반환 값으로 뷰를 찾는 것이 아닌, HTTP 메시지 바디에 바로 입력 한다
  • 따라서 실행결과로 String 또는 객체 타입으로 반환한다.

@RestController vs @Controller

@RestController @Controller
반환 값으로 뷰를 찾는 것이 아닌, HTTP 메시지 바디에 바로 입력 한다
따라서 실행결과로 String 또는 객체 타입으로 반환한다.
반환값이 String이면 뷰 이름으로 인식된다.
뷰를 찾고 뷰를 렌더링한다.
  만약, String "OK"반환시에는 논리뷰를 찾으므로 응답메세지에 넣어주고 싶은 경우, @RestController로 바꾸거나 @ResponseBody를 선언해준다

 

 

 

 

 

 

 

참고

https://life

re.tistory.com/entry/Spring-Framework-Controller%EC%9D%98-%EB%A6%AC%ED%84%B4-%ED%83%80%EC%9E%85

https://ooeunz.tistory.com/101