반응형

application/json 헤더를 지정하여 WebAPI를 통해 들어오는 Json Request Body를 그대로 Broker에 전달해야하는 API를 만들 일이 생겼다.


전달하는 것까지는 좋은데, 최소한의 검증 (Null, Empty Check나 integer의 경우 마이너스 값 체크) 정도는 해야되겠다 싶어서, @Valid를 이용해보기로 하였다.


일단 Model선언은 아래와 같이 했다.

1
2
3
4
5
6
7
8
9
10
11
12
public class TestLog {
    @Min(1)
    private int id;
     
    @NotNull
    @NotEmpty  
    private String description;
     
    @NotNull
    @NotEmpty
    private String now;
}


@Min, @NotNull 의 경우 기본적으로 java에서 제공하지만, @NotEmpty같은 경우는 hibernate-validator 의존성을 추가해주어야 한다.  (http://hibernate.org/validator/)


위와 같이 Model을 만든 후 Controller의 API에, @Valid만 붙여주면 된다.

1
2
3
4
@PostMapping("/test_log")
public Result testLog(@RequestBody @Valid TestLog testLog) {
    return "ok";
}


이제 Body로 들어오는 파라미터가 id는 1보다 작은 경우, description, now는 비어있거나 Null인 경우 400에러와 함께, org.springframework.web.bind.MethodArgumentNotValidException를 뱉어내게 된다.


클라 입장에서 받는 Response Body는 아래와 같이 생겼다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
    "timestamp": 1494829780576,
    "status": 400,
    "error": "Bad Request",
    "exception": "org.springframework.web.bind.MethodArgumentNotValidException",
    "errors": [{
        "codes": ["Min.testLog.id", "Min.id", "Min.int", "Min"],
        "arguments": [{
            "codes": ["testLog.id", "id"],
            "arguments": null,
            "defaultMessage": "id",
            "code": "id"
        }, 1],
        "defaultMessage": "반드시 1보다 같거나 커야 합니다.",
        "objectName": "testLog",
        "field": "id",
        "rejectedValue": 0,
        "bindingFailure": false,
        "code": "Min"
    }],
    "message": "Validation failed for object='testLog'. Error count: 1",
    "path": "/api/test_log"
}


기본적으로 위와 같은 Json 형태로 Response를 주기 때문에, 클라 입장에서 공통으로 Body를 parsing하여 사용하려면, 서버 단에서 해당 Exception을 핸들링하여 별도로 아래와 같이 예외처리를 해주어야 한다. 

1
2
3
4
5
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result handleMethodArgumentException(MethodArgumentNotValidException e) {   
        return "fail";
}


반응형
,