Spring

REST, RestController, ResponseEntity, AJAX

코리늬 2019. 4. 11. 14:09

# REST API

특정 URI를 통해 사용자가 원하는 정보를 제공하는 방식.

REST방식으로 제공되는 외부연결 URI를 REST API.

REST 방식의 서비스 제공이 가능한 것을 Restful 하다고 표현.

@RestController

@RestController = @Controller + @ResponseBody

클래스 상단에 @RestController 어노테이션을 선언하면 메소드마다 @ResponseBody를 붙여주지 않아도 된다.

# 단순 문자열 리턴

1
2
3
4
@RequestMapping("/hello")
public String sayHello(){
    return "Hello World";
}
cs

# JSON 리턴

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class SampleVO {
    private Integer SampleNo;
    private String firstName;
    private String lastName;
    
    //getter, setter, toString() 생략
}
 
//위에서 작성한 클래스의 객체를 반환하는 메소드를 RestController에 추가해준다.
@RequestMapping("/sendVO")
public SampleVO sendVO() {
    SampleVO sample = new SampleVO();
    sample.setSampleNo(1);
    sample.setFirstName("홍");
    sample.setLastName("길동");
    
    return sample;
}
cs

pom.xml에 jackson-databind 라이브러리를 추가해야한다.

1
2
3
4
5
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.4</version>
</dependency>
cs

# 컬렉션 타입(List)의 객체를 리턴

1
2
3
4
5
6
7
8
9
10
11
12
13
@RequestMapping("/sendList")
public List<SampleVO> sendList() {
    List<SampleVO> samples = new ArrayList<>();
    for(int i=0; i<10; i++){
        SampleVO sample = new SampleVO();
           sample.setSampleNo(1);
            sample.setFirstName("홍");
            sample.setLastName("길동");
            samples.add(sample);
    }
    
    return samples;
}
cs

# 컬렉션 타입(Map)의 객체를 리턴

1
2
3
4
5
6
7
8
9
10
11
12
13
@RequestMapping("/sendMap")
public Map<Integer, SampleVO> sendMap(){
    
    Map<Integer, SampleVO> sampleMap = new HashMap<>();
    for(int i=0; i<10; i++){
        SampleVO sample = new SampleVO();
        sample.setFirstName("홍");
           sample.setLastName("길동");
           sampleMap.put(i, sample);
    }
    
    return sampleMap;
}
cs

# ResponseEntity 타입

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

웹의 경우 HTTP 상태코드가 이러한 정보를 나타내는데 사용된다.

스프링에서 제공하는 ResponseEntity 타입은 개발자가 직접 결과 데이터와 HTTP 상태코드를 제어할 수 있는 클래스다.

ResponseEntity를 사용하면 404나, 500같은 에러를 전송하고 싶은 데이터와 함께 전송할 수 있기 때문에 좀 더 세밀한 제어가 가능해진다.

#ResponseEntity 예제1 : HTTP 상태코드만 보내기

1
2
3
4
@RequestMapping("/sendErrorAuth")
public ResponseEntity<Void> sendListAuth(){
    return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
cs

해당 URI를 요청하면 리턴타입으로 선언된 ResponseEntity는 결과 데이터로 HTTP 상태코드 중 400에러를 헤더메시지로 보내게된다.

이는 크롬 개발자도구의 네트워크 탭으로 확인할 수 있다.

#ResponseEntity 예제2 : 결과데이터와 HTTP 상태코드 같이 보내기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RequestMapping("/sendErrorNot")
public ResponseEntity<List<SampleVO>> sendListNot() {
 
    List<SampleVO> samples = new ArrayList<>();
    for(int i=0; i<10; i++){
        SampleVO sample = new SampleVO();
           sample.setSampleNo(1);
            sample.setFirstName("홍");
            sample.setLastName("길동");\
            samples.add(sample);
    }
    
    return new ResponseEntity<>(samples, HttpStatus.NOT_FOUND);
    
}
 
cs

해당 URI를 요청하면 리턴타입의 list 데이터와 HTTP 상태코드(404)를 전송하게 된다.

앞서 본 예제와 달리 화면에는 전송한 결과를 보여주면서, 상태코드도 함께 전달되는 것을 볼 수 있다.


스프링 @controller , @RestController 차이점

=> HTTP ResponseBody의 생성방식

@Controller는 View Page를 반환, @RestController는 객체 (Vo, DTO)를 반환하기만 하면,

객체데이터는application/json 형식의 HTTP ResponseBody에 직접 작성

스프링 3버전에서는 @ResponseBody를 통해 본격적으로 REST방식을 처리했다면,

스프링 4버전에서는 @Restcontroller 를 사용한다.

@RestController는 View가 필요없는 REST 방식에서 주로 사용되고 @ResponseBody를 포함하고 있다.

@Controller는 View와 REST 방식을 동시에 사용가능하지만 REST방식은 @ResponseBody를 사용해야한다.

 

AJAX

REST방식에서 가장 많이 쓰이는 형태는 AJAX와 결합된 형태이다.

비동기화는 결과의 데이터를 기다리는 방식이 아닌 결과를 통보받는 형식이다.

즉, 결과가 통보될 때 실행할 로직을 지정하는 방식이다.

  • 동기화방식은 순차적인 일을 실행하는데 적합

  • 비동기 방식은 일을 처리한 결과를 기다리지 않고 흐름이 지속됨

  • 비동기 방식의 특징은 처리된 일의 결과를 통보받은 형태로 처리

장점

  • 페이지의 이동없이 고속으로 화면 전환 가능

  • 서버처리를 기다리지 않고, 비동기 요청이 가능

  • 수신하는 데이터의 양을 줄일 수 있고, 클라이언트에게 처리를 위임할 수 있다.

단점

  • AJAX를 쓸 수 없는 브라우저에 대한 문제

  • HTTP 클라이언트의 기능이 한정

  • 페이지 이동없는 통신으로 인한 보안상의 문제 발생 염려

  • 지원하는 Charset이 한정적

  • 스크립트로 작성되어 디버깅이 엉렵다.

  • 요청이 남발되면 역으로 서버 부하가 늘 수 있다.

  • 다른 도메인과는 통신이 불가능