[Playground] Spring API 입력 검증 (feat. 400)

Daeya·어제

Playground

목록 보기
6/7

title 빈값이면 400 Bad Request 반환

POST /api/memos { "title": "", ... }
PUT /api/memos/{id} { "title": " ", ... }

Postman으로 빈 title내면 DB까지 안 가고 400으로 막는다.
Vue 화면 검증과 별개로, API만 직접 호출해도 검증되게 만든다.


1. 왜 서버에서도 검증하는지

Vue 검증Spring 검증
막는 대상화면에서 저장 버튼Postman / 다른 클라이언트
응답toast warning400 + JSON

프론트만 있으면 API를 직접 호출하면 빈 title이 들어갈 수 있다.


2. MemoValidationException 추가

public class MemoValidationException extends RuntimeException {
    public MemoValidationException(String message) {
        super(message);
    }
}

검증 실패 시 Service에서 throw 하는 전용 예외


3. Service에 validateTitle() 추가

public void insertMemo(String title, String content, String status) {
    validateTitle(title);
    // ... insert
}

public void updateMemo(int id, String title, String content, String status) {
    validateTitle(title);
    // ... update
}

private void validateTitle(String title) {
    if (title == null || title.trim().isEmpty()) {
        throw new MemoValidationException("title은 필수입니다");
    }
}
  • Controller는 그대로
  • Service에서 검증 → 실패 시 예외 throw

4. MemoApiExceptionHandler — 400 응답

@RestControllerAdvice
public class MemoApiExceptionHandler {

    @ExceptionHandler(MemoValidationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String, String> handleValidation(MemoValidationException e) {
        Map<String, String> error = new HashMap<>();
        error.put("message", e.getMessage());
        return error;
    }
}
어노테이션역할
@RestControllerAdviceAPI 예외 공통 처리
@ExceptionHandler이 예외 잡기
@ResponseStatus(BAD_REQUEST)HTTP 400

응답 예:

{ "message": "title은 필수입니다" }

5. dispatcher-servlet.xml

<context:include-filter type="annotation"
    expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation"
    expression="org.springframework.web.bind.annotation.ControllerAdvice"/>

6. Postman으로 확인

Create (400)

POST http://localhost:8080/playground/api/memos

{
  "title": "",
  "content": "내용",
  "status": "READY"
}

Update (400)

PUT http://localhost:8080/playground/api/memos/1

{
  "title": "   ",
  "content": "내용",
  "status": "READY"
}

정상 (200)

{
  "title": "제목",
  "content": "내용",
  "status": "READY"
}

정리

기능

  • POST / PUT 시 title 빈값 → 400 Bad Request
  • 응답 body: { "message": "title은 필수입니다" }

흐름 (요청 → 응답)

Controller: @RequestBody MemoVO
→ Service: validateTitle() → 실패 시 MemoValidationException
→ MemoApiExceptionHandler: 400 + message JSON

만든 순서

  1. MemoValidationException 추가
  2. Service validateTitle() (insert / update)
  3. MemoApiExceptionHandler (@RestControllerAdvice)
  4. dispatcher-servlet.xml에 ControllerAdvice 스캔
  5. Postman: 빈 title → 400 확인

필터/검색과 다른 점

  • 목록 조회: @RequestParam + XML <if>
  • 입력 검증: Service 검증 + 예외 + Advice

참고

profile
Daeya

0개의 댓글