간단한 health check 서버를 만든다.
/healthcheck로 요청하면 무조건 OK를 응답하는 서버다.(application/json 타입 사용)
spring initializr에서 spring web 모듈만 추가하여 프로젝트 파일을 다운받는다.
gradle, java11을 사용한다.
Generate를 클릭한다.
HealthcheckController를 만들자.
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
@RestController
public class HealthcheckController {
@GetMapping(value = "/healthcheck")
public HealthStatus healthcheck() {
return new HealthStatus("ok");
}
class HealthStatus {
private String status;
HealthStatus(String status) {
this.status = status;
}
String getStatus() {
return status;
}
}
}
gradlew 파일이 있는 프로젝트 홈으로 가자.
gradle로 빌드를 한다.
./gradlew build
jar 파일이 있는 경로로 가서 jar을 실행하자.
cd build/libs
java -jar demo-0.0.1-SNAPSHOT.jar
서버에서 406 error를 응답한다.
서버에서 클라이언트에서 요청한 content type에 맞는 content를 응답할 수 없는 경우, 406에러를 응답한다.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406
그런데 이상했다.
분명 curl로 application/json을 content type에 추가해서 요청하는데, 406에러를 응답한다.
컨트롤러에서 반환하는 HealthStatus의 getter 접근자가 default였다.
반환 객체 HealthStatus의 getter에 public을 추가했다.
class HealthStatus {
private String status;
HealthStatus(String status) {
this.status = status;
}
public String getStatus() {
return status;
}
}
이후 200을 성공적으로 반환했다.
처음에 406 에러가 난 정확한 이유는 모르겠지만, 서버에서 jackson serailize 과정 중 에러가 난 것 같다.
문제 원인을 다소 찾기 어려웠다.
406에러는 서버에서 클라이언트로부터 요청한 content type에 맞는 응답을 할 수 없다는 의미인데, 마치 서버에서 content type을 추가하면 문제가 해결되는 듯한 인상을 주기 때문이다.
실제로는 서버에서는 application/json 타입은 처리 가능한 형식이었고, 서버 내부적으로 객체 -> json으로 serialize하는 과정에서 에러가 났던 것 같다.