스프링 MVC 웹 페이지 만들기
상품 도메인 개발
상품 등록 처리
addItemV1
요청 파라미터 데이터를 하나하나 변수로 받는다.
ItemRepository에 저장한 뒤 item을 모델에 담아 뷰에 전달한다.
addItemV2
@ModelAttribute가 Item 객체를 생성하고 모델에 넣어주는 일을 대신 해준다.
모델에 데이터를 담을 때는 이름이 필요한데 이때 애너테이션 안에 name 속성을 넣어주면 된다.
이름 지정
@ModelAttribute("hello") Item item
모델에 해당 이름으로 저장
model.addAttribute("hello", item);
addItemV3
이름을 생략하면 클래스 이름의 맨 앞글자만 소문자로 바꾼 것이 이름이 된다.
HelloData
->helloData
addItemV4
@ModelAttribute를 완전히 생략해도 그대로 모델에 자동 등록된다. 동작 방식도 같다.
단순 타입은 @RequestParam, 임의의 객체는 @ModelAttribute가 적용된다.
상품 수정
@GetMapping("/{itemId}/edit")
상품 수정 폼으로 이동
@PostMapping("/{itemId}/edit")
상품 수정 로직 처리
redirect:/basic/items/{itemId}
뷰 템플릿 호출 대신, 상품 상세 화면으로 이동하도록 리다이렉트 한다.
컨트롤러에 매핑된 @PathVariable 값도 사용할 수 있다.
HTML Form 전송
GET, POST만 지원한다.
PUT, PATCH는 HTTP API 전송 시에 사용한다.
HTTP POST로 Form 요청 시 히든 필드를 통해 PUT, PATCH를 사용할 수도 있지만 HTTP 요청 상으로는 POST다.
PRG Post/Redirect/Get
상픔 등록 폼에서 상품 등록을 요청하면 상품 상세 페이지가 나오도록 개발했다.
사실 이 애플리케이션엔 상품 등록 폼에서 상품 등록을 한 뒤 새로고침을 하면 계속 상품이 생성되는 버그가 있다.
웹 브라우저의 새로고침은 마지막에 서버에 전송한 데이터를 다시 전송한다는 의미다.
따라서 상품 등록을 요청한 뒤 새로고침을 누르면 다시 같은 데이터를 서버로 전송하게 된다.
확인하면 똑같은 데이터로 POST 요청을 하고 있음을 알 수 있다.
해결 방법
저장 후 리다이렉트를 하면 웹 브라우저 입장에서는 완전히 다른 url을 받게 된다. 그럼 새로고침을 해도 직전에 요청한 GET의 결과를 받게 된다. 이 방식을 PRG라고 부른다.
따라서 상품 등록 후 상품 상세로 가도록 redirect 하면 문제가 해결된다.
주의 사항
+ item.getId()
처럼 URL에 변수를 더해서 넣으면 URL 인코딩이 안되기 때문에 위험하다. 다음에 나올 RedirectAttributes를 사용하면 해결된다.
RedirectAttributes
고객 입장에서 등록이 잘 된건지 확인이 어려우니 개선해보자.
itemId와 status가 전달된 걸 확인할 수 있다.
status가 true면 텍스트를 띄우도록 설정하면 등록이 확실하게 됐다는 걸 알 수 있다.
Last updated
Was this helpful?