Spring Boot - 사용자 요청 방식

UnKnown12·2023년 1월 9일
0

Spring Boot

목록 보기
12/13

❗ 사용자 ( URI 리소스 ) 와 서버 ( Spring 컨테이너 ) 가
서로 데이터를 주고 받기 위해 사용되는 기법들

📌 PathVariable 경로변수

❗URI 리소스와 Spring Controller 메소드 파라미터와
바인딩할 때 사용하는 어노테이션

PathVariable 예시

	/*
	 * 1-1 상품 아이템id로 조회
	 */
	@GetMapping("/{itemId}")
	public String item(@PathVariable Long itemId, Model model ) {
		Item item = itemRepository.findById(itemId);
		model.addAttribute("item", item);
		
		return "basic/item";
	}

예시와 같이 GetMapping 으로 받아오는 URI 리소스 중
itemid 값을 경로변수(PathVariable) 로 선언하여
해당 리소스 값을 Spring 컨테이너 내부에서 활용하는 기법이다.

🤔 바인딩 이란 ?

Spring 사용자 관점에서 사용자가 입력한 값을
어플리케이션 도메인 객체에 동적으로 할당하는 기능
( = 도메인 과 Controller 영역 간의 정보 전달 하기 위함 )

쉽게 말해, Spring 컨테이너 내부의 도메인 과 Controller 를 연결 시키는 작업

📌 @RequestParam

❗Controller 메소드의 파라미터와 웹 요청 파라미터를 매핑하기 위해
사용하는 어노테이션

@RequestParam 예시

	@PostMapping("/add")
	public String save(	@RequestParam String 	itemName,
						@RequestParam int		price,
						@RequestParam 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";
	}

사용자의 요청을 통해 명시된 URI 리소스
"ex) /itemName=name&price=100&quantity=30 " 에서
String, int, Integer 데이터를 받아
Item() 객체에 할당하고

Repository 영역으로 이동해 할당된 item()객체 데이터를
DB영역에 저장하도록 설계된 예시이다.

📌 @ModelAttribute

❗ Controller 메소드의 파라미터 나 리턴값을
Model 객체와 바인딩 하기 위한 어노테이션

❗ @RequestParam 를 다중으로 선언한 것과 같다

@ModelAttribute 예시

	@PostMapping("/add")
	public String saveV2( @ModelAttribute("item")Item item) {
		// @ModelAttribute 가 해주는 역할
//		Item item = new Item();
//		item.setItemName(itemName);
//		item.setPrice(price);
//		item.setQuantity(quantity);

		itemRepository.save(item);

//		model.addAttribute("item", item);
		return "basic/item";
	}

@RequestParam 을 통해 다수의 데이터를 주고 받을 때
Model 타입 객체 하나로 통일하여 다수의 데이터를 주고 받을 때 사용한다

URI 리소스의 데이터를 Model 객체로 가져와 view단에 즉시 적용 및 Repository 영역으로 이동 등 활용사례가 다양하다.

❗ Spring 3 버전에서 @ModelAttirbute 어노테이션 선언 없이
Model 객체 선언하는 것만으로도 적용이 되지만, 가독성 이슈로 인해 선언해 주자

📌 RedirectAttributes

사용자 요청에 맞춰 데이터를 전달하는 방식에 사용되는 클래스

Spring Controller 메소드의 파라미터에서 선언하여
데이터를 할당하고 redircet 형태로 할당된 데이터를 활용한다.

❗RedirectAttribute 는 GET 방식의 요청에서만 사용가능하다 !

RedirectAttribute 예시

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

사용자의 요청에 전달받은 itemid 를
saveItem 메소드의 id 데이터 로 할당하여

사용자의 itemid 가 변경될 때 마다
그 에 맞는 saveItem 메소드가 실행된다.

📌 BindingResult

Validation Check 에서 검증오류를 보관하는 객체
ex) 사용자가 int 필드에 String 값을 입력한 경우
타입오류로 발생하는 에러시 Spring BindingResult 에 자동으로 넣어준다.

이 부분을 개발자가 직접 검증을 수행해서 BindingResult 에 넣어줄 수 있다.

BindingResult 가 설정되어 있ㅎ으면
쿼리 파라미터를 Model Attribute에 객체로 바인딩하는 것에 실패해도
Controller가 실행된다.

❗ BindingResult 는 핸들러 매개변수에서 자신이 검증할 객체
바로 다음에 위치 시켜야한다

❗ BindingResult 는 Model 객체에 자동 할당된다.

BindingResult 예시

	/*
	 *  BindingResult : Item 객체에 값이 잘 담기지 않을 때, 
	 *  	BindingResult 객체에 값이 담긴다.
	 *  	Spring 에서 제공하는 검증 오류를 보관하는 객체, 검증 오류가 발생시 여기에 보관 
	 *  
	 *  	주의 ) BindingResult 는 검증할 대상 바로 다음에 설정해야한다 ( 순서 중요 ) 
	 *  	BindingResult 는 Model 에 자동으로 포함된다.
	 */
	@PostMapping("/add")
	public String saveV7( Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes) {

		// StringUtils.hasText
		// 값이 있을경우 true , 공백이나 null 들어올 경우에는 false를 반환하게 된다.
		if ( ! StringUtils.hasText(item.getItemName()) ) {
			// FieldError : Field 단위에 error를 처리하는 Spring 제공 객체 
			bindingResult.addError( new FieldError("item", "itemName", "상품 이름은 필수 입니다."));
		}
		
		// 검증에 실패하면 다시 addForm 화면으로 돌아가도록 설정
		
		if ( bindingResult.hasErrors()) {
			System.out.println("errors= " + bindingResult);
			return "basic/addForm";
		}
		
		// Price 조건
		
		if (item.getPrice() == null || item.getPrice() < 1000 
				|| item.getPrice() > 10000000) {
			bindingResult.addError( new FieldError("item", "price", "가격은 1000~1000000 사이여야합니다"));
		}
		
		// quantity 조건
		
		if ( item.getQuantity() == null || item.getQuantity() > 100000) {
			bindingResult.addError( new FieldError("item", "quantity", " 수량은 최대 9999개 까지 가능합니다"));
		}
		
		System.out.println("item.open = " + item.getOpen());
		System.out.println("item.regions = " + item.getRegions());
		System.out.println("item.itemType = " + item.getItemType());

		Item saveItem =  itemRepository.save(item);
		redirectAttributes.addAttribute("itemId", saveItem.getId());
		redirectAttributes.addAttribute("status",true);
	
		return "redirect:/basic/items/{itemId}";
	}
profile
Hyobin12

0개의 댓글