backend
  • README
  • DOCS
    • Java Docs
    • Servlet Docs
    • JSP Docs
    • DB & SQL Docs
    • Spring Boot Docs
    • Spring Security Docs
    • AWS Docs
  • 설치하기
    • Intellij 설정
  • 자바
    • 01 Java란?
    • 02 자바 시작하기
    • 03 자료형과 연산자
    • 04 제어문
    • 05 메소드
    • 06 클래스 기초
      • Static 보충자료
      • 패키지 보충자료
    • 07 객체지향 프로그래밍
    • 08 클래스 더 알아보기
      • 열거형 ENUM 보충자료
    • 09 클래스와 자료형
      • 다형성 보충자료
      • 제네릭 보충자료
    • 10 컬렉션 프레임워크
      • 컬렉션 프레임워크 보충자료
    • 11 람다식과 함수형 프로그래밍
      • 람다식 보충자료
    • 12 오류 대비하기
      • 오류 보충자료
    • 13 멀티태스킹
      • 멀티태스킹 보충자료
    • 교재보충
      • java.lang
  • 스프링
    • 서블릿, JSP
      • 05 Servlet(서블릿)
        • 서블릿 보충자료
        • 서블릿 추가코드
        • XML, YAML, JSON
      • 06 JSP(자바 서버 페이지)
        • JSP 보충자료
      • 07 JSTL(JSP 스탠다드 태그 라이브러리)
        • JSTL 보충자료
      • 08 Cookie(쿠키), Session(세션)
      • 09 서블릿,필터,리스너
        • 서블릿,필터,리스너 보충자료
      • 11 도서관리 프로젝트 실습
    • Spring Boot
      • 01 스프링 등장 배경, 객체지향
        • 스프링 등장 배경, 객체지향 보충자료
      • 02 IOC(제어의 역전), DI(의존성 주입)
        • IOC 보충자료
        • DI 보충자료
      • 03 스프링 구조
        • 스프링 구조 보충설명
      • 04 테스트코드 실습
      • 05 스프링 빈 설정
        • 스프링 빈 설정 보충자료
      • 06 싱글톤
        • 싱글톤 보충 자료
      • 07 스프링 빈 자동설정
        • 스프링 빈 자동설정 보충자료
      • 08 빈 생명주기
        • 빈 생명주기 보충자료
      • 09 빈 스코프
        • 빈 스코프 보충자료
      • 10 스프링 MVC
        • 스프링 MVC 보충자료
        • 데이터베이스 연동에 필요한 부분
      • 11 Validation(검증)
        • Validation(검증) 보충자료
      • 12 Bean Validation(빈검증)
        • Bean Validation(빈검증) 보충자료
      • 13 예외처리
        • 예외처리 보충자료
      • 14 타입변환
      • 15 JDBC(Java Database Connectivity)
      • 16 커넥션풀
      • 17 트랜잭션
        • 트랜잭션 보충자료
      • 18 JDBC 템플릿 활용
      • 19 MyBatis
      • 20 JPA(Java Persistence API)
      • 22 게시판 프로젝트 실습
    • Spring Security
      • 보안(Security)
      • Spring Security
      • 2. Spring Security 알아보기
        • 보안 위협 실제 사례와 방어 전략
      • 3. Spring Security 기본 동작 흐름
      • 4. Spring Security로 인증 권한 추가하기
        • Spring Security의 인증 및 인가
      • 5. Spring Security에서 세션 관리하기
        • 세션(Session)과 쿠키(Cookie) 비교, 토큰(Token)과의 관계
        • 해싱 및 해싱알고리즘
        • base64
      • 6. Spring Security 악용 보호
        • SameSite
      • 7. Spring Security로 인가 권한 추가하기
      • 8. Bcrypt(비크립트) 암호화
      • OAuth2 적용하기
  • 네트워크
    • HTTP
    • OSI 7계층
  • DB&SQL
    • 01 Database(데이터베이스)와 SQL 개요
    • 02 관계형 모델
    • 03 집합
    • 04 JOIN 연산
    • 05 MySQL
      • 세이브포인트
      • DBeaver, Mysql 오토커밋 설정 관련
    • 06 SQL 기초
      • 예시데이터 쿼리문
    • 07 SQL 실습
      • 실습 스키마
    • 08 Join 활용
      • 실습스키마
    • 09 SQL 활용
      • 실습스키마
    • 10 정규화
      • 실습 스키마
    • 데이터타입
    • 예시 프로젝트 스키마 구성
  • AWS
    • SSL 연결하기
    • 보충설명
Powered by GitBook
On this page
  • BindingResult
  • 주요 역할
  • BindingResult 사용 방법
  • 주요 메서드
  • 사용 시 주의사항
  • 타임리프와 BindingResult를 활용한 검증 및 오류 처리
  • 타임리프에서의 th:field
  • errors.properties와 application.properties 설정
  • BindingResult와 Validator를 활용한 검증 (User 예제)
  • BindingResult에서 메시지 코드 처리
  • 검증 로직 분리
  • 컨트롤러에서 Validator 사용
  • 글로벌 Validator 설정
  • Thymeleaf와 함께 검증 오류 처리
  • messages.properties
  1. 스프링
  2. Spring Boot
  3. 11 Validation(검증)

Validation(검증) 보충자료

BindingResult

BindingResult는 Spring Framework에서 제공하는 인터페이스로, 폼 데이터 바인딩 및 검증(Validation) 결과를 처리하기 위해 사용됩니다. 주로 컨트롤러에서 요청 데이터를 도메인 객체에 매핑한 후, 바인딩 과정에서 발생한 오류나 검증 결과를 확인하고 처리하는 데 활용됩니다.

주요 역할

1. 데이터 바인딩 결과 확인

클라이언트로부터 전달된 요청 데이터를 객체에 바인딩하는 과정에서 발생한 에러(예: 타입 불일치, 필수값 누락 등)를 확인할 수 있습니다.

2. 검증(Validation) 결과 처리

Validator나 @Valid를 사용해 검증 로직을 실행한 후 발생하는 검증 에러를 저장하고 관리합니다.

BindingResult 사용 방법

BindingResult는 컨트롤러 메서드에서 검증 대상 객체 바로 다음에 위치해야 합니다. 이는 검증된 결과를 BindingResult를 통해 처리하기 위함입니다.

예제: 폼 데이터 처리와 검증

1. 도메인 객체 정의

public class User {
    @NotEmpty(message = "이름은 필수입니다.")
    private String name;

    @Min(value = 18, message = "나이는 최소 18살 이상이어야 합니다.")
    private int age;

    // Getters and Setters
}

2. 컨트롤러에서 BindingResult 사용

@Controller
@RequestMapping("/users")
public class UserController {

    @PostMapping("/register")
    public String registerUser(@Valid @ModelAttribute User user, BindingResult bindingResult, Model model) {
        // 검증 오류 확인
        if (bindingResult.hasErrors()) {
            // 에러 정보를 모델에 추가
            model.addAttribute("errors", bindingResult.getAllErrors());
            return "userForm"; // 에러 발생 시 다시 폼 화면으로
        }

        // 정상 처리 로직
        model.addAttribute("message", "사용자가 성공적으로 등록되었습니다.");
        return "success";
    }
}

3. 뷰에서 에러 출력

<form action="/users/register" method="post">
    <div>
        <label for="name">이름:</label>
        <input type="text" id="name" name="name" value="${user.name}" />
        <span>${errors[0]?.defaultMessage}</span>
    </div>
    <div>
        <label for="age">나이:</label>
        <input type="text" id="age" name="age" value="${user.age}" />
        <span>${errors[1]?.defaultMessage}</span>
    </div>
    <button type="submit">등록</button>
</form>

주요 메서드

BindingResult는 다양한 메서드를 제공하여 검증 및 바인딩 결과를 처리할 수 있습니다.

1. 에러 확인

  • hasErrors(): 바인딩 또는 검증 에러가 있는지 확인

  • hasFieldErrors(String field): 특정 필드에 에러가 있는지 확인

2. 에러 정보 조회

  • getAllErrors(): 모든 에러를 리스트로 반환

  • getFieldErrors(String field): 특정 필드와 관련된 에러를 리스트로 반환

  • getFieldError(String field): 특정 필드의 첫 번째 에러 반환

3. 에러 메시지 접근

ObjectError 또는 FieldError 객체를 통해 검증 실패 시 메시지를 가져올 수 있습니다.

  • getDefaultMessage(): 기본 메시지 반환

  • getField(): 에러가 발생한 필드 이름 반환

예제: 특정 필드 에러 확인

if (bindingResult.hasFieldErrors("age")) {
    FieldError ageError = bindingResult.getFieldError("age");
    System.out.println("에러 메시지: " + ageError.getDefaultMessage());
}

사용 시 주의사항

  1. BindingResult의 위치: 반드시 검증 대상 객체 바로 다음에 위치해야 합니다. 그렇지 않으면 Spring이 에러를 처리하지 못합니다.

  2. @Valid 또는 @Validated: 검증을 활성화하려면 검증 대상 객체 앞에 해당 어노테이션을 붙여야 합니다.

  3. 커스텀 메시지: 검증 메시지는 messages.properties 파일을 통해 커스텀할 수 있습니다.

    NotEmpty.user.name=사용자 이름을 입력해주세요.
    Min.user.age=사용자의 나이는 최소 {0}살 이상이어야 합니다.

타임리프와 BindingResult를 활용한 검증 및 오류 처리

타임리프에서의 th:field

  • th:field는 HTML 폼 필드와 객체의 필드를 바인딩합니다.

  • 오류가 발생하면 FieldError에 보관된 값을 출력합니다.

  • 예시:

<input type="text" th:field="*{field}" />
  • 바인딩된 필드 값이 유효하지 않을 경우, BindingResult에서 FieldError 객체를 사용하여 오류 메시지를 출력합니다.


errors.properties와 application.properties 설정

errors.properties8

  • 검증 메시지를 정의하는 파일입니다. 예시:

required.user.userName=user name is required.
range.user.age=age must be between {0} and {1}.

application.properties

  • 메시지 파일 위치를 지정합니다.

spring.messages.basename=messages,errors
  • messages.properties와 errors.properties를 모두 사용할 수 있습니다.


BindingResult와 Validator를 활용한 검증 (User 예제)


BindingResult에서 메시지 코드 처리

rejectValue와 reject

  • BindingResult에서 오류를 추가할 때 FieldError나 ObjectError를 직접 생성하지 않아도 됩니다.

  • rejectValue: 필드 수준의 오류를 추가합니다.

  • reject: 객체 수준의 오류를 추가합니다.

메시지 코드 우선순위

  1. 필드 오류 코드: 예) required.user.userId

  2. 일반 오류 코드: 예) Required

예시 코드

// 필드 오류 추가
bindingResult.rejectValue("userId", "required.user.userId");

// 메시지 처리 우선순위
// 1순위: required.user.userId (필드명 포함)
// 2순위: Required (일반 오류 코드)

검증 로직 분리

Validator 구현

  • Validator 인터페이스를 구현하여 검증 로직을 분리합니다.

package spring.mvc.validation;

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import spring.mvc.domain.User;

@Component
public class UserValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return User.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        User user = (User) target;

        // userId 검증
        if (user.getUserId() == null || user.getUserId().isEmpty()) {
            errors.rejectValue("userId", "required.user.userId");
        } else if (user.getUserId().length() < 5) {
            errors.rejectValue("userId", "length.user.userId", "User ID must be at least 5 characters.");
        }

        // userName 검증
        if (user.getUserName() == null || user.getUserName().isEmpty()) {
            errors.rejectValue("userName", "required.user.userName");
        }
    }
}

컨트롤러에서 Validator 사용

@InitBinder 설정

  • 특정 컨트롤러에서 Validator를 적용합니다.

package spring.mvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import spring.mvc.domain.User;
import spring.mvc.validation.UserValidator;

@Controller
@RequestMapping("/users")
public class UserController {

    private final UserValidator userValidator;

    public UserController(UserValidator userValidator) {
        this.userValidator = userValidator;
    }

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(userValidator);
    }

    @GetMapping("/form")
    public String showForm(Model model) {
        model.addAttribute("user", new User());
        return "userForm";
    }

    @PostMapping("/add")
    public String addUser(
        @ModelAttribute @Validated User user,
        BindingResult bindingResult
    ) {
        if (bindingResult.hasErrors()) {
            return "userForm";
        }
        return "redirect:/users/success";
    }
}

글로벌 Validator 설정

WebMvcConfigurer 사용

  • 글로벌 범위에서 Validator를 적용합니다.

package spring.mvc.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.validation.Validator;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import spring.mvc.validation.UserValidator;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private final UserValidator userValidator;

    public WebConfig(UserValidator userValidator) {
        this.userValidator = userValidator;
    }

    @Override
    public Validator getValidator() {
        return userValidator;
    }
}
  • 위 설정을 통해 모든 컨트롤러에서 @Validated를 사용하면 UserValidator가 자동으로 적용됩니다.


Thymeleaf와 함께 검증 오류 처리

Thymeleaf 템플릿

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>User Form</title>
</head>
<body>
    <form th:action="@{/users/add}" th:object="${user}" method="post">
        <div>
            <label for="userId">User ID:</label>
            <input type="text" id="userId" th:field="*{userId}" />
            <span th:errors="*{userId}">Invalid User ID</span>
        </div>
        <div>
            <label for="userName">User Name:</label>
            <input type="text" id="userName" th:field="*{userName}" />
            <span th:errors="*{userName}">Invalid User Name</span>
        </div>
        <div>
            <label for="rank">Rank:</label>
            <input type="text" id="rank" th:field="*{rank}" />
        </div>
        <button type="submit">Submit</button>
    </form>
</body>
</html>

messages.properties

  • 검증 메시지를 관리하기 위한 파일입니다.

required.user.userId=User ID is required.
length.user.userId=User ID must be at least 5 characters long.
required.user.userName=User Name is required.
Previous11 Validation(검증)Next12 Bean Validation(빈검증)

Last updated 4 months ago