λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Spring

[Spring] - @ModelAttribute, @RequestParam

by 주발2 2021. 2. 2.
λ°˜μ‘ν˜•

 μ•ˆλ…•ν•˜μ„Έμš”~ 이전에 μš΄μ˜ν•˜λ˜ λΈ”λ‘œκ·Έμ™€ μ†ŒμŠ€μ½”λ“œλ₯Ό κ΄€λ¦¬ν•˜λŠ” GitHubκ°€ λ”°λ‘œ μžˆμŠ΅λ‹ˆλ‹€.

 λ„€μ΄λ²„ λΈ”λ‘œκ·Έ

 GitHub


βœ” @ModelAttribute, @RequestParam

 

μ•ˆλ…•ν•˜μ„Έμš”~ μ΄λ²ˆμ— 정리할 λ‚΄μš©μ€ μŠ€ν”„λ§μ˜

@ModelAttribute, @RequestParam μ–΄λ…Έν…Œμ΄μ…˜ μž…λ‹ˆλ‹€.

 

졜근 @ModelAttribute μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λŠ”λ°, 바인딩이 λ˜μ§€ μ•Šμ•„ λ¬Έμ œκ°€ μžˆμ—ˆκ³  ...

κ²€μƒ‰ν•΄λ³΄λ‹ˆ @ModelAttribute μ–΄λ…Έν…Œμ΄μ…˜μ„ 객체에 바인딩 ν•˜κΈ° μœ„ν•΄μ„  Setter λ©”μ†Œλ“œ ν˜Ήμ€ μƒμ„±μž κ°€ ν•„μˆ˜μ μœΌλ‘œ ν•„μš”ν•˜κΈ°μ— 바인딩이 λ˜μ§€ μ•ŠλŠ” λ¬Έμ œκ°€ λ°œμƒν–ˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

λ”°λΌμ„œ @ModelAttribute 와 λΉ„μŠ·ν•œ μ–΄λ…Έν…Œμ΄μ…˜μΈ @RequestParam μ–΄λ…Έν…Œμ΄μ…˜μ„ κ°„λ‹¨νžˆ 정리해보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

 

 

 

 

βœ” @ModelAttribute

@ModelAttributeλŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ μ „μ†‘ν•˜λŠ” μ—¬λŸ¬ νŒŒλΌλ―Έν„°λ₯Ό 1:1둜 객체에 바인딩 ν•œ ν›„ λ‹€μ‹œ View둜 데이터λ₯Ό λ„˜κ²¨μ„œ 좜λ ₯ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” μ–΄λ…Έν…Œμ΄μ…˜ μž…λ‹ˆλ‹€.

 

@ModelAttributeλŠ” λ„˜μ–΄μ˜¨ νŒŒλΌλ―Έν„°μ˜ νƒ€μž…μ΄ 객체의 νƒ€μž…κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν¬ν•¨ν•΄μ„œ λ‹€μ–‘ν•œ μœ νš¨μ„±(Validation) 검사λ₯Ό μΆ”κ°€μ μœΌλ‘œ μ§„ν–‰ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, int ν˜•μ˜ id 값에 "1" μ΄λΌλŠ” String의 λ¬Έμžμ—΄μ„ λ„£μœΌλ €κ³  ν•œλ‹€λ©΄ BindException μ—λŸ¬κ°€ λ°œμƒν•©λ‹ˆλ‹€.

 

  @PostMapping(path = "user/join", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  @ApiOperation(value = "νšŒμ›κ°€μž…")
  public ApiResult<JoinResult> join(
          @ModelAttribute JoinRequest joinRequest,
          @RequestPart(required = false) MultipartFile file) {
      // ... 
      
      
      

import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

public class JoinRequest {

  @ApiModelProperty(value = "이름", required = true)
  private String name;

  @ApiModelProperty(value = "둜그인 이메일", required = true)
  private String principal;

  @ApiModelProperty(value = "둜그인 λΉ„λ°€λ²ˆν˜Έ", required = true)
  private String credentials;

  protected JoinRequest() {}

  // Getter, Setter μƒλž΅
  // Setter λ©”μ†Œλ“œ ν˜Ήμ€ λͺ¨λ“  ν•„λ“œλ₯Ό λ°›λŠ” μƒμ„±μžλŠ” λ°˜λ“œμ‹œ μ‘΄μž¬ν•΄μ•Ό @ModelAttribute 바인딩 κ°€λŠ₯

  @Override
  public String toString() {
    return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
      .append("name", name)
      .append("principal", principal)
      .append("credentials", credentials)
      .toString();
  }

}      

μœ„ μ½”λ“œμ—μ„œ ν΄λΌμ΄μ–ΈνŠΈκ°€ λ‹€μŒκ³Ό 같은 νŒŒλΌλ―Έν„°λ₯Ό μ „μ†‘ν•˜λ©΄, JoinRequest 객체에 바인딩이 λ©λ‹ˆλ‹€.

 

  • https://localhost~?name=test&principal=id&credentials=password

 

 

β€» @ModelAttribute λŠ” Setter λ©”μ†Œλ“œ ν˜Ήμ€ λͺ¨λ“  ν•„λ“œλ₯Ό 인자둜 λ°›λŠ” μƒμ„±μžκ°€ μžˆμ–΄μ•Ό 바인딩이 λ©λ‹ˆλ‹€.

 

 

 

 

 

 

βœ” @RequestParam

@RequestParam μ–΄λ…Έν…Œμ΄μ…˜μ€ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ „μ†‘ν•˜λŠ” νŒŒλΌλ―Έν„°λ₯Ό 1:1둜 λ°›κΈ° μœ„ν•΄ μ‚¬μš©ν•©λ‹ˆλ‹€.


@RequestParam μ–΄λ…Έν…Œμ΄μ…˜μ€ μƒλž΅

β€» 사싀 @RequestParam μ–΄λ…Έν…Œμ΄μ…˜μ€ μƒλž΅μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€. μƒλž΅μ„ ν•˜λ”λΌλ„ 컨트둀러의 λ§€κ°œλ³€μˆ˜ 이름과 Formμ—μ„œμ˜ 넀이밍이 λ™μΌν•˜λ‹€λ©΄ ν΄λΌμ΄μ–ΈνŠΈκ°€ μš”μ²­ν•œ νŒŒλΌλ―Έν„°μ˜ key κ°’κ³Ό λ§€κ°œλ³€μˆ˜μ˜ 이름을 λΉ„κ΅ν•˜μ—¬ 적절히 바인딩을 ν•΄μ£Όμ§€λ§Œ μ‚¬μš©μžκ°€ μ›ν•˜λŠ” λ§€κ°œλ³€μˆ˜μ— 직접 맀핑을 ν•  수 μžˆμœΌλ―€λ‘œ μ‚¬μš©ν•©λ‹ˆλ‹€.


 

 

@ModelAttribute μ–΄λ…Έν…Œμ΄μ…˜μ€ 객체에 λ°”μΈλ”©ν•œλ‹€λŠ” μ μ—μ„œ λ‹€λ¦…λ‹ˆλ‹€.

 

 

@RequestParam μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λ©΄ λ°˜λ“œμ‹œ ν•΄λ‹Ή νŒŒλΌλ―Έν„°κ°€ 전솑이 λ˜μ–΄μ•Ό ν•˜λŠ”λ°μš”, λ§Œμ•½ ν•΄λ‹Ή νŒŒλΌλ―Έν„°κ°€ ν•„μš”ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ required 속성을 false둜 μ„€μ • ν•  수 μžˆμŠ΅λ‹ˆλ‹€. (defaultλŠ” true μž…λ‹ˆλ‹€.)

 

 

λ˜ν•œ μ•„λž˜μ™€ 같이 μ†μ„±μœΌλ‘œ name을 μ„€μ •ν•  수 μžˆλŠ”λ°μš”, μ„€μ •ν•˜λ©΄ ν•΄λ‹Ή μ„€μ • κ°’κ³Ό νŒŒλΌλ―Έν„°μ˜ keyκ°€ 동일해야 ν•©λ‹ˆλ‹€.

 

@Requestparam("test") String test ==> localhost:8080/hello/dto?test=1234

 

 

μ•„λž˜ μ†μ„±μ—μ„œ value = "test" 와 value = "testAmount" λ₯Ό μ°Έκ³ ν•΄μ£Όμ„Έμš”.

 

 

• @Request("test"), @Request("testAmount") ν…ŒμŠ€νŠΈ

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/hello/dto")
    public HelloResponseDto helloDto(@RequestParam(value = "test") String name,
                                     @RequestParam(value = "testAmount") int amount) {
        return new HelloResponseDto(name, amount);
    }
}

 

 

 

 

 

• @Request("name"), @Request("amount") ν…ŒμŠ€νŠΈ

RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/hello/dto")
    public HelloResponseDto helloDto(@RequestParam("name") String name,
                                     @RequestParam("amount") int amount) {
        return new HelloResponseDto(name, amount);
    }
}

 

 

• μš”μ²­ νŒŒλΌλ―Έν„°κ°€ λΆ€μ‘±ν•  λ•Œ

 

 

 

 

 

• required = false 속성 ν…ŒμŠ€νŠΈ

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/hello/dto")
    public HelloResponseDto helloDto(@RequestParam(value = "name", required = false) String name,
                                     @RequestParam(value = "amount") int amount) {
        return new HelloResponseDto(name, amount);
    }
}

 

 

 

 

 

• primitive νƒ€μž…μ€ require = false 속성 λΆˆκ°€λŠ₯!

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/hello/dto")
    public HelloResponseDto helloDto(@RequestParam("name") String name,
                                     @RequestParam(value = "amount", required = false) int amount) {
        return new HelloResponseDto(name, amount);
    }
}

 

Reference Type이 μ•„λ‹Œ primitive type은 μœ„μ™€ 같이 required = false 속성이 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€!!

  • Reference Type

      • ex) String

  • primitive type

      • ex) int

λ°˜μ‘ν˜•

λŒ“κΈ€