스프링/4. 스프링 MVC-2 87

27. 검증 직접 구현

검증 실패시 검증 실패시, 고객의 불편을 최소화 하기 위해 고객이 보낸 데이터를 다 지워버리지 말고 그대로 담아서 상품등록 폼으로 다시 보여준다. 그리고 뭘 잘못했는지 알려줘서 고객의 불편을 최소화 한다. @PostMapping("/add") public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes, Model model) { //검증 오류 보관 Map errors = new HashMap(); //검증 로직 if(!StringUtils.hasText(item.getItemName())){ errors.put("itemName", "상품 이름은 필수입니다."); } if(item.getPrice() == n..

26. 검증

뭐 예를 들자면 가격이나 수량에 숫자만 들어갔는 지 등.. 근데 검증은 클라이언트에서 한번, 서버에서 한번 2차적으로 이루어져야 함. 클라이언트에서의 검증은 클라이언트의 사용성을 위한 검증이라고 보면 되고, 서버에서의 검증이 진짜 검증이라고 생각하면 됨. 왜냐하면 솔직히 포스트맨같은걸로 데이터 직접 보낸다든가 너무 쉬움. 그래서 최종적으로는 서버에서 검증이 이루어 져야 함. 예제의 요구사항은 타입, 필드 (텍스트 필드, 공백이 포함되어 있는지, 가격이나 수량의 최대 최소) 특정 필드 범위를 넘어서는 (가격 * 수량의 합은 최소 10000 이상이라던지) API 같은 경우 API 스펙을 잘 정의해서 검증 오류를 API 응답 결과에 잘 넘겨주어야 함.

25. 메시지, 국제화 적용

messages.properties hello=안녕 hello.name=안녕 {0} label.item=상품 label.item.id=상품 ID label.item.itemName=상품명 label.item.price=가격 label.item.quantity=수량 page.items=상품 목록 page.item=상품 상세 page.addItem=상품 등록 page.updateItem=상품 수정 button.save=저장 button.cancel=취소 타임리프 템플릿 상품 등록 폼 #{~} 이게 메시지 접근자임. 이렇게 하면 이제 저 messages.properties의 page.addItem을 가져옴. 상품 등록 폼 이렇게 인자넣기 가능. 함수처럼 쓰면 됨. message_en.properties hel..

24. 메시지, 국제화

메시지는 예를 들어, 우리가 상품명 : , 이런 단어들이 있다고 치자. 근데 만약 저걸 "상품이름 : " 이렇게 고치고 싶다면, 웹페이지가 수십개라면 힘들다. 일종의 공통 이름들을 message.properties라는 파일에 정의해둬서 변수처럼 사용할 수 있다. 양식은 #{클래스이름.변수이름} 국제화 위의 저걸 다 영단어로 바꾸면 끝. message_en.properties message_ko.properties 이 기능은 스프링에서 제공하는 추상체 MessageSource 기능을 사용하면 된다. 저걸 Bean에 등록해서 쓰면 된다. @Bean public MessageSource messageSource(){ ResourceBundleMessageSource messageSource = new Reso..

23. 셀렉트 버튼

@ModelAttribute("deliveryCodes") public List deliveryCodes(){ List deliveryCodes = new ArrayList(); deliveryCodes.add(new DeliveryCode("FAST", "빠른 배송")); deliveryCodes.add(new DeliveryCode("NORMAL", "일반 배송")); deliveryCodes.add(new DeliveryCode("SLOW", "느린 배송")); return deliveryCodes; } 아 난 솔직히 이코드 마음에 안든다. 이런 분류적인건 Enum 썼으면 좋겠다. 이건 김영한 선생님도 언급했는데, 저렇게 하면 컨트롤러를 지날 때 마다 생성하기 때문에, 따로 싱글톤 등으로 해서 쓰는..

21. 멀티 체크박스

@ModelAttribute("regions") public Map regions(){ Map regions = new LinkedHashMap(); regions.put("SEOUL", "서울"); regions.put("BUSAN", "부산"); regions.put("JEJU", "제주"); return regions; } 이렇게 아예 컨트롤러에서 함수로 @ModelAttribute 만들어 두면 모든 컨트롤러 지날 때 저게 들어간다. 이것도 좀 비효율 적이기는 함. 싱글톤같은걸로 처리하는게 좋긴 함. 참고로 LinkedHashMap은 순서가 보장됨. 여튼 위의 "regions"라는 이름으로 return값, regions가 들어감. @Data public class Item { private Long..

20. 단일 체크박스

@PostMapping("/add") public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes) { log.info("open = " + item.getOpen()); Item savedItem = itemRepository.save(item); redirectAttributes.addAttribute("itemId", savedItem.getId()); redirectAttributes.addAttribute("status", true); return "redirect:/form/items/{itemId}"; } Post방식으로 /add로 들어올 시 수행 판매 오픈 원래 좀 문제가 있는 부분이, html에..

19. 기존 Item에 요구사항 추가.

현재 팔고 있는지 파는 지역 상품 종류 파는 타입 (쿠팡 로켓배송, 일반배송 등) @Data public class Item { private Long id; private String itemName; private Integer price; private Integer quantity; private Boolean open; private List regions; private ItemType itemType; private String deliveryCode; public Item() { } public Item(String itemName, Integer price, Integer quantity) { this.itemName = itemName; this.price = price; this.qu..

18. 스프링 타임리프 폼

@GetMapping("/add") public String addForm(Model model) { model.addAttribute("item", new Item()); return "form/addForm"; } 빈 값은 뭐 보여줄려고 넘기는 거다. 상품명 가격 수량 상품 등록 취소 th:object 커맨드 객체로 지정해 주는거다. 이거 하면 이제 *{} 이렇게 쓸 수 있다. 원래 보통 ${item.itemName} 이렇게 써야 하는데, 저게 커맨드 객체라서 *{itemName} 이렇게 쓰면 ${item.itemName} 이거랑 같다. 저건 자손포함 태그에 하나밖에 못 쓴다. th:field 이거는 th:field="${item.itemName}" 이렇게 해주면 id, name, value를 자동으..