백엔드/Spring

미완성) Spring Web Annotations

꾸준함의 미더덕 2024. 8. 29. 22:44

안녕하세요. 
 
저번 시간에 이어서 XSS 방지 기능을 리팩토링하며 배운 정보들을 정리해보는 시간을 갖겠습니다.
이번엔 SpringBindAnnotations입니다.
 
스프링은 HTTP Method 및 ContentType과 컨트롤러 메서드 인자에 선언된 SpringBindAnnotations 에 따라 각각의 경우 값을 다르게 바인딩합니다. 
 
SpringBindAnnotations가 생각보다 여러 상황에서 유연하게 값을 바인딩해주기 때문에.. 개발을 하면서 예상치 못했던 상황이 종종 있었습니다.
이번 기회에 확실히 ! 정리해보겠습니다.
 
 

Spring Web Annotations


- Spring Web Annotations는 HTTP 요청 값에 대해 스프링이 값은 다양하게 바인딩하는 것을 지원합니다.
- 기존에 자세히 알아보지 않고 인터넷의 정보를 받아 들였었는데, 틀린 사실이 많아 자세히 정리해야겠다는 생각이 들었습니다.
- Spring Web Annotation는 다양하게 값을 처리하기 때문에 특정 HTTP Method, HTTP Content-Type, 파라미터 요청, 혹은 바디 요청에 대해 다양한 경우의 수가 생깁니다. 따라서 인터넷에서 위의 대한 설명은 실무적으로 사용하는 Best Practice의 접근으로 이해하면 좋을 것 같아요..
(@RequestParam은 HTTP 파라미터에 대해 바인딩을 처리한다든지의.. 하지만 Body데이터도 바인딩할 수 있다...)
또한, Best Practice의 관점은 주관이 강하고, 시간에 따라 변하기 때문에 (생각보다 기본적인 주제인데도 불구하고) 명확한 기준도 찾아보기 힘들었습니다..


@ModelAttribute

- 컨트롤러 메서드 인자에 아무런 바인딩 메서드를 선언하지 않았다면 스프링은 기본적으로 @ModelAttribute를 달아준 것과 동일하게 처리한다.

[받을 수 있는 조건]

  • HTTP Parameter 와 HTTP Body 둘다 바인딩 할 수 있음
  • HTTP Method - 모든 Method를 받을 수 있다.
    • GET : 쿼리스트링을 바인딩
    • POST / PUT / PATCH : 주로 Body를 바인딩
      • HTTP Content-Type (Body로 데이터를 요청하는 경우 - POST/PUT/PATCH)
        • application/x-www-form-urlencoded
        • multipart/form-data (서브 content-type이 form인경우와 파일만 인것같음 확인 필요) 
        • text/plain(확인필요)
    • DELETE : 주로 URL 경로로 식별자를 받으므로 사용할 경우가 드물다 

 

// GET 요청
// 예시코드

 

// multipart 단독 파일 잘 받음 

@Controller
public class MyController {

    @PostMapping("/submit")
    public String handleFileUpload(@ModelAttribute("file") MultipartFile file) {
        // 'file' 파라미터로 전달된 파일이 MultipartFile로 바인딩됩니다.
        return "result";
    }
}

 
 

// 이런식의 요청은 multipart/form-data 내부에 w-xxx-form-urlencoded의 조합은 file만 제대로 받게 된다..

POST http://localhost:8080/submit
Host: example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="metadata"
Content-Type: application/x-www-form-urlencoded

name=JohnDoe&email=john.doe%40example.com&age=30
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

(file content here)
------WebKitFormBoundary7MA4YWxkTrZu0gW--

// 컨트롤러 메서드
@PostMapping(value="submit", consumes = "multipart/form-data")
public String submitForm(
        @ModelAttribute UserForm userForm, //값을 null로 받는다
        @ModelAttribute("file") MultipartFile file) // file은 제대로 받는다
        throws UnsupportedEncodingException {

    return "success";
}

 
 

// 단독으로 보내는 x-www-form-urlencoded는 잘 받고 있음

POST http://localhost:8080/submit HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

name=JohnDoe&email=john.doe%40example.com&age=30


@PostMapping(consumes = "application/x-www-form-urlencoded")
public String submitForm(@ModelAttribute UserForm userForm) {

    return "success";
}

 
 
-> 하지만 multipart + parameter 요청의 조합인 경우는 또 받아짐.. 
 

@RequestParam

@RequestBody

@RequestPart