학원/servlet jsp

11.20일 (jstl / model-2(mvc))

쿠룽지 2023. 11. 20. 23:06
728x90
반응형

 

1. core lib

 

<c:remove var="변수명" scope="범위" />

  • 설정된 속성을 제거하는 태그 (set 태그로 셋팅된 데이터 삭제 가능)
  • scope은 값이 셋팅된 범위를 의미(page,request,session,application), 생략 시 page 가 기본 셋팅 위치

 

 

ch21-jstl

s02_remove.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>remove 태그</title>
</head>
<body>
<%--		속성명		속성값	저장영역=page(기본값) --%>
<c:set var="str" value="겨울"/>
데이터 삭제 전 : ${str}<br> <%-- 데이터 삭제 전 : 겨울 --%>
-------------------------<br>
<c:remove var="str"/> <%-- 동일한 속성명을 찾아서 삭제 --%>
데이터 삭제 후 : ${str} <%-- 데이터 삭제 후 : --%>
</body>
</html>

scope를 따로 지정하지 않을 때 기본 저장 위치는 page

 

 


 

 

<c:if test="조건" var="변수명" scope="범위" />

  • 조건이 true이면 수행문을 수행하는 태그
  • jstl에도 if문이 있음 (태그 형태)
  • input 태그로 if를 만들기 때문에 else가 없어 다중 체크는 불가능, 단일 체크만 가능함
  • boolean 타입으로 조건체크 -> el태그가 연산 후 출력

 

 

ch21-jstl

s03_if.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>if 태그</title>
</head>
<body>

<%-- 값을 넘기지 않아도 출력 --%>
<c:if test="true"> 
	무조건 수행 <br>
</c:if>


<%-- 값을 넘겨야만 출력 --%>
<c:if test="${param.name == 'dragon'}"> 
	name 파라미터의 값이 ${param.name} 입니다. <br>
</c:if>

<c:if test="${param.name.equals('dragon')}">
	name 파라미터의 값이 ${param.name} 입니다. <br>
</c:if>

<c:if test="${param.age >= 20}">
	당신의 나이는 20세 이상입니다.
</c:if>

</body>
</html>

1) <> 안은 boolean type이라 <c:if test="true> 면 무조건 input 태그 내 문장이 무조건 수행됨

2) ${param.name == 'dragon'} == ${param.name.equals('dragon')} / 문자열 비교기 때문에

 

실행 후 url에서 직접 get방식으로 값을 주면 됨

http://localhost:8080/ch05-ServletMain/ch21-jstl/s03_if.jsp?name=dragon&age=30 << 식으로

 

 


 

 

<c:choose>
   <c:when test="조건"></c:when>
   <c:when test="조건"></c:when>
   <c:otherwise></c:otherwise>
</c:choose>

  • if 태그는 else가 없어서 모든 조건에 if를 넣어야 함.
  • 짧은 조건문은 문제가 없는데 조건이 많다면 choose when otherwise를 사용해야 함

 

 

s04_choose.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>choose 태그</title>
</head>
<body>
<c:choose>
	<c:when test="${param.name == 'dragon' && param.age >= 20}"> <%-- 조건체크 --%>
		당신의 이름은 ${param.name}이고 20세 이상입니다.
	</c:when>
	<c:when test="${param.name == 'dragon'}">
		당신의 이름은 ${param.name} 입니다.
	</c:when>
	<c:when test="${param.age >= 20}">
		당신은 20세 이상입니다.
	</c:when>
	<c:otherwise>
		당신은 'dragon'이 아니고 20세 이상이 아닙니다.
	</c:otherwise>
</c:choose>
</body>
</html>

[출력 화면]

첫 실행 화면
당신은 'dragon'이 아니고 20세 이상이 아닙니다.

http://localhost:8080/ch05-ServletMain/ch21-jstl/s04_choose.jsp?name=dragon&age=20
당신의 이름은 dragon이고 20세 이상입니다.

http://localhost:8080/ch05-ServletMain/ch21-jstl/s04_choose.jsp?name=dragon
당신의 이름은 dragon 입니다.

http://localhost:8080/ch05-ServletMain/ch21-jstl/s04_choose.jsp?age=20
당신은 20세 이상입니다.

 

조건 개수가 적다면 choose when otherwise보단 if가 더 짧고 좋다함

 

 


 

 

<c:forEach items="객체명" begin="시작 인덱스" end="끝 인덱스" step="증감식" var="변수명" varStatus="상태변수" />

  • 태그의 반복문 ( 목록 처리 시 많이 사용)
  • model-2 패턴은 일반적인 for문보다 forEach를 사용하는 게 훨씬 편함
  • jstl의 if와 forEach는 꼭 알아야하는 태그
  • 일반적인 for문보다 기능이 더 많음
    • 반복문
    • 배열 정보 읽어오기 
    • key와 value의 쌍 읽어오기 (+hashmap)

 

s05_forEach.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.HashMap" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>forEach 태그</title>
</head>
<body>

<h4>1부터 100까지 홀수의 합</h4>
<c:set var="sum" value="0"/>
<c:forEach var="i" begin="1" end="100" step="2"> <%-- 1~100까지 2씩 증가 --%>
	<c:set var="sum" value="${sum+i}"/>
</c:forEach>
결과 = ${sum}


<%-- 구구단 --%>
<h4>구구단 : 5단</h4>
<ul>
	<c:forEach var="i" begin="1" end="9"> <%-- page에 i값 저장됨--%>
    	<li>5 * ${i} = ${5 * i}</li>
    </c:forEach>
</ul>


<%-- 배열정보 읽어오기 // 확장 for문과 닮아있음 --%>
<h4>int형 배열</h4>
<c:set var="intArray" value="<%= new int[] {10,20,30,40,50}%>"/>
<c:forEach var="i" items="${intArray}" begin="2" end="4" varStatus="status"> <%-- i=배열명 / begin-end를 통해 읽어올 범위도 지정 가능--%>
	${status.index} - ${status.count} - [${i}]<br>
</c:forEach>
<%-- forEach >> 반복 정보, 인덱스 정보 모두 제공
반복 정보 varStatus="status" > ${status.count}
인덱스 정보 				   > ${status.index}
--%>


<%-- hashmap에 접근해 정보읽기
자바는 k를 알아내서 하나하나 빼냈는데 jstl은 한번에 k/v를 읽어올 수 있음 --%>
<h4>Map</h4>
<%
	HashMap<String,String> mapData = new HashMap<String,String>();

	mapData.put("name", "홍길동"); //key, value의 쌍으로 넣음
	mapData.put("job", "경찰");
%>
<c:set var="map" value="<%= mapData %>"/>
<c:forEach var="i" items="${map}">
	${i.key} = ${i.value}<br>
</c:forEach>

</body>
</html>

HashMap의 key와 value를 한꺼번에 읽을 수 있음

 

 


 

 

<c:forTokens items="객체명" delims="구분자" begin="시작 인덱스" end="끝 인덱스" step="증감식" var="변수명" varStatus="상태변수" />

  • 문자열을 구분자로 잘라내어 출력 (java Stringtokenizer/ split과 유사)
  • delims: 구분자 지정
  • 시작 인덱스와 끝 인덱스, 증감식을 지정하여 구분할 수도 있다

 

 

s06_forTokens.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>forTokens 태그</title>
</head>
<body>
	<h4>쉼표와 점을 구분자로 사용</h4>
	<%-- 			var=변수				 items=데이터 					delims=구분자 --%>
	<c:forTokens var="token" items="빨강색,주황색,노란색.초록색.파란색,남색.보라색" delims=",.">
		${token}<br>
	</c:forTokens>
	
	<h4>날짜를 연월일시분초로 구분해서 출력</h4>
	<c:forTokens var="now" items="2023-05-23 11:12:59" delims="- :">
		${now}<br>
	</c:forTokens>
	
</body>
</html>

 

 


 

<c:redirect url="URL" context="context" />

  • 지정한 url로 redirect
  • response.sendRedirect 중에 알맞은 걸 골라 사용하면 됨

 

 

s07_redirect.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:redirect url="s01_set.jsp">
	<%-- 	파라미터네임			값 --%>
	<c:param name="id" value="dragon"/>
	<c:param name="name" value="petter"/>
</c:redirect>

http://localhost:8080/ch05-ServletMain/ch21-jstl/s01_set.jsp;jsessionid=871F193D4213C1398A019754DF7F33F0?id=dragon&name=petter

redirect한 페이지에 get방식으로 parameter 문자열로 값을 전달할 수 있음 (id=dragon&name=petter)

 


 

<c:out value="출력값" default="기본값" escapeXml="true/false"  />

  • 지정된 값을 출력하는 태그
  • el이 하는 출력을 태그로도 가능케 함
  • out태그로 출력 시 태그를 불인정하게 할 때 사용 (ex- html)

 

 

s08_out.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>out 태그</title>
</head>
<body>
<%-- escapeXml="true" 이면 html 태그 불인정 (명시안하면 기본값) --%>
<c:out value="<h1>오늘은 월요일</h1>" escapeXml="true"/> 
<br>
<%-- escapeXml="false"이면 html 태그 인정 --%>
<c:out value="<h1>내일은 화요일</h1>" escapeXml="false"/>
</body>
</html>

escapeXml="true"  (기본값)  ==  태그 불인정

escapeXml="false" == 태그 인정 

 

 


 

 

<c:catch var="변수명" />

  • 예외 발생 시 예외 처리 태그
  • 예외가 발생할 수 있는 수행문 앞뒤에 catch 태그 배치, 예외 발생 시 var에 지정한 변수명에 예외 문구 저장, out 태그 or el 태그를 통해 예외 문구 호출 및 출력 가능

 

 

s09_catch.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>catch 태그</title>
</head>
<body>
<%-- catch 태그 내에 예외가 발생할 가능성이 있는 코드 작성 --%>
<c:catch var="ex">
name 파라미터의 값 = <%= request.getParameter("name") %>
<%
	if(request.getParameter("name").equals("test")){
%>
		${param.name}은 test입니다.
<%		
	}
%>
</c:catch>
<p>
<c:if test="${ex != null}"> <%-- 위에 예외객체인 ex를 가리킴 --%>
	예외가 발생했습니다.<br>
	${ex}
</c:if>
</p>
</body>
</html>

<c:catch var="변수명"></c:catch>로 예외 발생 가능성이 있는 코드를 넣고

<c:if test="${변수명 != null}"></c:if>에 예외 출력 문장과 ${ex} 를 넣으면 문장이 출력됨

 

url에 http://localhost:8080/ch05-ServletMain/ch21-jstl/s09_catch.jsp?name=test
라고 name값을 전달해주면 예외 발생 X

name 파라미터의 값 = test test은 test입니다. 라고 출력

 

 


 

2. fmt lib

 

 

 

<fmt:formatNumber value="Number로 형식화할 수치 데이터"
                           type="숫자, 통화, 퍼센트 중 하나{number|currency|percent}"
                           pattern="사용자 지정 패턴"
                           currencyCode="통화코드지정"
                           currencySymbol="통화기호"
                           groupingUsed="{true|false}출력시 그룹 분리 기호(,) 
                                포함여부"
                           maxIntegerDigits="출력시 integer 최대 자릿수 지정"
                           minIntegerDigits="출력시 integer 최소 자릿수 지정"
                           maxFractionDigits="출력시 소수점 이하 최대 자릿수 지정"
                           minFractionDigits="출력시 소수점 이하 최소 자릿수 지정"
                           var="변수"
                           scope="범위" />

  • 숫자 포맷 예제
  • 수치 데이터를 숫자, 통화, 퍼센트로 변환
  • pattern을 넣어서 원하는 패턴으로 출력 가능

 

 

s10_number.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>formatNumber 태그</title>
</head>
<body>
숫자 : <fmt:formatNumber type="number" value="10000"/> <%-- 자동으로 ,넣어서 출력도 해줌 --%>
<br>
통화 : <fmt:formatNumber type="currency" value="10000" currencySymbol="$"/>
<br>
<%-- \(원) 표시가 특문이라 일반 문자로 바꾸기 위해선 \를 하나 더 넣어줌 --%>
통화 : <fmt:formatNumber type="currency" value="10000" currencySymbol="\\"/>
<br>
퍼센트 : <fmt:formatNumber type="percent" value="0.3"/>
<br>
패턴 : <fmt:formatNumber value="12.345" pattern="0000.00"/> <%-- 패턴 : 0012.35 --%>
</body>
</html>

 

 


 

 

<fmt:formatDate value="형식화할 날짜와 시간 데이터"
                          type="{time|date|both}"
                       deteStyle="{short|full}"
                       timeStyle="{short|full}"
                       pattern="사용자 지정 패턴"
                       timeZone="타임존 지정"
                       var="변수"
                       scope="범위" />

  • 날짜에 형식 지정
  • 특정 데이터를 빼낼 수도 있음

 

 

s11_date.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>formatDate 태그</title>
</head>
<body>
<c:set var="now" value="<%= new java.util.Date()%>"/>
${now}<br> <%-- Mon Nov 20 12:32:40 KST 2023 --%>

<%-- simpleDateFormat이 없어도 한글로 나올 수 있게끔 태그 처리 --%>
<fmt:formatDate value="${now}" type="date" dateStyle="full"/> <%--2023년 11월 20일 월요일 --%>
<br>
<fmt:formatDate value="${now}" type="date" dateStyle="short"/> <%-- 23. 11. 20. --%>
<br>

<fmt:formatDate value="${now}" type="time" timeStyle="full"/> <%-- 오후 12시 35분 58초 대한민국 표준시 --%>
<br>
<fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/> <%-- 2023년 11월 20일 월요일 오후 12시 37분 34초 대한민국 표준시 --%>
<br>


<%-- 원하는 것만 명시하고 싶을 땐 pattern 사용 --%>
<fmt:formatDate value="${now}" pattern="yyyy-MM-dd E요일 a hh:mm:ss"/>
<%-- 2023-11-20 오후 12:40:17 --%>
</body>
</html>

<fmt:formatDate> 를 통해 Date() 객체의 값을 한글로 변환할 수 있음

pattern을 통해 원하는 형식으로 빼낼 수도 있음

yy MM (대문자) dd E a hh mm ss

 

 


 

3. functions lib

 

 

  • el이 functions lib를 읽어서 메서드를 함수처럼 만들 수도 있음
  • functions lib가 별도로 있어서 (태그형태 x el이 호출하는 형태 o) 조금 더 UI에 사용하기 편리하다

 

 

s12_functions.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>functions 라이브러리</title>
</head>
<body>
<c:set var="str1" value=" Functions <태그>를 사용합니다. "/>
<c:set var="str2" value="사용"/>
<c:set var="tokens" value="10,20,30-40,50,60,70,80.90,100"/>

문자열의 길이 : ${fn:length(str1)}<br> <%-- 문자열의 길이 : 24 --%>
대문자로 변경 : ${fn:toUpperCase(str1)}<br> <%-- 대문자로 변경 : FUNCTIONS <태그>를 사용합니다. --%>
소문자로 변경 : ${fn:toLowerCase(str1)}<br> <%-- 소문자로 변경 : functions <태그>를 사용합니다. --%>
인덱스 3 ~ 6전까지 문자열 추출 : ${fn:substring(str1, 3, 6)}<br> <%-- 인덱스 3 ~ 6전까지 문자열 추출 : nct --%>
문자열에서 원래 문자를 지정한 문자로 대체 : ${fn:replace(str1, " ", "-")}<br> <%-- 문자열에서 원래 문자를 지정한 문자로 대체 : -Functions-<태그>를-사용합니다.- --%>
<%-- 트림은 앞뒤 공백만 제거, 중간 공백은 제거하지 못함 --%>
문자열의 앞뒤 공백 제거 : ${fn:trim(str1)}<br> <%-- 문자열의 앞뒤 공백 제거 : Functions <태그>를 사용합니다. --%>
지정한 문자의 인덱스 구하기 : ${fn:indexOf(str1, str2)}<br> <%-- 지정한 문자의 인덱스 구하기 : 17 --%>
문자열에서 지정한 문자를 구분자로 문자열을 잘라내기 : ${fn:split(tokens, ',')}<br> <%-- 문자열에서 지정한 문자를 구분자로 문자열을 잘라내기 : [Ljava.lang.String;@5f9b2100 --%>
<c:forEach var="array" items="${fn:split(tokens, ',-.')}">
	${array}<br>
</c:forEach>
</body>
</html>

 

 

 

 


 

 

model-1,2 차이점

DB연동은 같음 (dao, vo)

화면 호출하는 순서와 자바 클래스가 별도로 생성된다는 것은 다름 

 

 

client --> 요청 --> servlet

servlet--> 호출 --> model class = 데이터 생성

model class --> 데이터를 자바빈에 담고 자바빈을 DAO에 옮김 --> DAO <> DB연동

model class --> jsp 경로 --> servlet

servlet --> 응답 --> client

 

이런 과정을 거치는 것 같은데 자세히는... 아직 잘 모르겠다

 

하다보면 알겠지

 

 

요약

Model Class = 데이터 생성 // Model (M)

JSP = HTML을 만드는 UI // View (V)

Servlet=교통정리 // Controller (C)

모델 비즈니스 영역의 상태 정보를 처리한다.
비즈니스 영역에 대한 프레젠테이션 뷰(즉, 사용자가 보게 될 결과 화면)를 담당한다.
컨트롤러 사용자의 입력 및 흐름 제어를 담당한다.

 

 


 

 

ch05 - ServletMain

src/main/java

kr.web.mvc (package 생성)

DispatcherServlet (class 생성)

 

 

 

이론적인 부분(어떻게 호출/ 실행) 을 더 알기 위해 Servlet 작성

차후에는 JSP, DAO, VO 에만 집중하면 됨

 

 

아래 구문과 같이 일반적인 Servlet을 mvc 방식에서 쓰는 Servlet으로 바꿔볼거임

 

 

DispatcherServlet.java

package kr.web.mvc;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

#WebServlet("/dispatcher") >> web.xml에 설정할 거라 지움
public class DispatcherServlet extends HttpServlet{
	@Override
	public void doGet(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		//컨텐트 타입 및 캐릭터셋 지정
		response.setContentType("text/html;charset=utf-8");
		//HTML 출력을 위한 출력스트림을 생성
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<head><title>Hello World</title></head>");
		out.println("<body>");
		out.println("안녕하세요!!");
		out.println("</body>");
		out.println("</html>");
		out.close();
	}
}

mvc 패턴 

되도록이면 Servlet은 건드리지 않고 web.xml (설정파일) 에다 따로 설정을 추가하는 경우가 대다수임

(이중설정하지 않게 조심!!!)

 

 

 

web-inf

lib

web.xml

<!-- DispatcherServlet 설정 시작 -->
<servlet>
	<servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>kr.web.mvc.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/dispatcher</url-pattern>
</servlet-mapping>
  <!-- DispatcherServlet 설정 끝 -->

 

저장 후 위 DispatcherServlet에서 실행하면 주소가 servlet에 없는데도 

body 내용이 보임

 


 

 

동일한 주소 + 내부적으로 forward 방식 사용

더보기

forward

-리다이렉트와 비슷해보이지만 주소(url) 가 바뀌지 않음

-클라이언트가 호출한 a.jsp가 클라이언트에게 통보하지 않고 b.jsp로 바뀜 (클라이언트는 모름) --> 클라이언트 속이기 (b.jsp가 생성하지만 a.jsp가 생성하는 것처럼 보임)

-다른 서버일 경우에도 호출 가능 (다른 웹 서버에 있는 웹 자원도 호출 가능)

-request 내장 객체를 통해 데이터 전달

 

servlet이 요청을 받고 jsp가 호출을 받으면 UI를 처리하는 예제

 

 

 

DispatcherServlet.java 수정

package kr.web.mvc;

import java.io.IOException;
import java.io.PrintWriter;

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

public class DispatcherServlet extends HttpServlet{
	@Override
	public void doGet(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}	
	
	@Override
	public void doPost(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}
	
	private void requestPro(HttpServletRequest request,
							HttpServletResponse response)
							throws ServletException, IOException{
		//forward방식으로 view(JSP) 호출
		RequestDispatcher dispatcher = request.getRequestDispatcher("/ch22-mvc/messageView.jsp");
		dispatcher.forward(request, response);
	}
}

1) get/ post 방식 어떤 방식이 들어오던 둘 다 에러가 안나게 두 가지 모두 구현

작업을 할 수 있는 별도의 메서드를 만들고 doGet과 doPost 모두 사용할 수 있게끔 만듦 (requestPro)

 

2) requestPro   dispatcher.forward(request, response)

forward 방식으로 ch-mvc/messageView.jsp 내용을 보이게 함 (jsp에서 ui를 만들어서 전송)

 

 

 

webapp

ch22-mvc (folder 생성)

messageView.jsp (jsp file)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
안녕하세요
</body>
</html>

저장 후 servlet으로 가서 실행 

 

 


 

 

mvc 모델 = UI 작업/ 데이터 작업 분리

request 공유 (forward 방법 사용)

 

 

데이터를 공유할 수 있게끔 request에 데이터를 저장하는 예제

(클라이언트가 보낸 데이터 처리)

 

 

DispatcherServlet.java 수정

private void requestPro(HttpServletRequest request,
							HttpServletResponse response)
							throws ServletException, IOException{
		
		String message = request.getParameter("message"); // 클라이언트가 보낸 메시지
		
		//request에 전송받은 데이터를 저장
		request.setAttribute("result", message);		
		
		//forward방식으로 view(JSP) 호출
		RequestDispatcher dispatcher = request.getRequestDispatcher("/ch22-mvc/messageView.jsp");
		dispatcher.forward(request, response);
	}

 

 

 

 

messageView.jsp 수정

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>뷰</title>
</head>
<body>
결과 : <%= request.getAttribute("result") %><br>
결과 : ${requestScope.result}<br>
결과 : ${result}
</body>
</html>

위처럼 총 세가지 방법으로 데이터 출력 가능

요청은 servlet 진입 -> 데이터 생성 -> view에서 데이터 가져다 쓰는 방식이라 servlet에서 실행해야함

 

${result}처럼 el로 쓰는게 짧고 간단해서 보통 저걸 많이 사용

 

[출력결과-초기화면]
결과 : null
결과 :
결과 :

[get방식으로 넘기기]
http://localhost:8080/ch05-ServletMain/dispatcher?message=sky 수정 
결과 : sky
결과 : sky
결과 : sky

 

 


 

 

저장 전 가공도 가능

DispatcherServlet.java 수정

package kr.web.mvc;

import java.io.IOException;
import java.io.PrintWriter;

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

public class DispatcherServlet extends HttpServlet{
	@Override
	public void doGet(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}	
	
	@Override
	public void doPost(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}
	
	private void requestPro(HttpServletRequest request,
							HttpServletResponse response)
							throws ServletException, IOException{
		
		String message = request.getParameter("message"); // 클라이언트가 보낸 메시지
		String result = null;
        
		if(message == null || message.equals("")) {
			result = "메시지가 없네요~~";
		}else if(message.equals("name")) {
			result = "홍길동";
		}else if(message.equals("base")) {
			result = "기본 호출";
		}else {
			result = "잘못된 호출";
		}
		
		//request에 전송받은 데이터를 저장
		request.setAttribute("result", result);
		
		//forward방식으로 view(JSP) 호출
		RequestDispatcher dispatcher = request.getRequestDispatcher("/ch22-mvc/messageView.jsp");
		dispatcher.forward(request,  response);
	}
	
}

클라이언트가 보낸 메시지를 받고 가공 후 request에 저장, jsp 호출 (forward)

 

 

[출력결과]
결과 : 메시지가 없네요~~
결과 : 메시지가 없네요~~
결과 : 메시지가 없네요~~

[?message=name]
http://localhost:8080/ch05-ServletMain/dispatcher?message=name
결과 : 홍길동
결과 : 홍길동
결과 : 홍길동

[?message=base]
http://localhost:8080/ch05-ServletMain/dispatcher?message=base
결과 : 기본 호출
결과 : 기본 호출
결과 : 기본 호출

 

[?message=sdfsdf]
http://localhost:8080/ch05-ServletMain/dispatcher?message=sdfsdf
결과 : 잘못된 호출
결과 : 잘못된 호출
결과 : 잘못된 호출

 


 

 

게시판을 만드는 과정으로 class 생성

 

ListAction 목록 처리

WriteAction 글쓰기 클래스

UpdateAction 수정 클래스

DetailAction 상세보기 클래스

등의 클래스를 생성하고 객체를 생성함

근데 이전에 했던 방식처럼 여러 타입의 객체를 하나하나 생성하게 되면 자동화 처리에 어려움이 생김

 

--> 부모 클래스(추상 메서드 형태) 를 만들거나 인터페이스를 활용하여 한번에 객체를 생성할 수 있음

 

 

Action 이라는 인터페이스를 활용한 예제를 해볼 것 (implement를 이용해 하나의 타입으로 사용)

 

 

 

 

인터페이스 생성

kr.web.mvc

Action (interface) / 자료형으로 쓰면서 메서드를 강요하기 위해

package kr.web.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface Action {
	//추상 메서드
	public String execute(HttpServletRequest request,
						  HttpServletResponse response)
						  throws Exception;	
}

 

 

 

 

 

실제 동작하는 클래스

kr.web.mvc

ListAction.java / 뷰

package kr.web.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ListAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//데이터 생성 후 request에 데이터 저장
		//						속성명		속성값
		request.setAttribute("message", "목록 페이지입니다.");
		//JSP 경로 반환
		return "/ch22-mvc/list.jsp";
	}
}

 

 

 

 

webapp

ch22-mvc

list.jsp / 모델

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>목록</title>
</head>
<body>
${message}
</body>
</html>

 

 

 

 

목록을 호출한다는 url을 받아야함

DispatcherServlet.java / 컨트롤러

package kr.web.mvc;

import java.io.IOException;
import java.io.PrintWriter;

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

public class DispatcherServlet extends HttpServlet{
	@Override
	public void doGet(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}	
	
	@Override
	public void doPost(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}
	
	private void requestPro(HttpServletRequest request,
							HttpServletResponse response)
							throws ServletException, IOException{
		Action com = null; //모델 클래스
		String view = null; //jsp경로
		
		String command = request.getParameter("command");
        if(commad == null || command.equals("list")){
        	com = new ListAction();
        }
		
		try {
			//메서드 호출 결과 JSP 경로를 view에 저장
			view = com.execute(request, response);
		}catch(Exception e) {
			e.printStackTrace();
		}
		
		//forward방식으로 view(JSP) 호출
		RequestDispatcher dispatcher = request.getRequestDispatcher(view);
		dispatcher.forward(request,  response);
	}
	
}

 

 


 

 

 

kr.web.mvc

WriteAction.java / 뷰

package kr.web.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WriteAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		//request에 데이터 저장
		request.setAttribute("message", "글 등록 완료");
        //아직은 db연동이 없기 때문에 db연동해서 하는 것처럼 문구를 여기다 넣은거임
		//JSP 경로 반환
		return "/ch22-mvc/write.jsp";
	}
}

 

 

 

 

DispatcherServlet.java / 컨트롤러

package kr.web.mvc;

import java.io.IOException;
import java.io.PrintWriter;

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

public class DispatcherServlet extends HttpServlet{
	@Override
	public void doGet(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}	
	
	@Override
	public void doPost(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}
	
	private void requestPro(HttpServletRequest request,
							HttpServletResponse response)
							throws ServletException, IOException{
		Action com = null; //모델 클래스
		String view = null; //jsp 경로
		
		String command = request.getParameter("command");
		if(command == null || command.equals("list")) {
			com = new ListAction();
		}else if(command.equals("write")) {
			com = new WriteAction();
		}
		
		try {
			//메서드 호출 결과 JSP 경로를 view에 저장
			view = com.execute(request, response);
		}catch(Exception e) {
			e.printStackTrace();
		}
		
		//forward방식으로 view(JSP) 호출
		RequestDispatcher dispatcher = request.getRequestDispatcher(view);
		dispatcher.forward(request,  response);
	}
}

 

 

 

 

ch22-mvc

write.jsp / 모델 클래스

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글쓰기</title>
</head>
<body>
${message }
</body>
</html>

jsp 에서 호출하면 데이터가 만들어진게 없기 때문에 mvc 패턴일 경우에 servlet으로 가서 호출해야함

 

 

[호출 초기 출력화면]

목록 페이지입니다.

 

[command=list]

http://localhost:8080/ch05-ServletMain/dispatcher?command=list
목록 페이지입니다.

 

[command=write]

http://localhost:8080/ch05-ServletMain/dispatcher?command=write
글 등록 완료

 

데이터는 미리 만들어져있고,

그 데이터를 가지고 html을 만들기 때문에 jsp가 제일 마지막에 호출됨 (모델클래스)

 

 


 

 

 

kr.web.mvc

DetailAction.java

package kr.web.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DetailAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		//request에 데이터 저장
		request.setAttribute("message", "상세페이지 입니다.");
		return "/ch22-mvc/detail.jsp";
	}
}

 

 

 

 

DispatchServlet.java

package kr.web.mvc;

import java.io.IOException;
import java.io.PrintWriter;

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

public class DispatcherServlet extends HttpServlet{
	@Override
	public void doGet(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}	
	
	@Override
	public void doPost(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}
	
	private void requestPro(HttpServletRequest request,
							HttpServletResponse response)
							throws ServletException, IOException{
		Action com = null; //모델 클래스
		String view = null; //jsp 경로
		
		String command = request.getParameter("command");
		if(command == null || command.equals("list")) {
			com = new ListAction();
		}else if(command.equals("write")) {
			com = new WriteAction();
		}else if(command.equals("detail")) {
			com = new DetailAction();
		}
		
		try {
			//메서드 호출 결과 JSP 경로를 view에 저장
			view = com.execute(request, response);
		}catch(Exception e) {
			e.printStackTrace();
		}
		
		//forward방식으로 view(JSP) 호출
		RequestDispatcher dispatcher = request.getRequestDispatcher(view);
		dispatcher.forward(request,  response);
	}
}

 

 

 

 

ch22-mvc

detail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상세페이지</title>
</head>
<body>
${message}
</body>
</html>

 

 

[command=detail]

http://localhost:8080/ch05-ServletMain/dispatcher?command=detail
상세페이지 입니다.

 

 


 

 

 

하나의 주소가 아니라 개별적인 주소를 할당하는 방법

 

지금까지 가져온 주소들은 /dispatcher 라고 하나의 주소 안에 있던 것들임 (?command=list/write/detail)

요즘은 주소 하나당 개별 주소를 부여해준다고 함

 

주소 변형 시키는 방법

 

 

 

DispatchServlet.java

String command = request.getParameter("command");
		if(command == null || command.equals("/list.do")) {
			com = new ListAction();
		}else if(command.equals("/write.do")) {
			com = new WriteAction();
		}else if(command.equals("/detail.do")) {
			com = new DetailAction();
		}

/list.do

/write.do

/detail.do 로 수정

 

 

 

web-inf

lib

web.xml

<!-- DispatcherServlet 설정 시작 -->
<servlet>
	<servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>kr.web.mvc.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- DispatcherServlet 설정 끝 -->

/dispatcher -> *.do 수정

 

 

 

 

DispatcherServlet.java

서버 요청 시 본래

/dispatcher?command=list / write / detail 라고 기재했는데

 

http://localhost:8080/ch05-ServletMain/list.do
http://localhost:8080/ch05-ServletMain/write.do
http://localhost:8080/ch05-ServletMain/detail.do
라고 이렇게 하나하나 개별 주소를 줄거임

 

ch05-ServletMain/list.do = URI
여기서 contextroot를 지워서 list.do 부분을 구하고자함

private void requestPro(HttpServletRequest request,
							HttpServletResponse response)
							throws ServletException, IOException{
		Action com = null; //모델 클래스
		String view = null; //jsp 경로
		
		String command = request.getRequestURI(); // ch05-ServletMain/list.do
		System.out.println("1 command : " + command); //첫번째 command
		if(command.indexOf(request.getContextPath())==0) { //맨 앞 contextpath가 있냐 > ch05가 있어서 true -> 추출 가능
			command = command.substring(request.getContextPath().length()); // contextpath 다음부터 추출> command에 list.do 담기
			System.out.println("2 command : " + command); // 최종적으로 만들어진 command
		}
		
		if(command == null || command.equals("/list.do")) {
			com = new ListAction();
		}else if(command.equals("/write.do")) {
			com = new WriteAction();
		}else if(command.equals("/detail.do")) {
			com = new DetailAction();
		}

String command = request.getRequestURI(); #ch05-ServletMain/list.do 라는 URI 를 command에 담음

syso("1 command :" + command); URI를 1 command라는 문장을 붙여 console에 표시

 

if(command.indexOf(request.getContextPath())==0){ # ch05-ServletMain = contextpath가 맨 앞에 있으면 true

   command = command.substring(request.getContextPath().length()); #contextpath 길이~ substring> command에 담기

   syso("2 command :" + command); #contextPath가 제외된 command console에 출력

}

 

 

[초기 출력화면]
*.do // null 

*.do -> list.do
목록 페이지입니다.
[콘솔]
1 command : /ch05-ServletMain/list.do
2 command : /list.do

*.do -> write.do
글 등록 완료
[콘솔]
1 command : /ch05-ServletMain/write.do
2 command : /write.do

*.do -> list.do
상세페이지입니다.
[콘솔]
1 command : /ch05-ServletMain/detail.do
2 command : /detail.do

 


나머지 update랑 delete도 같이 넣어줌

 

 

kr.web.mvc

UpdateAction.java

package kr.web.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class UpdateAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		//request에 데이터 저장
		request.setAttribute("message", "게시판 정보 수정");
		
		//JSP 경로 반환
		return "/ch22-mvc/update.jsp";
	}
}

 

 

 

 

deleteAction.java

package kr.web.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DeleteAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//request에 데이터 저장
		request.setAttribute("message", "게시글 삭제");
		
		//JSP 경로 반환
		return "/ch22-mvc/delete.jsp";
	}
}

 

 

 

 

ch22-mvc

update.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 정보 수정</title>
</head>
<body>
${message}
</body>
</html>

 

 

 

delete.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 삭제</title>
</head>
<body>
${message}
</body>
</html>

 

 

 

 

 

DispatcherServlet.java

package kr.web.mvc;

import java.io.IOException;
import java.io.PrintWriter;

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

public class DispatcherServlet extends HttpServlet{
	@Override
	public void doGet(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}	
	
	@Override
	public void doPost(HttpServletRequest request,
						HttpServletResponse response)
						throws ServletException, IOException{
		requestPro(request,response);
	}
	
	private void requestPro(HttpServletRequest request,
							HttpServletResponse response)
							throws ServletException, IOException{
		Action com = null; //모델 클래스
		String view = null; //jsp 경로
		
		String command = request.getRequestURI(); // ch05-ServletMain/list.do
		System.out.println("1 command : " + command); //첫번째 command
		if(command.indexOf(request.getContextPath())==0) { //맨 앞 contextpath가 있냐 > ch05가 있어서 추출 가능
			command = command.substring(request.getContextPath().length()); // contextpath 다음부터 추출> command에 list.do 담기
			System.out.println("2 command : " + command); // 최종적으로 만들어진 command
		}
		
		if(command == null || command.equals("/list.do")) {
			com = new ListAction();
		}else if(command.equals("/write.do")) {
			com = new WriteAction();
		}else if(command.equals("/detail.do")) {
			com = new DetailAction();
		}else if(command.equals("/update.do")) {
			com = new UpdateAction();
		}else if(command.equals("/delete.do")) {
			com = new DeleteAction();
		}
		
		try {
			//메서드 호출 결과 JSP 경로를 view에 저장
			view = com.execute(request, response);
		}catch(Exception e) {
			e.printStackTrace();
		}
		
		//forward방식으로 view(JSP) 호출
		RequestDispatcher dispatcher = request.getRequestDispatcher(view);
		dispatcher.forward(request,  response);
	}
}
728x90
반응형