Spring 데이터흐름: Controller ↔ View

코딩하는 포로리·2022년 2월 19일
1

Spring

목록 보기
8/10
post-thumbnail

📌 1. Conteroller to View


📎 개요

MVC패턴에서 Controller와 View가 서로 데이터를 전송하는 방법이 여러가지가 있다. 이 포스팅에서 먼저 Controller에서 View로 데이터를 보내는 방법을 알아보고, 다음으로 View에서 Controller로 데이터를 보내는 방법을 알아보려고 한다.

📎 Model

메소드의 파라미터로 Model을 추가하고, addAddtribute("속성명","값") 메소드로 View에서 사용할 데이터를 전달 한다.

👉 Model 객체 기능

메소드설명
addAttributeModel에 속성추가
getAttributeModel에 있는 속성을 조회
addAttributesModel에 속성을 여러개 추가
getAttributesModel에 속성을 여러개 조회
containsAttributesModel에 특정한 속성이 있는지 확인
mergeAttributesModel 두개를 합침

👉 Controller에서 Model 코드 작성

@RequestMapping(value="/modelEx" , method=RequestMethod.GET)
public String modelEx(Model model) {
		
	List<MemberDto> memberList = new ArrayList<MemberDto>();
	MemberDto mdto;
		
	for (int i = 1; i < 11; i++) {
		mdto = new MemberDto();
		mdto.setId("아이디"+i);
		mdto.setPassword("1111");
		mdto.setName("이름"+i);
		mdto.setEmail("anon@anon.com");
		memberList.add(mdto);
	}
		
	model.addAttribute("method" , "Model");
	model.addAttribute("memberList", memberList);
		
	return "dataTransfer/memberList";
		
}

👉 Controller에서 model로 보내온 데이터를 JSP로 받음

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h2>${method }</h2>
	<table border="1">
		<tr>
			<th>아이디</th>
			<th>비밀번호</th>
			<th>이름</th>
			<th>이메일</th>
		</tr>
		<c:forEach var="member" items="${memberList }">
			<tr align="center">
				<td>${member.id}</td>
				<td>${member.password}</td>
				<td>${member.name}</td>
				<td>${member.email}</td>
			</tr>
		</c:forEach>
	</table>
</body>
</html>

📎 ModelAndView

ModelAndView객체를 생성하여 addObject("속성명", "값") 메소드로 View에서 사용할 데이터를 전달 한다.

관용적으로 객체명을 mv 혹은 mav로 작성한다.

👉 Model과 ModelAndView 차이점

실제로 2가지 방법에는 성능차이가 없다. 단지, ModelAndView는 Model에서 기능을 추가한 것으로 Model과 View를 동시에 설정이 가능하다.

더 디테일하게 설명하면 Model파라미터 방식으로 메소드에 (Model model)파라미터를 넣어주고 String 형태로 리턴한다. 값을 넣을때도 addAttribute()를 사용한다.

반대로 ModelAndView컴포넌트 방식으로 ModelAndView 객체를 생성해서 객체형태로 리턴한다. ModelAndView는 말그대로 Model과 View를 합쳐놓은 것으로, 값을 넣을때 addObject()를 사용하고, setViewName()으로 보낼 곳 View를 세팅한다.

👉 ModelAndView 객체 기능

메소드설명
setViewNameview 이름을 설정
getViewNameview 이름을 조회
setViewview 설정
getViewview 조회
hasView설정되어있는 view가 있는지 확인
getModelMap내부의 모델 Map 조회
getModel내부 모델 조회
getStatus상태 설정

👉 Controller에서 ModelAndView 코드 작성

@RequestMapping(value="/modelAndViewEx" , method=RequestMethod.GET)
public ModelAndView modelAndViewEx() { // return 타입은 String이 아닌 ModelAndView 클래스타입을 작성한다.
		
	List<MemberDto> memberList = new ArrayList<MemberDto>();
	MemberDto mdto;
		
	for (int i = 11; i < 21; i++) {
		mdto = new MemberDto();
		mdto.setId("아이디"+i);
		mdto.setPassword("1111");
		mdto.setName("이름"+i);
		mdto.setEmail("anon@anon.com");
		memberList.add(mdto);

		//ModelAndView mv = new ModelAndView(); // ModelAndView 객체 생성
		//mv.setViewName("dataTransfer/memberList"); // view 파일명 작성
		
		ModelAndView mv = new ModelAndView("dataTransfer/memberList");
		
		mv.setViewName("method" , "ModelAndView");
		mv.addObject("memberList" , memberList);
		
		return mv;							  // ModelAndView 객체를 반환
		
	}	

📎 httpServeletRequest

HttpServletRequest객체를 생성하여 setAttribute("속성명", "값") 메소드로 View에서 사용할 데이터를 전달 한다.

@RequestMapping(value="/requestEx" , method=RequestMethod.GET) 
public String requestEx(HttpServletRequest request) {
		
	List<MemberDto> memberList = new ArrayList<MemberDto>();
	MemberDto mdto;
		
	for (int i = 21; i < 31; i++) {
		mdto = new MemberDto();
		mdto.setId("아이디"+i);
		mdto.setPassword("1111");
		mdto.setName("이름"+i);
		mdto.setEmail("anon@anon.com");
		memberList.add(mdto);
	}
		
	request.setAttribute("method", "Request");
	request.setAttribute("memberList", memberList);
		
	return "dataTransfer/memberList";
		
}

📎 ResponseBody

ResponseEntity와 기능이 같으며 헤더와 상태 코드를 제외한 html 본문만 전송한다.

한글 데이터가 전송이 되지 않으며 한글 전송시 ResponseEntity의 객체의 객체명.add("Content-Type", "text/html; charset=utf-8") 메소드를 이용하여 헤더 정보를 추가하여 사용한다.

@RequestMapping(value="/responseBodyEx" , method=RequestMethod.GET)
public @ResponseBody String responseBodyEx() {

	String message  = "<script>";
			  message +=    "alert('html page');";
			  message +=    "location.href = 'modelEx';";
			  message += "</script>";
	    
	return message;			  
	
}

📎 ResponseEntity

HTTP에서 RequestResponse 동작시 전송되는 정보는 크게 body(몸체) , headers(헤더), status code(상태 코드)가 있다.

@ResponseBody 에는 없는 헤더와 상태코드가 함께 들어간다.

@RequestMapping(value="/responseEntityEx" , method=RequestMethod.GET)
public ResponseEntity<Object> responseEntityEx(){
		
	//1) return new ResponseEntity<Object>(HttpStatus.OK);
		
	//2) return new ResponseEntity<Object>(data , HttpStatus.OK);
		
	//3)
	HttpHeaders responseHeaders = new HttpHeaders();
	responseHeaders.add("Content-Type", "text/html; charset=UTF-8");
		
	String data = "<h1>html페이지를 반환합니다.</h1>";
	return new ResponseEntity<Object>(data , responseHeaders ,HttpStatus.OK);		
		
	}
	
}

📎 RestController

ResponseBody와 기능이 같으며 헤더와 상태 코드를 제외한 html 본문만 전송한다.

클래스에 @RestController어노테이션을 작성하여 구현한다.

@RestController
class RestControllerEx {
		
	@RequestMapping(value="/restControllerEx" , method=RequestMethod.GET)
	public String restControllerEx() {
		
		String message  = "<script>";
		   message +=    "alert('html page');";
		   message +=    "location.href = 'modelEx';";
		   message += "</script>";
		
		return message;
		
	}
	
}



📌 2. View to Controller


📎 HttpServletRequest

HttpServletRequest를 직접 이용하여 getParameter 메소드를 이용하여 파라미터의 값에 접근 할 수 있다. JSP에서의 사용법과 동일하다.

@RequestMapping(value="/transfer1" , method=RequestMethod.POST)
public String transfer1(HttpServletRequest request) {
		
	System.out.println("\n transfer1 \n");
	System.out.println("id : "       + request.getParameter("id"));
	System.out.println("password : " + request.getParameter("password"));
	System.out.println("name : "     + request.getParameter("name"));
	System.out.println("email : "    + request.getParameter("email"));
	System.out.println();
		
	return "home";
}

📎 커멘드 객체

HttpServletRequest 방법은 요청 파라미터 개수가 증가할때마다 코드의 길이도 길어지는 단점이 있다. 만약 파라메타의 개수가 20개면 파라미터의 값을 읽어와 설정하는 코드만 최소 40줄 이상 작성해야 한다.

하지만 커멘드 객체는 POJO를 이용하여 훨씬 간결한 코드를 작성할 수 있게 해준다. name의 요청 파라미터의 값을 커맨드 객체(pojo)의 setter 메서드를 사용해서 커맨드 객체에 전달한다.

@RequestMapping(value="/transfer2" , method=RequestMethod.POST)
public String transfer2(MemberDto mdto) {
		
	System.out.println("\n transfer2 \n");
	System.out.println("id : "       + mdto.getId());
	System.out.println("password : " + mdto.getPassword());
	System.out.println("name : "     + mdto.getName());
	System.out.println("email : "    + mdto.getEmail());
	System.out.println();
		
	return "home";
		
}

📎 Map

Map 컬렉션 프레임워크를 이용하여 요청파라미터에 접근이 가능하다.

@RequestMapping(value="/transfer3" , method=RequestMethod.POST)
public String transfer3(@RequestParam Map<String,String> memberMap) {
		
	System.out.println("\n transfer3 \n");
	System.out.println("id : "       + memberMap.get("id"));
	System.out.println("password : " + memberMap.get("password"));
	System.out.println("name : "     + memberMap.get("name"));
	System.out.println("email : "    + memberMap.get("email"));
	System.out.println();
		
	return "home";
		
}

📎 [특정 값만 입력받기] requestParam 이용

요청 파라미터의 개수가 얼마 되지 않는다면 @RequestParam 어노테이션을 사용하여 파라메타의 값에 접근 할 수 있다.

👉 @RequestParam 어노테이션 속성

  • name : 파라메타의 이름을 지정한다.
  • required : 필수 여부를 지정한다. 기본값은 true이며 요청값이 없으면 익셉션이 발생한다.
  • defaultValue : 요청 파라미타의 값이 없을때 사용할 값을 지정한다.
@RequestMapping(value="/transfer4" , method=RequestMethod.POST)
public String transfer4(@RequestParam(name="id" , defaultValue = "anonymous")  String id ,
						@RequestParam(name="password" , defaultValue = "1111") String password) {
		
	System.out.println("\n transfer4 \n");
	System.out.println("id : "       + id);
	System.out.println("password : " + password);
	System.out.println();
		
	return "home";
		
}	

📎 [특정 값만 입력받기] parameter에 직접 name값만 입력

메서드의 파라미터에 name값을 직접 입력하여 파라메타에 접근이 가능하지만, 가독성 향상 및 코드의 통일성을 위해 @RequestParam 어노테이션 사용을 권장한다.

@RequestMapping(value="/transfer5" , method=RequestMethod.POST)
	public String transfer5(String id , String password , String name) {
		
		System.out.println("\n transfer5 \n");
		System.out.println("id : " + id    );
		System.out.println("password : " + password);
		System.out.println("name : " + name);
		System.out.println();
		
		return "home";
		
	}



📖 참고

0개의 댓글