본문 바로가기

programming/Gukbi

국비 교육 64일차 - EL, MVC구조, JSTL

728x90
반응형

오늘은 마지막에 프로젝트 시간 없이 온전히 수업만 8시간을 나갔다. 그만큼 좀 정신없이 진도가 나갔는데 잘 정리해보도록 하겠다. 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%--
		EL : 화면 출력
			 out.println("")
			 <%= %>
			 ${}
			 목적 : 자바 / HTML ===> MV패턴
			 					   Model => 자바
			 					   View => HTML (JSP)
			 			      ===> MVC 패턴
			 			      		Model => 자바
			 			      		View => HTML(JSP)
			 			      		Controller => 자바와 JSP를 연결
		EL
		 연산자 처리
		 메소드 처리
		 처리 영역
		 ${일반 변수 출력이 아니다}
		 예) 
		 	String name="홍길동";
		 	${name} (X)
		 	request.getAttribute("name");
		 	session.getAttribute("")	 			      			
			 			   
 --%>
<%
	String name="이제노";
	request.setAttribute("name", name);
	// ${requestScope.name}
	//				  ===== 키명
	session.setAttribute("name", "황런쥔");
	// 우선 순위 => request, session, application 
	// 자바에서 데이터를 보낸다 (request, session)
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	이름:${name },${requestScope.name}<br>
	<%= request.getAttribute("name") %><br>
	${sessionScope.name }, ${nick }
</body>
</html>

 

 mvc구조는 자바영역(model), 뷰영역이 완전히 분리되어 있고 그걸 연결해주는 controller가 합쳐진 구조이다. 지금까지는 jsp에서 <%= %>을 혼합해서 써왔는데, 이제 분리를 해서 사용하는 법을 배웠다. 

 

자바 영역에서 값을 채워준뒤, request에서 그 내용을 전달해주는 방법이다. 위의 경우 setAttribute로 값을 채워줘서 getAtrribute로 받아왔다. 

 

package com.sist.model;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
/*
 * 	class HttpServletRequest
 * {
 * 	int a=10;
 * }
 * 
 * 	request를 받는곳 : JSP, 서블릿
 */
public class SawonModel {
	public void sawonInit(HttpServletRequest request)
	{
		String name="황런쥔";
		request.setAttribute("name", name);
	}
	public void sawonDetailData(HttpServletRequest request)
	{
		SawonVO vo=new SawonVO(1, "이제노", "드림");
		// vo=> jsp로 전송
		request.setAttribute("vo", vo);
	}
	public void sawonTwoData(HttpServletRequest request)
	{
		String firstName="박";
		String lastName="지성";
		request.setAttribute("first", firstName);
		request.setAttribute("last", lastName);
	}
}

  혹은 아예 파일을 분리해서 자바 파일 (model)에 값을 설정해두고 그 값을 jsp에서 받아오는 방법도 있다. 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="com.sist.model.*"%>
<jsp:useBean id="model" class="com.sist.model.SawonModel"></jsp:useBean>
<%
	// Controller 영역 : 클라이언트가 요청 => 요청을 받아서 해당 Model을 찾고
	// 메소드를 호출
	model.sawonInit(request); // Call By Reference
	model.sawonDetailData(request); // vo를 받아옴
	model.sawonTwoData(request);
	/*
		어노테이션 : if문 대신 사용하는 것
		url주소로 호출 가능
	*/
%> 
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	이름 : ${name } <br>
	사번 : ${vo.sabun }, ${vo.getSabun() }<br> 
	이름 : ${vo.name }<br>
	그룹 : ${vo.dept }<br>
	이름 : ${first+=last }
</body>
</html>

 이런식으로 자바빈을 통해서 패키지와 클래스를 받아온 뒤 메소드를 호출할 수 있다. 

 

<%@ 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>
	<%-- 산술연산자는 순수하게 산술처리만 한다 --%>
	10+20=${10+20 } <br>
	"10"+"20"=${"10"+"20" }<br>
	
	10/3=${10/3 } <br>
	
	"10"+="20"=${"10"+="20" }<br>
	
	${10==20}, ${"10"!="20" } <br>
	<%
		String name="";
	request.setAttribute("name", name);
	%>
	${empty request.getAttribute("name") }
</body>
</html>

 el 안에서도 위와 같이 연산자를 사용할 수 있다. 다만 주의할 점은 문자열 결합은 +가 아니라 +=로 적어줘야 한다. 

 

 

그 다음은 JSTL에 대해서 배웠다. JSTL은 태그형으로 자바 문법을 제작하는 구조이다. 변수 설정, URL 불러오기, 제어문의 사용이 가능해진다. 즉 원래 사용하던 JSP구조보다 훨씬 간편해진다. 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
	JSTL => 태그형으로 자바 문법을 제작
	core : 변수설정, URL, 제어문
			1) 변수 설정
				<c:set var="s" value="Hello">
				String s="Hello"; (X)
				request.setAttribute("s", "Hello") (O)
				<c:set var="s" value="10">
				=== prefix
				
			2) URL 
				<c:redirect url="">
				response.sendRedirect("")
				
			3) 제어문
				조건문 : 단일조건문만 사용이 가능 
				if(조건)
				{
				}
				
				<c:if test="조건">
				</c:if>
				선택문 
				switch(값)
				{
					case 값 : 처리
					==
					==
					==
				}
				
				<c: choose>
				 <c:when test="조건">처리값</c:when>
				 <c:when test="조건">처리값</c:when>
				 <c:when test="조건">처리값</c:when>
				 <c:otherwise>Default</c:when>
				</c: choose>
				반복문
				 for(int i=1; i<=10; i++)
				 
				 <c:forEach var="i" begin="1" end="10" step="1">
				 							  ========  =======
				 							  포함		step="1"일 경우 생략이 가능
				 							  			단점 : 감소할 수 없다
				 for(MovieVO vo:list)
				 
				 <c:forEach var="vo" items="list">
				 
				 StringTokenizer st=new StringTokenizer(s, ",");
				 <c:forTokens var="ss" value="s" delimit=",">
	fmt : 날짜 변환, 숫자 젼환
				<fmr:formatDate> SimpleDateFormat
				<fmt:formatNumber> String.format()
	fn : String, Collection 
			${fn:replace()}
			${fn:substring()}
	xml : XML 파싱 => OXM
	sql : SQL => ORM => MyBatis, DAO, Service
 --%>
<%
	String name="이제노";
	// 					   var="name" value="황런쥔"
	//request.setAttribute("name", name);
%>
<c:set var="name" value="황런쥔"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	이름:<%=name %> <br>
	이름:${name }<br>
	<%
		if(name.equals("이제노"))
		{
	%>
			<b>이름은 <%=name %>입니다</b>
	<% 		
		}
	%>
	<br>
	<c:if test="${name=='황런쥔' }">
		<b>이름은 ${name }입니다</b>
	</c:if>
</body>
</html>
<%@ 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>
	<h3>Java이용</h3>
	<%
		for(int i=1; i<=10; i++)
		{
			if(i%2==0)
			{
	%>
			<%=i %>는 짝수입니다 <br>
	<% 
			}
			else
			{
	%>
			<%=i %>는 홀수입니다 <br>
	<% 
			}
		}
	%>
	<%--
		태그가 XML형식으로 만들어져 있다
		속성="", '' 대소문 구분
		여는 태그와 닫는 태그가 명확해야 된다
	 --%>
	<h3>JSTL이용</h3>
	<c:forEach var="i" begin="1" end="10" step="1">
	 <c:if test="${i%2==0 }">
	 	${i }는 짝수입니다 <br>
	 </c:if>
	 <c:if test="${i%2!=0 }">
	 	${i }는 홀수입니다 <br>
	 </c:if>
	</c:forEach>
</body>
</html>

 위의 코드는 자바를 이용해서 만든 홀짝 예제이고, 아래는 JSTL을 이용해서 만든 예제이다. 누가봐도 아래가 더 간편하다는 것을 알 수 있다. 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%
	List<String> list=new ArrayList<String>();
	list.add("chenle");
	list.add("jeno");
	list.add("renjun");
%>
<%-- request.setAttribute("list",list) --%>
<c:set var="list" value="<%=list %>"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3>일반 자바</h3>
	
	<h3>JSTL 사용(일반변수는 사용할 수 없다, request,session)</h3>
	<ul>
	<c:forEach var="name" items="${list }">
		<li>${name }</li>
	</c:forEach>
	</ul>
</body>
</html>

 forEach의 사용도 가능해진다. 위의 자바 영역에서 만들어준 list에서 forEach를 사용해서 전부 출력해주는 코드를 완성했다. 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	String color="red,green,blue,yellow,black";
	request.setAttribute("color", color);
	//
%>
<%--
	<c:set var="color" value="<%=color"%>"> 권장사항
 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3>자바사용</h3>
	<ul>
	<%
		StringTokenizer st=new StringTokenizer(color, ",");
		while(st.hasMoreTokens())
		{
	%>
			<li><%=st.nextToken() %></li>
	<%
		}
	%>
	</ul>
	<h3>JSTL 사용</h3>
	<ul>
		<c:forTokens var="col" items="${color }" delims=",">
		<li>${col }</li>
		</c:forTokens>
	</ul>
</body>
</html>

 StringTokenizer도 마찬가지로 태그형으로 사용할 수 있다. 콤마 단위로 출력해서 리스트 형식으로 출력해준다. 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<%-- 다중 조건문 --%>
<c:set var="star" value="5"/>
<c:set var="sex" value="여자"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<c:choose>
	 <c:when test="${star==1 }">★</c:when>
	 <c:when test="${star==2 }">★★</c:when>
	 <c:when test="${star==3 }">★★★</c:when>
	 <c:when test="${star==4 }">★★★★</c:when>
	 <c:when test="${star==5 }">★★★★★</c:when>
	</c:choose>
	<br>
	<c:choose>
	 <c:when test="${sex=='여자' }">
	  <b>여자입니다</b>
	  </c:when>
	  <c:otherwise>
	  	<b>아무것도 아닙니다</b>
	  </c:otherwise>
	</c:choose>
	
</body>
</html>

 조건문도 가능하다. 위에는 case 구문, 아래는 다중조건문으로 이해하면 된다. 

 

 

그리고 진짜로 배우기 시작하는 MVC구조

아까도 설명했지만 model, view, controller의 영역이 나눠지는 구조이다. 

 

 

model이 자바 영역, jsp가 view 영역, controller로 나뉘어져 있다. 자바 클래스들은 따로따로 만들어 주지만, 인터페이스 (model)하나로 묶어주고 있다. 

 

그냥 간단하게 개념만 이해하고 넘어갈 수 있도록 예제를 가볍게 보면, 

 

package com.sist.model;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
public class ListModel implements Model{
	public void handlerRequest(HttpServletRequest request)
	{
		List<String> list=new ArrayList<String>();
		list.add("이제노");
		list.add("이마크");
		list.add("이동혁");
		list.add("황인준");
		list.add("나은혈");
		// 클라이언트로 전송
		request.setAttribute("list", list); // 데이터 추가
	}
}

 handlerRequest라는 메소드를 만들고, 매개변수로는 request를 받아준다. 그 안에는 리스트를 만들어 값을 추가하고, setAttribute로 채워서 전송하는 것까지 완료한다. 

 

<%@ 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>
	<ul>
	 <c:forEach var="name" items="${list }">
		<li>${name }</li>
	 </c:forEach>
	</ul>
</body>
</html>

 list.jsp에서는 위와 같이 값으로 받아온 이름들을 출력할 수 있도록 view작업을 해준다. 

 

package com.sist.model;

import javax.servlet.http.HttpServletRequest;

public interface Model {
	public void handlerRequest(HttpServletRequest request);
}

 이걸 여러개를 하고, 하나의 인터페이스로 위와 같이 묶어준다. 

 

위의 자바와 뷰를 하나로 이어줄 컨트롤러를 만들면 mvc구조가 완성된다. 

 

package com.sist.controller;

import java.io.*;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sist.model.*;

public class Controller extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String cmd=request.getRequestURI();
		
		
		
		cmd=cmd.substring(cmd.lastIndexOf("/")+1);
		//System.out.println(cmd);
		// model, jsp 호출 전부 controller에서 해줌
		String jsp="";
		
		
		
		if(cmd.equals("list.do"))
		{
			ListModel model=new ListModel();
			model.handlerRequest(request);
			jsp="list.jsp";
		}
		else if(cmd.equals("update.do"))
		{
			UpdateModel model=new UpdateModel();
			model.handlerRequest(request);
			jsp="update.jsp";
		}
		else if(cmd.equals("delete.do"))
		{
			DeleteModel model=new DeleteModel();
			model.handlerRequest(request);
			jsp="delete.jsp";
		}
		else if(cmd.equals("detail.do"))
		{
			DetailModel model=new DetailModel();
			model.handlerRequest(request);
			jsp="detail.jsp";
		}
		
		RequestDispatcher rd=request.getRequestDispatcher("view/"+jsp);
		rd.forward(request, response); // 해당 JSP로 request를 전송
		
	}

}

  위가 controller영역이다. 다만 좀 쉽게 풀어썼다. 조건문으로 jsp의 파일명이 바뀔때마다 그에 맞는 model을 호출해주고, 맞는 jsp파일을 띄워준다. 

 

package com.sist.controller;

import java.io.*;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import com.sist.model.*;


/*
 * 	interface A
 * 	{
 *  	public void display();
 *  }
 * 	class B implements A
 * 	{
 * 		public void display()
 * 		{
 * 		}
 * 	}	
 *  클래스를 여러개를 모으려면 인터페이스
 */
public class Controller2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private Map clsMap=new HashMap();
	private String[] strCls= {
			"com.sist.model.DeleteModel",
			"com.sist.model.DetailModel",
			"com.sist.model.UpdateModel",
			"com.sist.model.ListModel"
			
	};
	private String[] strCmd={"delete", "detail", "update", "list"};
	@Override
	public void init(ServletConfig config) throws ServletException {
		/*
		 * clsMap.put("list", new ListModel()); clsMap.put("update", new UpdateModel());
		 * clsMap.put("delete", new DeleteModel()); clsMap.put("detail", new
		 * DetailModel());
		 */
		try
		{
			int i=0;
			for(String cls:strCls)
			{
				Class clsName=Class.forName(cls);
				Object obj=clsName.newInstance();
				clsMap.put(strCmd[i], obj);
				i++;
				
			}
		} catch (Exception ex) {
			
		}
	}

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String cmd=request.getRequestURI();
		cmd=cmd.substring(cmd.lastIndexOf("/")+1, cmd.lastIndexOf("."));
		//System.out.println(cmd);
		Model model=(Model)clsMap.get(cmd);
		model.handlerRequest(request);
		RequestDispatcher rd=request.getRequestDispatcher("view/"+cmd+".jsp");
		rd.forward(request, response);
	}

}

 위의 코드는 같은 controller이지만 조건문의 반복없이 채워주고 있다. Map에 키와 값을 설정해서 받아오고 있다. 

 

 

다음시간에는 이 부분에 대해서 좀 더 자세히 배울 예정이다. 

728x90
반응형