스프링 MVC - @ModelAttribute, PRG, RedirectAttributes

2022. 1. 10. 12:57·개발/Spring MVC
반응형
본 게시글은 인프런 김영한 선생님 강의 스프링 MVC 1편을 완강하고 배운 것을 남기고자 적은 포스팅입니다.
(2022.08.07 수정) - 복습을 하면서, 기억할 부분 설명 추가.

 

강의 링크는 아래와 같습니다.

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

www.inflearn.com

 

 

@ModelAttribute

우리는 저번에 @ModelAttribute에 대해 배워봤다. 그러나 이번에는 복습 겸 추가 내용을 남기려고 한다.

HTML FORM POST 방식을 통해 @RequestParam으로 변수를 하나하나 받아서 Item을 생성하는 과정은 불편했다.

이번에는 @ModelAttribute를 사용해서 한 번에 처리해보자. 코드는 아래와 같다.

/**
 * @ModelAttribute("item") Item item
 * model.addAttribute("item", item); 자동 추가
 *
 * @ModelAttribute name 생략 가능
 * 생략시 model에 저장되는 name은 클래스명 첫글자만 소문자로 등록 Item -> item
 * @ModelAttribute("item") Item item, ->  @ModelAttribute Item item
 */
@PostMapping("/add")
public String addItemV2(@ModelAttribute("item") Item item, Model model) {
   itemRepository.save(item);
   //model.addAttribute("item", item); //자동 추가, 생략 가능
   return "basic/item";
}

 

  • @ModelAttribute - 요청 파라미터 처리
    • @ModelAttribute는 Item 객체를 생성하고, 요청 파라미터의 값을 프로퍼티 접근법 (setXxx)으로 입력해준다.
  • @ModelAttribute - Model 추가
    • @ModelAttribute는 중요한 한 가지 기능이 더 있다.
    • 바로 모델(Model)에 @ModelAttribute로 지정한 객체를 자동으로 넣어준다.
    • 지금 코드를 보면 model.addAttribute("item", item)가 주석 처리되어 있어도 잘 동작하는 것을 확인할 수 있다.

모델에 데이터를 담을 때는 이름이 필요하다.

이름은 @ModelAttribute에 지정한 name(value) 속성을 사용한다.

만약 다음과 같이 @ModelAttribute의 이름을 다르게 지정하면 다른 이름으로 모델에 포함된다.

 

@ModelAttribute("hello") Item item 이름을 hello로 지정

model.addAttribute("hello", item); 모델에 hello 이름으로 저장

 

@ModelAttribute의 이름을 생략하면 모델에 저장될 때 클래스명을 사용한다. 이때 클래스의 첫 글자만 소문자로 변경해서 등록한다.

/**
 * @ModelAttribute 자체 생략 가능
 * model.addAttribute(item) 자동 추가
 */
@PostMapping("/add")
public String addItemV4(Item item) {
   itemRepository.save(item);
   return "basic/item";
}

@ModelAttribute 자체 생략도 가능하다. 대상 객체는 모델에 자동 등록된다. 

PRG POST/Redirect/GET

POST 방식을 통해 매핑된 컨트롤러가 뷰를 렌더링 한다고 가정해보자. 쉽게 이해를 도울 사진은 아래와 같다.

웹 브라우저의 새로 고침은 마지막에 서버에 전송한 데이터를 다시 전송한다.

상품 등록 폼에서 데이터를 입력하고 저장을 선택하면 POST /add + 상품 데이터를 서버로 전송한다.

이 상태에서 새로 고침을 또 선택하면 마지막에 전송한 POST /add + 상품 데이터를 서버로 다시 전송하게 된다.

즉 POST 방식으로 상품을 등록하고 새로 고침을 하면 ID만 다른 같은 상품이 등록되는 불상사가 발생한다.

 

어떻게 이를 해결할 수 있을까? 아래 이미지를 확인해보자.

 

바로 뷰를 렌더링 하지 않고 다른 URL로 Redirect 시키는 것이다.

브라우저의 새로 고침은 마지막에 서버에 전송한 데이터를 다시 전송한다.

새로 고침 문제를 해결하려면 상품 저장 후에 뷰 템플릿으로 이동하는 것이 아니라, 상품 상세 화면으로 리다이렉트를 호출해주면 된다.

웹 브라우저는 리다이렉트의 영향으로 상품 저장 후에 실제 상품 상세 화면으로 다시 이동한다.

따라서 마지막에 호출한 내용이 상품 상세 화면인 GET /items/{id}가 되는 것이다.

이후 새로고침을 해도 상품 상세 화면으로 이동하게 되므로 새로 고침 문제를 해결할 수 있다.

Redirect 

Redirect를 하도록 코드를 작성해보자.

/**
 * PRG - Post/Redirect/Get
 */
@PostMapping("/add")
public String addItemV5(Item item) {
   itemRepository.save(item);
   return "redirect:/basic/items/" + item.getId();
}

이런 문제 해결 방식을 PRG Post/Redirect/Get 방식이라고 한다.

주의!!!

"redirect:/basic/items/" + item.getId() redirect에서 +item.getId()처럼 URL에 변수를 더해서 사용하는 것은

URL 인코딩이 안되기 때문에 위험하다. 다음에 설명하는 RedirectAttributes를 사용하자.

RedirectAttributes

저장이 잘 되었으면 상품 상세 화면에 "저장되었습니다"라는 메시지를 보여달라는 요구사항이 왔다. 간단하게 해결해보자.

/**
 * RedirectAttributes
 */
@PostMapping("/add")
public String addItemV6(Item item, RedirectAttributes redirectAttributes) {
   Item savedItem = itemRepository.save(item);
   redirectAttributes.addAttribute("itemId", savedItem.getId());
   redirectAttributes.addAttribute("status", true);
   return "redirect:/basic/items/{itemId}";
}

리다이렉트 할 때 간단히 status=true를 추가해보자. 그리고 뷰 템플릿에서 이 값이 있으면, 저장되었습니다.라는 메시지를 출력해보자.

실행해보면 다음과 같은 리다이렉트 결과가 나온다. http://localhost:8080/basic/items/3? status=true

RedirectAttributes

RedirectAttributes를 사용하면 URL 인코딩도 해주고, pathVarible , 쿼리 파라미터까지 처리해준다.

 

  • redirect:/basic/items/{itemId}
    • pathVariable 바인딩: {itemId}
    • 나머지는 쿼리 파라미터로 처리:? status=true

이제 뷰 템플릿에서 if문을 사용해서 저장이 잘 되었다는 확인 메시지를 출력하면 된다.

 

이상으로 스프링 MVC 1편 포스팅을 마칩니다.

반응형
'개발/Spring MVC' 카테고리의 다른 글
  • 스프링 MVC 2편 - Thymeleaf 기초 part 2
  • 스프링 MVC 2편 - Thymeleaf 기초 part 1
  • 스프링 MVC - 기본 기능 (HTTP 응답, HTTP 메시지 컨버터)
  • 스프링 MVC- 기본 기능 (로깅, HTTP 요청)
Debin
Debin
공부 기록을 남기며 게시글 리팩토링을 진행하는 블로그입니다.
  • Debin
    리팩토링하는 블로그
    Debin
  • 전체
    오늘
    어제
    • 분류 전체보기
      • DB
        • DB 기초
        • MySQL
        • SQL 튜닝
      • OS
      • Network
      • Git
      • 디지털콘텐츠기획
      • 소프트웨어공학
      • 코딩테스트
        • 프로그래머스
        • 백준
        • 인프런
      • 공부 일지
      • 독서
        • 클린코드
        • 일상 속 사물이 알려주는 웹 API 디자인
        • 토비의 스프링
        • 객체지향의 사실과 오해
        • 자바 잘 읽는 법
      • 기록 및 회고
      • Cloud
        • AWS
      • 개발
        • Java
        • Spring Core
        • Spring MVC
        • Spring DB
        • Spring Boot
        • Spring Security
        • Spring Batch
        • JPA
        • Test
        • Android
      • 대외활동
        • UMC SERVER
        • 카엔프 SW 아카데미
      • 프로젝트
      • Docker
      • Gradle
      • ELK
      • 실무 이야기
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

    • 본인 깃허브입니다!
  • 인기 글

  • 태그

    코딩 #개발자 #노마드북클럽 #노개북
    객체
    docker
    인덱스
    Java
    트랜잭션
    ORM
    container
    AWS
    test
    spring mvc
    스프링
    토비의 스프링
    redis
    컨테이너
    SQL
    스프링 부트
    프록시
    도커
    spring boot
    운영체제
    데이터베이스
    mysql
    spring
    JPA
    리눅스
    innodb
    객체지향
    자바
    AOP
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
Debin
스프링 MVC - @ModelAttribute, PRG, RedirectAttributes
상단으로

티스토리툴바