본문 바로가기
스프링/mvc패턴

[spring] 스프링 입문1. Controller->view 와 view->Controller

by CodeMango 2023. 2. 20.

스프링이란?

 

 

web.xml로 시작하는 스프링의 구조

 

 

controller와 view가 데이터를 주고 받을 수 있게 된다.

사용예제

1.web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
  <display-name>spSample1</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>dispatcherServlet</servlet-name>
  	<servlet-class>
  		org.springframework.web.servlet.DispatcherServlet
  	</servlet-class>
  	
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>
  			/WEB-INF/spring/servlet-context.xml		<!-- 설정할 파일 읽어오기 -->
  		</param-value>
  	</init-param>
  	
  	<load-on-startup>1</load-on-startup>  	
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>dispatcherServlet</servlet-name>
  	<url-pattern>*.do</url-pattern>
  	
<!--  *.do :확장자가 ".do"로 끝나는 모든 url(패턴)은 무조건 컨트롤러로 간다는 주문!
							 예) "/home.do", "/hello.do" 등-->
							 
 <!-- 1. index.jsp에서 home으로 이동을 클릭하면 HelloController.java의 value ="home.do"로 간다. 
 	  2. HelloController.java에서 return값인 home.jsp로 간다.
	  3. home.jsp 에서 controller에서 보내준걸 받아서 서버에 출력한다.-->
  </servlet-mapping>
  
  <!--  한글설정 : 스프링에서는 여기서 한번만 설정해주면 된다. -->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>
    	org.springframework.web.filter.CharacterEncodingFilter
    </filter-class>
    
    <init-param>
    	<param-name>encoding</param-name>	<!--  강하게 인코딩.. 써줘야함. -->
    	<param-value>UTF-8</param-value>
    </init-param>
    
    <init-param>
    	<param-name>forceEncoding</param-name>
    	<param-value>true</param-value>
    </init-param>
    
  </filter>
  
  <filter-mapping>
  	<filter-name>encodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>	<!--  /* : 모든패턴 -->
  </filter-mapping>
  
    
</web-app>

2. index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

 <!-- 1. index.jsp에서 home으로 이동을 클릭하면 HelloController.java의 value ="home.do"로 간다. 
 	  2. HelloController.java에서 return값인 home.jsp로 간다.
	  3. home.jsp 에서 controller에서 보내준걸 받아서 서버에 출력한다.-->
	  
<a href="home.do">home으로 이동</a>

</body>
</html>

3. home.jsp

<%@page import="mul.cam.a.dto.HumanDto"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
 <!-- 1. index.jsp에서 home으로 이동을 클릭하면 HelloController.java의 value ="home.do"로 간다. 
 	  2. HelloController.java에서 return값인 home.jsp로 간다.
	  3. home.jsp 에서 controller에서 보내준걸 받아서 서버에 출력한다. (home을 출력)-->
	  
<h1>home</h1>
<br>


<!-- -------------------------------------------------------------------------------------- -->

<!-- 🎈첫번째. Controller(Servlet) *.do -> View(html, jsp) 🎈
view(home)에서 컨트롤러로 이동시키고, 다시 컨트롤러에서 짐을 가져오기 
1. home.jsp에서 hello를 클릭하면 (view에는 안 보이게) hello.do를 가진 컨트롤러로 이동한다. 
2. 컨트롤러에서 addAttribute를 통해 name="홍길동"이라는 짐을 싸서 다시 home.jsp로 온다. 
3. 짐싼걸 getAttribute로 받아서 "서버창"에 출력한다. -->

<a href="hello.do">hello</a><br>
<%	
	//만약 name이 넘어왔다면 자바스크립트를 통해 이름:나 를 서버에 출력함.
	String name = (String)request.getAttribute("name");	
	if(name != null && !name.equals("")){	//이름이 null이 아니고 빈문자가 아닐때
		%>
		이름:<%=name %>
		<%
	}
%>
<br><br>

<!-- 🎈두번째. View(html, jsp) -> Controller(Servlet) *.do 🎈
view(home)에서 입력받은 것을 컨트롤러로 이동시켜서 출력시키고, home에서 다시 받기
1. home.jsp에서 form 태그를 통해 입력받은 name과 age를 world.do를 가진 컨트롤러로 이동시킨다.
2. 컨트롤러에서 public String world(String name, int age)를 통해 데이터를 받는다. 
3. 컨트롤러에서 받은 데이터를 "콘솔창"에 출력시킨다.
4. 컨트롤러에 머무를 순 없으므로 return "home"; 을 통해 home.jsp로 돌아온다.-->
<form action="world.do" method="post">
이름:<input type="text" name="name"><br>
나이:<input type="text" name="age">
<input type="submit" value="world로 이동">
</form>

<!--  form 과 a태그 다른점 :
 form은 method 방식을 고를 수 있다.
 form은 method="post"로도 보낼 수 있는데, a는 무조건 get으로만 보낸다! 
  
<a href="home.do?name=홍길동&age=24"></a>

<script type="text/javascript">
location.href = ""
</script>
 -->

<br><br>
<!-- 🎈두번째. View(html, jsp) -> Controller(Servlet) *.do 🎈 
view(home)에서 입력받은 것을 컨트롤러로 이동시켜서 출력시키고, home에서 다시 받기
1. home.jsp에서 form 태그를 통해 입력받은 name과 age를 main.do를 가진 컨트롤러로 이동시킨다.
2. (dto를 만들어놨다는 전제 하에) 컨트롤러에서 public String mainMethod(HumanDto human)를 호출해 dto의 데이터를 받는다.
3. 컨트롤러에서 System.out.println(human.toString()); 를 통해 dto의 toString을 "콘솔창"에 출력한다.
	(dto의 toString: "HumanDto [name=" + name + ", age=" + age + "]"; )
4. 컨트롤러에 머무를 순 없으므로 return "home"; 을 통해 home.jsp로 돌아온다.-->

<form action="main.do" method="post">
이름:<input type="text" name="name"><br>
나이:<input type="text" name="age">
<input type="submit" value="main로 이동">
</form>

<br><br>

<!--   
		mylist.do 만드는 과제
		-> list 사용
		-> 출력은 table로
		
<과제 해설>
1. home.jsp에서 mylist.do를 통해 컨트롤러에 보내는데, a태그로 message를 같이 보내준다. 
2. 컨트롤러에서 public String mylist(String message, Model model)을 통해 message를 받는다.
3. 컨트롤러에서 System.out.println("message:" + message);를 통해 "콘솔창"에 message:하이 를 출력한다.
4. 컨트롤러에서 리스트를 생성하여 list.add를 통해 데이터를 추가한다.
5. 컨트롤러에서 model.addAttribute("list", list);를 통해 짐싸고 return "home"으로 home.jsp로 보낸다.
6. home.jsp에서 List<HumanDto> list = (List<HumanDto>)request.getAttribute("list");를 통해 짐을 받는다.
   (코드 해석은 아래에 필기)
결과 : 서버창에서 my list를 클릭하면 콘솔창에는 message:하이 가 출력되고,
	  서버창에는 홍길동, 성춘향, 일지매의 번호, 이름, 나이 데이터테이블이 출력된다.
 --> 

<!-- mylist.do를 통해 컨트롤러에 보내는데, a태그로 message를 같이 보내준다. -->
<a href="mylist.do?message=하이">my list</a> 
<br><br>  
<%
/*<코드해석> List<HumanDto> list = (List<HumanDto>)request.getAttribute("list");
 1) 컨트롤러에서 model.addAttribute("list", list); 를 통해 object로 보내줬다.  
 2) object타입을 List<HumanDto>타입으로 형변환 해줘야 list로 바뀌므로, 형변환 해준다.
 3) 이를 다시 List<HumanDto> 타입의 변수 list에 할당해준다.
이렇게 하면 list 변수에 request 객체의 속성으로 설정된 list라는 이름의 리스트가 할당된다.
*/
	List<HumanDto> list = (List<HumanDto>)request.getAttribute("list");
	if(list != null && list.isEmpty() == false){
	// 조사순서도 중요함. list != null 조사 후에 list.isEmpty() 조사한다.
	// 이 경우에 isEmpty부터 조사 못함. list는 처음엔 null이니까
		%> 
		
		<table border="1">
		<tr>
			<th>번호</th> <th>이름</th> <th>나이</th>
		</tr>
		<%
			for(int i = 0;i < list.size(); i++){
				HumanDto dto = list.get(i);	//list로 넘어온걸 하나하나 dto에 집어넣는다.
			%>
				<tr>
					<th><%=i + 1 %></th>
					<td><%=dto.getName() %></td>
					<td><%=dto.getAge() %></td>
				</tr>
			<%
			}		
		%>
		</table>
		<%
	}
%>

</body>
</html>

4. HelloController.java

package mul.cam.a;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import mul.cam.a.dto.HumanDto;

// 컨트롤러를 만들고 가장 먼저 해야할 일 : @Controller 작성
@Controller
public class HelloController {
	
	//로그(Logger)를 사용할 준비하기
	// *Logger, LoggerFactory는 org.slf4j 로 추가할 것
	private static Logger logger = LoggerFactory.getLogger(HelloController.class);
				//클래스명,  인스턴스명
	
	//요청할 맵핑
	//web.xml에서  *.do패턴이면 무조건 컨트롤러로 온다고 주문해놨으므로 
	//value값을 .do로 끝낸다.
	
	@RequestMapping(value = "home.do", method = RequestMethod.GET)
	public String homeMethod() {
		
		// 아래 코드 대신 logger를 사용한다.
		// System.out.println("HelloController homeMethod() " + new Date());
		
		// Logger : System.out.println 대신 사용하는 로그. 
		// 로그 장점: 원하는 레벨 이상의 로그만 출력, 로그 파일에 저장 가능, print보다 가벼움.
		logger.info("HelloController homeMethod() " + new Date());
		
		return "home";	// return : home.jsp로 보내라는 의미
	}
	
	//home.jsp에서 <a href="hello.do">hello</a><br>를 통해 컨트롤러로 왔고, 짐싸서 다시 보내기.
	@RequestMapping(value = "hello.do", method = RequestMethod.GET)
	public String hello(Model model) {	//Model1 model 객체를 추가한다.(짐싸서 보내기 위해)
		
		String name = "홍길동";
		
		// 짐싸!
		//model.addAttribute : 전에는 request.setAttribute로 보냈는데, 스프링에서는 다른 방법으로 보낸다
		model.addAttribute("name", name);	//"name"으로 name을 보내기
		
		// 잘가!
		return "home";	// return : 다시! home.jsp로 보내라는 의미
	}
	
	//home.jsp에서  form 태그를 통해 입력받은 name과 age를 보내준 상황.
	//servlet에서는 req.getParameter로 받았으나, 
	//스프링 컨트롤러에서는 public String world(String name, int age) 로 받아준다.
	
//* get이든 post든 상관없게 만들려면 아래와 같이 쓴다.
	//@RequestMapping(value= "world.do", method = {RequestMethod.GET, RequestMethod.POST})
	@RequestMapping(value = "world.do", method = RequestMethod.POST)
	public String world(String name, int age) {	//매개변수가 여기로 따라 들어옴.
		//초기 매개변수는 string였지만, int로 바꿔서 들어올 수 있다.
	
		
		logger.info("HelloController world() " + new Date());
		
		System.out.println("이름:" + name);
		System.out.println("나이:" + age);
		
		return "home";	// return : 다시! home.jsp로 보내라는 의미
						// 컨트롤러에 머무를 순 없으니까 결국에 home으로 다시 보내주긴 해야한다.
	}
	
//* get이든 post든 상관없게 만들려면 아래와 같이 쓴다.
	//@RequestMapping(value= "main.do", method = {RequestMethod.GET, RequestMethod.POST})
	
	@RequestMapping(value = "main.do", method = RequestMethod.POST)
	
	//home.jsp에서 입력받은 데이터를 받아올때, 스프링에서는 dto로 받을 수 있다!
	public String mainMethod(HumanDto human) {
		logger.info("HelloController mainMethod() " + new Date());
		
		System.out.println(human.toString());
		
		return "home";	// return : 다시! home.jsp로 보내라는 의미
	}
	
	//* get이든 post든 상관없게 만들려면 아래와 같이 쓴다.
		//@RequestMapping(value= "mylist.do", method = {RequestMethod.GET, RequestMethod.POST})
	
	//* @RequestMapping 대신에 쓸 수 있는 것들도 있다.
		// @PostMapping, @GetMapping 사용가능 -> get인지 post인지 확실할 때만 쓸 수 있음
		// a 태그로 보냈으면 get으로만 받을 수 있으므로 @GetMapping("mylist.do") 사용가능
		// 구글링 시 당황하지 않기 위해 알고있기.
		//a태그로 보냈으니까 GET으로 풀어줘야함.

	
	// 7교시 과제 : mylist.do를 만들고, list아용, table로 출력해라.
	@GetMapping("mylist.do")
	//message를 String으로 넘겨줬으니까 String으로 받는다
	//예전에는 request.getParameter로 받았지만, 스프링에서는 message라는 매개변수로 받을 수 있다.
	public String mylist(String message, Model model) {	//model아무데나 추가해도됨
		logger.info("HelloController Get mainMethod() " + new Date());
		
		System.out.println("message:" + message);
		
/*<HumanDto> : HumanDto 클래스의 인스턴스를 List 객체의 요소로 사용하기 위해 지정된 것!
 따라서 List 객체의 요소로 사용했다는 것은 해당 List 객체에는 특정 클래스의 인스턴스들이 저장될 수 있다는 것을 의미함.
 객체 생성과는 조금 다른 개념이긴 하지만, List 객체 안에 저장될 요소의 자료형을 명시해주는 것은 
 객체를 생성할 때 클래스의 타입을 지정하는 것과 유사한 개념이라고 볼 수 있음.
*/

//List<HumanDto> list = new ArrayList<>(); : 
//HumanDto 객체를 저장할 수 있는 ArrayList를 생성하고 이를 List<HumanDto> 타입의 list 변수에 할당	

	List<HumanDto> list = new ArrayList<>(); 
//위 코드는 List<HumanDto> list = new ArrayList<HumanDto>(); 를 간결하게 쓴 버전		

		list.add(new HumanDto("홍길동", 24));
		list.add(new HumanDto("성춘향", 16));
		list.add(new HumanDto("일지매", 22));
		
		//짐싸!
		//model.addAttribute : 전에는 request.setAttribute로 보냈는데, 스프링에서는 다른 방법으로 보낸다
		model.addAttribute("list", list);
		
		return "home";	// 다시 home.jsp로 보낸다.
	}
	
}

5.HumanDto.java

package mul.cam.a.dto;

import java.io.Serializable;

public class HumanDto implements Serializable{
	
	private String name;
	private int age;
	
	public HumanDto() {
	}

	public HumanDto(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "HumanDto [name=" + name + ", age=" + age + "]";
	}
	
}

댓글