97일차 Spring Controller에 대해

쿠우·2022년 8월 18일
0

-이전 중요부분 복습

Spring MVC 기반으로 웹어플리케이션 개발시 중요한 2가지 종류의 클래스를 개발
이게 아주 중요!

(1) DTO == Data Transfer Object

== 데이터를 전달하는게 목적인 객체
==> 웹브라우저의 화면에서 사용자가 입력한 "전송파라미터들"을 수집해서, 이를 필요로하는 어떤 계층(웹3계층: 표현/비지니스/영속성)에서든 전달할 목적
==> 방향: 표현계층에서 수집 => 비지니스 계층으로 전달, 영속성 계층으로 전달

(2) VO == Value Object == 소위 "값객체"라고도 부름

== 데이터를 전달하는게 목적인 객체
==> Database 의 1개의 테이블의 1개의 레코드를 저장(immutable, read-only)하는게 역할
==> 이를 필요로하는 어떤 계층(웹3계층: 표현/비지니스/영속성)에서든 전달할 목적
==> 방향: 영속성계층에서 수집 => 비지니스 계층으로 전달, 표현 계층으로 전달

계층

<표현> ---- <비지니스,서비스> ----- <영속성> ---- [데이터베이스]


-Controller 예제들

DTO가 없는데 전송파라미터를 어떻게 얻느냐

우리가 만든 컨트롤러 핸드러 메소드가 필요로 하는 "전송파라미터"를 얻는 방법
=> 그저, DispatcherServlet 에게 요청하면 된다. (매개변수로)
=> 값을 넣지 않으면 null값을 넣어준다.
=> 따라서 기본타입을 넣어서는 안된다.
=> 또한 넣어야하는 값이 무수히 많아진다면??? 무수히 많은 매개변수를 만들어야겠지 따라서 DTO를 만들어 사용한다.

=>응답이 나가기전까지만 살아있는 RequestScope에 올라가는 공유속성인 Command Object은 전송파라미터를 한꺼번에 얻어내고 수집하는 용도로 쓰는 객체다. 그 이름은 DTO클래스의 첫글자만 소문자로 바꿔서 사용한다.

	@GetMapping("/ex01")
	public String ex01(ParamsDTO param) { 
		log.trace("ex01({}) invoked.",param);
		
		
		// View Resolver의 설정에 따라 
		// Prefix +ViewName + Suffix  =  /WEB-INF/views/ +  /ex01 +  .jsp
		return "ex01"; // MVC패턴에서 , View의 이름 
	}// ex01
// DTO클래스는 그저 "자바빈즈" 클래스 이면 된다. 
// 이 DTO 클래스는 왜 만들었습니까? 컨트롤러의 핸들러 메소드에서, 전송파라미터들을 한방에 수집

@Data
public class ParamsDTO {
	private String param1;
	private String param2;
	private String param3;
	private String param4;
	private String param5;
}// end class

@RequestParam 사용 예제

매개변수가 전송파라미터와 다른 명칭일 때 입력 받을 전송파라미터의 명칭과 연결해준다.

	@GetMapping("/ex02")
	// 지정하는 매개변수의 이름은 기본적으로 전송파라미터의 이름과 동일해야한다. 
	// DispatcherServlet이 이름에 맞는 전송파라미터의 값을 자동으로 넣어주기 때문에
	public String ex02(
			@RequestParam("name") String recvName, 
			@RequestParam("age") Integer cuurentAge) { 
		log.trace("ex02(recvName,cuurentAge) invoked.");
	

		return "ex02";
	}// ex02

@RequestParam 사용 예제2

동일 속성명으로 여러 값을 받아야하는 경우(취미: 축구 농구 독서 ~)
전송파라미터의 다중 값을 컬렉션 프레임워크에 담아 줄때 사용한다.

	@GetMapping("/ex03")
//	public String ex03(List<String> hobby) {  xx : java.lang.IllegalStateException
//	public String ex03(ArrayList<String> hobby) {    ox: 오류 발생은 안하는데, 실제 값은 들어오지 않음
//	public String ex03(@RequestParam("hobby") List<String> hobby) {   OK : 배열로는 정적으로 다중값 전송파라미터 송신완료
//	public String ex03(@RequestParam("hobby") ArrayList<String> hobby) {    OK : 배열로는 정적으로 다중값 전송파라미터 송신완료
	public String ex03(String[] hobby) {		// OK : 배열로는 정적으로 다중값 전송파라미터 송신완료
		log.trace("ex03({}) invoked.");
	

		return "ex03";
	}// ex03

@DateTimeFormat 사용 예제

전송파라미터에 날짜포맷형식으로 전달될때 날짜형태의 포맷으로 변환해준다. 대신 형식을 지정해줘야한다.

	@GetMapping("/ex04")
	public String ex04(
			@DateTimeFormat(pattern="yyyy-MM-dd")
			Date hireDate) {		
		log.trace("ex04({}) invoked.",hireDate);
	
		return "ex04";
	}// ex04

DTO와 model 객체를 이용한 비즈니스 데이터 저장

  • model은 map형식으로 값을 담는다.
	@GetMapping("/ex05")
	public String ex05(
			// 1. 각 전송파라미터의 값 획득 from DispatcherServlet 
			//String name, Integer age,
			SampleDTO dto, Integer page,
			// 2. 핵심 비지니스 로직의 수행 결과데이터를 저장 및 View에 전달하는 상자
			Model model) {		
		log.trace("ex05({},{},{}) invoked.",dto,page,model);
		
		log.info("\t + model type:{}" , model.getClass().getName());
		
		// Model 상자에 저장할 객체 생성
//		SampleDTO dto = new SampleDTO();
//		dto.setName(name);
//		dto.setAge(age);
		
		// 비지니스 데이터를 저장하는 "상자" 역할을 하는 Model 객체
//		model.addAttribute("sampleDTO",dto);
		model.addAttribute("page",page);
		
		
		return "commandObject"; // 반환된 뷰의 이름
	}// ex05
	

@ModelAttribute 사용 예제

(공유영역에 Map 형식으로 model에 전달해주는 어노테이션 )
Post전송방식으로의 전송파라미터 받는 방법

	@PostMapping("/ex06")
//	public String ex06(SampleDTO dto, Integer page) {	 page 값이 전달이 안된다.	
	public String ex06(SampleDTO dto, @ModelAttribute("page") Integer page) {		
		log.trace("ex06({}) invoked.",dto, page);
	
		return "commandObject";
	}// ex06

스프링에서 리다이렉션 하는 법

	@GetMapping("/ex07")
	public String ex07(
			String name, Integer age,
			// Model 상자와 비슷한 역할 - 임시상자역할: 
			//  리다이렉션의 Target URL에 전달할 전송파라미터를 보관하는 역할.
			RedirectAttributes rttrs) {		
		log.trace("ex07({},{},{}) invoked.", name, age,rttrs);
		
		// 1. 1회성 데이터 전달 => Request Scope 에 공유속성으로 올려서 전달 (공유)
		// 이것을 사용 할 때, 사용하는 것을 고민해보라 (아래의 방법을 사용하라)
//		rttrs.addFlashAttribute("name", name);
//		rttrs.addFlashAttribute("age", age);
		
		//2. 전송파라미터로 전달 => GET 방식의 Query String 형태로 전달 
		rttrs.addAttribute("name", name);
		rttrs.addAttribute("age", age);
		
		// redirect: 가. 특수문자열 뒤에는, 재요청을 보낼 Target URL 지정
		//			 나. 이 반환된 문자열은 View의 이름이 아니다! => View가 호출되지 않는다.
		// 			 다. 바로 307 Redirect 응답문서가 즉시 전송됩니다. 
		return "redirect:/board/ex02"; 
		
		
		// 1번은 오류나는 이유는  Request Scope에 담아서 보내기 때문에 오류난다.
		// Request Scope는 redirect될 때 소멸
		// 2번은 localhost:8080/board/ex07?name=~~&age=~~ 형식으로 리다이렉트 된다. 
		
		
	}// ex07

@RequestMapping의 테이블

이런식으로 쭈루루룩 확인가능 짜여진 스토리 보드에 화면구현에 따라서 매핑을 나눠보라고 하셨음.

profile
일단 흐자

0개의 댓글