[인프런 강의] 스프링 부트 개념과 활용 - 8

2020. 6. 9. 21:39강의/스프링 부트 개념과 활용

1. 스프링 웹 MVC - ExceptionHandler

스프링 부트 애플리케이션을 실행하고 웹을 띄워보면 whitelabel 에러 페이지를 볼 수 있었다. 이것은 웰컴 페이지를 찾지 못하였을 때 띄워지도록 ExceptionHandler가 핸들링한 예시로 볼 수 있다. 이처럼 스프링 부트는 따로 설정해주지 않아도 등록된 핸들러를 통해서 ExceptionHandle을 해준다. 간단한 예외 핸들링 상황을 만들어 보자.

 

위에서 @ExceptionHandler(SampleException.class)가 의미하는 것은 SampleController에서 발생하는 예외 중 SampleException에 해당하는 예외가 발생할 경우 이 핸들러를 통해 처리한다는 것을 의미한다. 여기서는 AppError라는 클래스를 만들어 예외 발생에 대한 정보를 담고 있는 객체를 만들고 @ResponseBody를 통해 웹에 띄워보았다.

/hello요청을 하면 ExceptionHandler를 통해서 핸들링한 결과를 웹 상에서 확인할 수 있었다. 

 

이러한 ExceptionHandler를 해당 클래스에서 발생하는 예외뿐 아니라 전역적으로 사용하고 싶다면  ExceptionHandler들을 보관하는 클래스를 만들고 @ControllerAdvice를 붙여주면 된다. 이렇게 하면 어디서든지 SampleException에 해당하는 예외가 발생하면 해당 핸들러를 통해 핸들링된다. 

 

2. 스프링 웹 MVC - 상태 코드 값에 따른 웹페이지 설정

일종의 커스텀 에러 페이지라고 할 수 있다. 어떠한 에러상태에서의 상태코드 값에 따라 보이는 페이지를 설정할 수 있다. 예를 들어 많이 봐본 적이 있는 404 에러가 발생했을 때 커스텀한 페이지가 나오도록 해보았다. 방법은 아주 간단하다. src/main/resource밑에 static 또는 templates에 error 패키지를 만들고 그 안에 404.html 파일을 만들어 커스텀하면 된다.

 

404.html

이와 같이 404.html을 만들고 다시 localhost:8080을 띄워보면 404 에러에 대해 whitelabel 페이지가 뜨지 않고 커스텀한 페이지가 뜨는 것을 확인할 수 있다. 

 

3. 스프링 웹 MVC - HATEOAS

먼저 HATEOAS는 Hypermedia As Engine Of Application State의 약자이다. 말 그대로 이러한 기능을 해주는 라이브러리의 이름이기도 하다. 전에 REST API에 대해 정리한 적이 있는데, REST API로 인정받기 위한 최종 관문이라고 할 만큼 현재 이 HATEOAS가 적용되지 않은 API가 많이 존재한다. 이러한 HATEOAS를 통해 서버와 클라이언트는 아래와 같은 작업이 가능하다. 

  • 서버: 현재 리소스와 연관된 링크 정보를 클라이언트에게 제공한다.
  • 클라이언트: 연관된 링크 정보를 바탕으로 리소스에 접근한다.

어느 타 기능과 마찬가지로 이 기능을 사용하기 위해서는 먼저 의존성을 추가해야 한다.

1) pom.xml에 hateoas 의존성 추가

 

2) 테스트 코드 작성

이번에도 TDD를 실천하기 위해 테스트 코드를 먼저 작성해 보았다. /hello라는 요청이 들어왔을때 json으로 바뀐 리소스 중 _links가 존재하는지를 테스트하는 것이다. (이와 같은 테스트 코드를 작성할 때 get, status, jsonPath 등은 모두 org.springframework.test.web.servlet.result.MockMvcResultHandlers 또는 org.springframework.test.web.servlet.request.MockMvcRequestBuilders의 static 메소드를 import 해주면 된다.)

 

당연히 hello요청에 대한 컨트롤러 내용을 작성하지 않았으므로 테스트는 에러가 발생한다.

 

3) SampleController작성

 

위와 같이 /hello요청이 들어올 시 Hello 객체를 만들어 prefix와 name을 설정해주고 그 객체를 리턴해주도록 만들었다. 이 애플리케이션을 실행하면 객체의 정보는 있지만 어떠한 link정보도 넣지 않았기 때문에 테스트가 에러를 발생한다. 

 

3) 링크 정보 추가

링크 정보를 추가하는 방법은 아주 다양하다. 대표적인 방법을 통해 예시 코드를 작성해 보았다. 여기서는 HATEOAS에 들어있는 Resource를 사용한다. 이것은 리소스와 링크 정보를 함께 제공해준다. 

 

강의에서는 Resource <T>를 사용하였지만 공식문서에 의하면 이것이 EntityModel로 변경되었다고 하여 적용해보았다. 위와 같이 링크 정보를 더해주면 응답에 링크 정보가 함께 들어가는 것을 볼 수 있다. 

 

HATEOAS에 대한 자세한 내용은 너무 깊은 내용이라고 강의에서 말해주었다. 생각보다 흥미로운 내용이어서 따로 정리를 할 예정이다.

 

4. 스프링 웹 MVC - CORS

CORS라는 기능은 나에게는 매우 생소한 기능이었다. 덧붙여 이것은 SOP기술을 우회하기 위한 기술이라고 하는데 SOP도 나에게는 생소했다... 각각 Single-Origin Policy과 Cross-Origin Resource Sharing의 약자인데 SOP의 경우 Origin이 다르면 호출하지 못한다. 

이때 Origin이 의미하는 것은 아래의 세 가지를 조합한 것이다.

  • URI 스키마 (http, https)
  • hostname (whiteship.me, localhost)
  • 포트 (8080, 18080)

간단하게 말하자면 18080 포트에 띄워진 애플리케이션에서 8080 포트에 띄워진 무언가를 호출할 수 없는 것이 SOP이다. 이것을 우회하는 방법이 바로 CORS인 것이다. 스프링 부트는 이를 위한 자동 설정이 모두 되어있으므로 @CrossOrigin을 통해 기능을 사용하기만 하면 된다. 

 

이것을 확인하기 위해서는 프로젝트를 두 개 만들어야 한다. 하나는 포트 8080에서 띄워질 corsServer 프로젝트이고 다른 하나는 18080 포트에서 띄워질 corsClient 프로젝트이다. 아래와 같이 두 프로젝트를 구성해보자.

 

1) cors-server

서버의 역할을 할 프로젝트는 @RestController를 통해 /hello요청이 왔을 때 Hello문자열을 보여주도록 만든다.

localhost:8080/hello를 통해 Hello문자열이 잘 보이는 것을 확인할 수 있다.

 

2) cors-client

이 프로젝트는 server프로젝트의 origin에 접근할 프로젝트이다. 따라서 포트번호를 달리하기 위해 application.properties에 server.port=18080을 설정해준다. 이후 웰컴 페이지에서 http://localhost:8080/hello를 호출할 수 있는지를 확인한다.

(웰컴 페이지는 index.html을 만들면 자동으로 루트 페이지가 된다는 것을 전에 정리하였다.)

 

cross origin에 대한 어떠한 설정도 없기 때문에 실패하는 것을 볼 수 있다. 

 

3) @CrossOrigin

이때 Cross Origin을 허용해주기 위한 어노테이션 @CrossOrigin을 사용하면 된다. 

위와 같이 CrossOrigin의 매개변수로 http://localhost:18080을 설정해주면 해당 주소로부터 /hello에 대한 요청이 왔을 시 응답해줄 수 있게 된다. 

Hello메시지를 통해 성공적으로 호출했음을 볼 수 있었다.

 

http://localhost:18080뿐만아니라 여러 컨트롤러로부터 CrossOrigin을 허용하기 위해서는 두 가지 방법이 있다.

  • @Controller나 @RequestMapping에 추가하거나
  • WebMvcConfigurer 사용해서 글로벌 설정