Amenable
Amenable's Blog
Amenable
  • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (189)
    • ๐Ÿ“‚ JAVA (87)
      • ์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” (65)
      • ์ฃผ์š” ๊ฐœ๋… (22)
    • ๐Ÿ“‚ ๊ฐœ๋ฐœ ์„œ์  (22)
      • ์‹ค์šฉ์ฃผ์˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ (1)
      • ๊ฐ์ฒด์ง€ํ–ฅ์˜ ์‚ฌ์‹ค๊ณผ ์˜คํ•ด (2)
      • ํด๋ฆฐ ์ฝ”๋“œ (8)
      • ํ•จ๊ป˜ ์ž๋ผ๊ธฐ (1)
      • ๊ทธ๋ฆผ์œผ๋กœ ๋ฐฐ์šฐ๋Š” HTTP&Network Basic (10)
    • ๐Ÿ“‚ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (8)
      • ๊ฐœ๋… (8)
      • ๋ฌธ์ œํ’€์ด (0)
    • ๐Ÿ“‚ ๋„คํŠธ์›Œํฌ (14)
      • ๊ฐœ๋… (6)
      • ์„ฑ๊ณต๊ณผ ์‹คํŒจ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” 1%์˜ ๋„คํŠธ์›Œํฌ ์›๋ฆฌ (8)
    • ๐Ÿ“‚ ์Šคํ”„๋ง (13)
      • ๊ธฐ๋ณธ ๊ฐœ๋… (13)
    • ๐Ÿ“‚ WEB (5)
    • ๐Ÿ“‚ ์ž๋ฃŒ๊ตฌ์กฐ (12)
      • ๊ฐœ๋… (2)
      • ์ •๋ ฌ (8)
      • ํŠธ๋ฆฌ (2)
    • ๐Ÿ“‚ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (10)
      • ์ตœ์†Œ์‹ ์žฅํŠธ๋ฆฌ (2)
      • ์ตœ๋‹จ ๊ฒฝ๋กœ (2)
      • ๋ฌธ์ž์—ด (2)
      • ETC (4)
    • ๐Ÿ“‚ ์•Œ๊ณ ๋ฆฌ์ฆ˜_๋ฌธ์ œํ’€์ด (4)
      • BOJ_๋ฐฑ์ค€ (4)
    • ๐Ÿ“‚ ํ”„๋กœ๊ทธ๋ž˜๋ฐ (3)
    • ๐Ÿ“‚ DevOps (2)
      • ๋ฐฐํฌ (2)
    • ๐Ÿ“‚ ํ›„๊ธฐ (8)
      • ์šฐ์•„ํ•œ ํ…Œํฌ์ฝ”์Šค(ํ”„๋ฆฌ์ฝ”์Šค) (4)
      • 2023๋…„ (3)
      • 2024๋…„ (1)
    • ๐Ÿ“‚ ํšŒ๊ณ  (1)
      • 2023๋…„ (1)

๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

  • ๐Ÿš€ GitHub

ํ‹ฐ์Šคํ† ๋ฆฌ

hELLO ยท Designed By ์ •์ƒ์šฐ.
Amenable

Amenable's Blog

[Spring] ๊ฒ€์ฆ(Validation) - bindingResult.rejectValue(), binding.reject()
๐Ÿ“‚ ์Šคํ”„๋ง/๊ธฐ๋ณธ ๊ฐœ๋…

[Spring] ๊ฒ€์ฆ(Validation) - bindingResult.rejectValue(), binding.reject()

2023. 5. 2. 22:30

  ์ด๋ฒˆ ๊ธ€์„ ํ†ตํ•ด ์ด์ „ ๊ธ€์—์„œ BindingResult, FieldError, ObjectError๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค์–ด๋ณด์•˜๋˜ ๊ฒ€์ฆ ๊ธฐ๋Šฅ์„ ์กฐ๊ธˆ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

1. rejectValue() & reject() ๐Ÿฃ

  FieldError์™€ ObjectError๋Š” ๋„ˆ๋ฌด ๋ณต์žกํ•˜๋‹ค. BindingResult์˜ rejectValue์™€ reject๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์กฐ๊ธˆ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

  ์ด์ „ ๊ธ€์—์„œ BindingResult๋Š” ํ•ญ์ƒ ๊ฒ€์ฆํ•ด์•ผ ํ•  ๊ฐ์ฒด ๋ฐ”๋กœ ๋’ค์— ์ด์–ด์„œ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•œ ์ ์ด ์žˆ๋‹ค. ์ด๋Š” BindingResult๊ฐ€ ๊ฒ€์ฆํ•ด์•ผ ํ•  ๊ฐ์ฒด๋ฅผ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ์ด ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์•„๋ž˜ ๋‚ด์šฉ๋“ค์„ ๊ณ„์†ํ•ด์„œ ์‚ดํŽด๋ณด์ž.

  rejectValue์™€ reject์˜ ์ƒ์„ฑ์ž๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

void rejectValue(@Nullable String field, 
        String errorCode,
        @Nullable Object[] errorArgs, 
        @Nullable String defaultMessage);
void reject(String errorCode, 
        @Nullable Object[] errorArgs, 
        @Nullable String defaultMessage);
  • field
    ์˜ค๋ฅ˜ ํ•„๋“œ๋ช…
  • errorCode
    ์˜ค๋ฅ˜ ์ฝ”๋“œ(์ด ์˜ค๋ฅ˜ ์ฝ”๋“œ๋Š” ๋ฉ”์‹œ์ง€์— ๋“ฑ๋ก๋œ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋‹ค. ๋’ค์—์„œ ์„ค๋ช…ํ•  messageResolver๋ฅผ ์œ„ํ•œ ์˜ค๋ฅ˜ ์ฝ”๋“œ์ด๋‹ค.)
  • errorArgs
    ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์—์„œ {0}์„ ์น˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ’
  • defaultMessage
    ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ณธ ๋ฉ”์‹œ์ง€

  rejectValue()์™€ reject()๊ฐ€ ๋‚ด๋ถ€์—์„œ MessageCodesResolver๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ ์ ˆํ•œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ •ํ•˜๊ฒŒ ๋œ๋‹ค. 

 

2. messageCodesResolver ๐Ÿœ

  messageCodesResolver๋Š” 'errorCode, ๊ฐ์ฒด ์ด๋ฆ„, ํ•„๋“œ ์ด๋ฆ„, ํ•„๋“œ ํƒ€์ž…'์„ ์ด์šฉํ•ด์„œ ์ ์ ˆํ•œ ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€๋ฅผ ์ •ํ•œ๋‹ค. ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์„ ๊ฒฝ์šฐ์—๋Š” ์œ„์—์„œ ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ defaultMessage๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

  MessageCodesResolve๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๊ณ , DefaultMessageCodesResolver๋Š” ๊ธฐ๋ณธ ๊ตฌํ˜„์ฒด์ด๋‹ค. DefaultMessageCodesResolver์˜ ๊ธฐ๋ณธ ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ ๊ทœ์น™์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. ๊ฐ์ฒด ์˜ค๋ฅ˜๋กœ ๋‚˜๋ˆ„์–ด์ ธ ์žˆ๊ณ  ๋ฒˆํ˜ธ๊ฐ€ ๋‚ฎ์„์ˆ˜๋ก ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’๋‹ค.

๐Ÿ“’ 1. ๊ฐ์ฒด ์˜ค๋ฅ˜

  1. errorCode + "." + object name
  2. code

  errorCode๊ฐ€ required, object name์ด item์ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์ง„๋‹ค.

  1. required.item
  2. required

๐Ÿ“’ 2. ํ•„๋“œ ์˜ค๋ฅ˜

  1. errorCode + "." + object name + "." + field
  2. errorCode + "." + field
  3. errorCode + "." + field type
  4. errorCode

  errorCode๊ฐ€ typeMismatch, object name์ด user, field๊ฐ€ age, field type์ด int๋ผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์ง„๋‹ค.

  1. typeMismatch.user.age
  2. typeMismatch.age
  3. typeMismatch.int
  4. typeMismatch

  MessageCodesResolver๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

  ์˜ค๋ฅ˜ ์ฝ”๋“œ๋Š” ์ž์„ธํžˆ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค. ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉด ๋ฒ”์šฉ์„ฑ์ด ์ข‹์•„์„œ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฉ”์‹œ์ง€๋ฅผ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ๋ฐ˜๋ฉด์— ๋„ˆ๋ฌด ์ž์„ธํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉด ๋ฒ”์šฉ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.

  ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์„ธ๋ฐ€ํ•œ ๊ฒฝ์šฐ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ์ž์„ธํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๋ฒ”์šฉ์„ฑ์ด ์ค‘์š”ํ•˜๋‹ค๋ฉด ๋‹จ์ˆœํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค.

 

3. ๊ตฌํ˜„ ๐Ÿค

  rejectValue์™€ reject๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์ „์— FieldError์™€ ObjectError๋กœ ๋‚˜ํƒ€๋ƒˆ๋˜ ๊ฒƒ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

// ๊ธฐ์กด
bindingResult.addError(
        new FieldError("item",
                "itemName",
                item.getItemName(),
                false,
                null,
                null,
                "์ƒํ’ˆ ์ด๋ฆ„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค."));

// ๋ณ€๊ฒฝ
bindingResult.rejectValue("itemName", "required");

----------

// ๊ธฐ์กด
bindingResult.addError(new FieldError("item",
        "price",
        item.getPrice(),
        false,
        null,
        null,
        "๊ฐ€๊ฒฉ์€ 1,000 ~ 1,000,000 ๊นŒ์ง€ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค."));

// ๋ณ€๊ฒฝ
bindingResult.rejectValue("price", "range", new Object[]{1_000, 1_000_000}, null);

----------

// ๊ธฐ์กด
bindingResult.addError(new FieldError("item",
        "quantity",
        item.getQuantity(),
        false,
        null,
        null,
        "์ˆ˜๋Ÿ‰์€ ์ตœ๋Œ€ 9,999 ๊นŒ์ง€ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค."));

// ๋ณ€๊ฒฝ
bindingResult.rejectValue("quantity", "max", new Object[]{9_999}, null);

----------

// ๊ธฐ์กด
bindingResult.addError(new ObjectError("item",
        null,
        null,
        "๊ฐ€๊ฒฉ * ์ˆ˜๋Ÿ‰์˜ ํ•ฉ์€ 10,000์› ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.. ํ˜„์žฌ ๊ฐ’ = " + resultPrice));

// ๋ณ€๊ฒฝ
bindingResult.reject("totalPriceMin", new Object[]{10_000, resultPrice}, null);
// application.properties
spring.messages.basename=messages, errors

// /resources/errors.properteis
required.item.itemName=์ƒํ’ˆ ์ด๋ฆ„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.
range.item.price=๊ฐ€๊ฒฉ์€ {0} ~ {1} ๊นŒ์ง€ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.
max.item.quantity=์ˆ˜๋Ÿ‰์€ ์ตœ๋Œ€ {0} ๊นŒ์ง€ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.
totalPriceMin=๊ฐ€๊ฒฉ * ์ˆ˜๋Ÿ‰์˜ ํ•ฉ์€ {0}์› ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ฐ’ = {1}

  ์ „์ฒด ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

@Slf4j
@Controller
@RequiredArgsConstructor
public class ValidationController2 {

    private final ItemRepository itemRepository;

    @PostMapping("/add")
    public String addItem(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes) {

        // 1. ์•„์ดํ…œ ์ด๋ฆ„(itemName)์ด ์—†๋Š” ๊ฒฝ์šฐ
        if(!StringUtils.hasText(item.getItemName())){
            bindingResult.rejectValue("itemName", "required");
        }

        // 2. ๊ฐ€๊ฒฉ(itemPrice)์˜ ๋ฒ”์œ„๊ฐ€ 1,000 ~ 1,000,000์ด ์•„๋‹Œ ๊ฒฝ์šฐ
        if(item.getPrice() == null || item.getPrice() < 1000 | item.getPrice() > 1_000_000){
            bindingResult.rejectValue("price", "range", new Object[]{1_000, 1_000_000}, null);
        }

        // 3. ๊ฐœ์ˆ˜(quantity)๊ฐ€ ์ตœ๋Œ€ 9,999๊ฐœ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ
        if(item.getQuantity() == null || item.getQuantity() > 10_000) {
            bindingResult.rejectValue("quantity", "max", new Object[]{9_999}, null);
        }

        // ํŠน์ • ํ•„๋“œ ์˜ˆ์™ธ๊ฐ€ ์•„๋‹Œ ์ „์ฒด ์˜ˆ์™ธ
        // 4. ์ตœ์ข… ๊ฐ’(๊ฐ€๊ฒฉ(itemPrice) * ๊ฐœ์ˆ˜(quantity))์ด 10,000์› ๋ฏธ๋งŒ์ธ ๊ฒฝ์šฐ
        if(item.getPrice() != null && item.getQuantity() != null){
            int resultPrice = item.getPrice() * item.getQuantity();

            if(resultPrice < 10_000) {
                bindingResult.reject("totalPriceMin", new Object[]{10_000, resultPrice}, null);
            }
        }

        if(bindingResult.hasErrors()){
            return "item/addForm"; // ๋‹ค์‹œ ์ƒํ’ˆ ๋“ฑ๋กํŽ˜์ด์ง€๋กœ ์ด๋™
        }

        Item savedItem = itemRepository.save(item);
        redirectAttributes.addAttribute("itemId", savedItem.getId());
        redirectAttributes.addAttribute("status", true);
        return "redirect:/items/{itemId}";
    }
}

 

ํ•ด๋‹น ๊ธ€์€ ๊น€์˜ํ•œ ๋‹˜์˜ '์Šคํ”„๋ง MVC 2ํƒ„ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ '์„ ์ฐธ๊ณ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

'๐Ÿ“‚ ์Šคํ”„๋ง > ๊ธฐ๋ณธ ๊ฐœ๋…' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Spring] ๊ฒ€์ฆ(Validation) - Validator  (0) 2023.05.02
[Spring] ๊ฒ€์ฆ(Validation) - BindingResult, FieldError, ObjectError  (0) 2023.05.01
์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ(Spring Interceptor)  (0) 2023.04.30
์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ(Servlet Filter)  (0) 2023.04.29
๋ฉ”์‹œ์ง€ & ๊ตญ์ œํ™” (Message & Internationalization)  (0) 2023.04.25
    '๐Ÿ“‚ ์Šคํ”„๋ง/๊ธฐ๋ณธ ๊ฐœ๋…' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [Spring] ๊ฒ€์ฆ(Validation) - Validator
    • [Spring] ๊ฒ€์ฆ(Validation) - BindingResult, FieldError, ObjectError
    • ์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ(Spring Interceptor)
    • ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ(Servlet Filter)
    Amenable
    Amenable
    CS, ์ž๋ฐ”, ์ž๋ฃŒ๊ตฌ์กฐ, ์•Œ๊ณ ๋ฆฌ์ฆ˜, ์Šคํ”„๋ง, ์Šคํ”„๋ง ๋ถ€ํŠธ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐœ๋ฐœ์— ๊ด€ํ•œ ๋‚ด์šฉ์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

    ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”