[스프링 MVC part1] 웹 페이지 만들기

진영준·2024년 2월 5일

김영한스프링

목록 보기
2/3
post-thumbnail

🚗 새롭게 안 사실

  • 비즈니스 로직을 만들면 test로 실험을 해서 내가 만든 로직이 이상이 없는 지를 확인하는 것(tdd, 테스트주도설계) 도메인 주도 설계
  • 해당 강의에서는 JPA를 사용하지 않았지만 JPA에서 사용하는 기본 기능을 사용한다는 점.
  • resorces/static 경로에 html 등을 넣어두면 외부에서도 접근이 가능하기 때문에 별로 추천하지 않는다.
  • 타임리프 문법 중 th:action 태그를 비워두게 되면 현재 URI의 값으로 요청을 보낸다는 것. 그래서 같은 요청값이여도 get방식이냐 post방식이냐에 따라서 다른 요청을 보낸다는 것.


@RequiredArgsConstructor 사용하는 이유


@RequiredArgsConstructor 사용 전

  • @Autowired 를 사용해서 스프링 Bean에 의존성을 주입한다.
  @Controller
  @RequestMapping("/basic/items")
  public class BasicItemController {
      private final ItemRepository itemRepository;

      @Autowired
      public BasicItemController(ItemRepository itemRepository) {
          this.itemRepository = itemRepository;
      }
  }

@RequiredArgsConstructor 사용 후

  • @RequiredArgsConstructor 가 final이 붙은 repository를 자동으로 스프링 Bean에 등록해준다.
  @Controller
  @RequestMapping("/basic/items")
  @RequiredArgsConstructor
  public class BasicItemController {
      private final ItemRepository itemRepository;

  }

결론

코드가 간결해질 뿐만 아니라 훨씬 더 명시적으로 변한다.



@ModelAttribute를 이용한 form데이터 클린코딩


가정을 해봅시다.

  1. html의 form에서 데이터가 넘어온다는 가정.
  2. body에 넘어오는 데이터(파라미터)는 총 3개로 itemName, price, quantity이다.
  3. 실제 강의에서는 JPA를 사용하지 않았지만, JPA를 사용한다고 해도 충분히 코드가 잘 작동됨.

@ModelAttribute 사용 전

  • @RequestParam을 이용해서 모든 파라미터값을 명시해줘야한다.
	@PostMapping("/add")
	public String addItemV1(@RequestParam("itemName") String itemName,
                            @RequestParam("price") int price,
                            @RequestParam("quantity") Integer quantity,
                            Model model) {
        Item item = new Item();
        item.setItemName(itemName);
        item.setPrice(price);
        item.setQuantity(quantity);

        itemRepository.save(item);

        model.addAttribute("item", item);

        return "basic/item";
    }

@ModelAttribute 사용 후

  • @RequestParam 을 이용해서 모든 파라미터값을 명시할 필요가 없다.
  • 하지만 이것보다 더 간단한 코딩을 할 수 있다.
	@PostMapping("/add")
    public String addItemV2(@ModelAttribute("item") Item item) {
        itemRepository.save(item);
        return "basic/item";
    }

@ModelAttribute는 사실 명시해줄 필요도 없다.

  • @ModelAttribute는 생략이 가능하다.
  • 결론적으로는 아래와 같은 코드만으로도 위와 같은 효과를 볼 수 있다.
	@PostMapping("/add")
    public String addItemV2(Item item) {
        itemRepository.save(item);
        return "basic/item";
    }

됐고 그래서 @ModelAttribute가 뭔데..?

  1. @ModelAttribute 는 form으로 넘겨진 데이터를 객체를 만들어 model에 담아서 제공한다.
  2. @ModelAttributemodel.addAttribute("example", example)의 역할을 함께한다.


RedirectAttributes


🌋 RedirectAttributes의 개념

redirect:/ 를 사용할 때 ModelAttributes와 비슷한 개념이라고 생각하면 된다. 하지만,
그럼 ModelAttributes를 사용하면 되지. 뭐하러 RedirectAttributes를 사용하냐? 라고 말할 수 있다.
아래의 그림은 내가 chatGPT에게 물어본 두개의 역할과 목적의 차이점이다.

🪂 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}";
    }

위와 같은 코드가 있다. 코드를 보면서 예시를 들자면,

  • 첫 번째로, RedirectAttributes는 반환값을 치환해주는 역할을 한다.(URI 인코딩도 함께 해줌.)
  • 두 번째로, RedirectAttributes는 치환할 값이 없으면 쿼리파라미터(GET)방식으로 값을 넘겨주게 된다.
  • 위와 같은 코드가 URI는 다음과 같다. http://localhost:8080/basic/items/51?status=true
<!-- 추가 -->
    <h2 th:if="${param.status}" th:text="'저장 완료'"></h2>	

status가 true라는 점을 이용해 다음과 같은 타임리프(Thymeleaf)조건문을 사용하는 것도 가능하다.



🌎 공부를 하다 생긴 의문점

redirect:/ ~ 를 사용하는 정확한 이유는 무엇인가?

우리가 보통 @PostMapping 을 사용할 때 create 를 한다고 알고 있다.
그리고 이럴 때 redirect:/ ~를 많이 쓰는데 이러한 기법을 PRG(post redirect get) 기법이라고 한다.
그렇다면 이런 기법을 왜 사용하는 걸까? 바로 무분별한 create를 막기 위함이다.
원래는 우리가 Controller에서 view를 반환할 때 String으로 반환을 하곤 하는데, 이건 문제점이 있다.
예를 들어 @PostMapping을 처리하는 view에서 F5(새로고침)을 하면 어떻게 될까?
아마 무수한 @PostMapping 요청으로 인해서 필요없는 데이터가 DB에 쌓이거나 에러가 날 것이다.
이런 점을 막기 위해서 우리는 새로운 Mapping 요청인 redirect:/ ~를 사용하는 것이다.
이때 @PostMapping의 반환값을 @GetMapping으로 redirect 해주게 되면 위의 예시와 같은 상황은 일어나지 않을 것이다.
결론적으로 이러한 경우를 위해 생긴 개념(기법)이 PRG(post redirect get) 기법이다.

profile
주니어 개발자를 꿈꾸는 12hugs입니다.

0개의 댓글