ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JSP] 004. 포워딩과 리다이렉트
    SsY/Class 2023. 5. 22. 09:50
    728x90
    포워딩과 리다이렉트
    •  포워딩과 리다이렉트 개념
    ■■■ 포워딩(Forwarding)과 리다이렉트(Redirect) ■■■
    //-- 클라이언트가 서버에게 요청을 할 때 서버에서 요청을 어떻게 처리하는가의 방식
    =============================================================================================
    ○ 포워딩(Forwarding, 포워드)
    //-- 해당 서버가 다른 요청을 처리하는 중에 쉬는 컨테이너에게 일을 처리해달라고 하는 방식
    
      요청을 포워딩할 때 해당 요청은 서버의 다른 자원에 전달된다.
      이 때에는 다른 자원에 이 요청을 처리할 것을 클라이언트에게 알리지 않는다.
      이와 같은 방식의 처리는 웹 컨테이너 안에서만 일어나고
      클라이언트는 알 수 없게 된다.
    
      포워딩은 리다이렉트와 다르게
      객체를 요청에 담고 해당 요청을 사용할 다음 자원에 전송한다.
      따라서 클라이언트는 포워딩이 발생한 사실을 알지 못하는 것이다.
      포워딩은 클라이언트와 통신 없이 서버에서만 처리되기 때문에
      리다이렉트보다 나은 성능을 갖는다고 할 수 있다.
    =============================================================================================
    ○ 리다이렉트(Redirect, 리디렉트, 리디렉션, 리다이렉션)
    //-- 서버에게 요청을 했는데 URL로 돌아와서 해당 URL 로 이동하여 다시 요청을 해야하는 방식
    
      클라이언트의 요청을 처리한 후
      컨테이너는 『sendRedirect()』메소드가 호출되면 브라우저에 응답을 보낸다.
      이 응답에는 웹 브라우저가 웹 컨테이너의 응답을 받은 후
      다시 요청을 보낼 새로운 URL 이 포함되어있다.
      여기서 하나의 요청이 종결된다.
      새로 부여받은 URL 로 브라우저가 완전히 새롭게 요청하기 때문에
      이전의 요청 스코프에 저장되어있던 객체는
      새로운 요청이 이루어지기 전에 소멸된다.
      리다이렉트는 추가적으로 발생한 왕복처리 때문에 포워딩보다 느리다고 할 수 있다.
    //-- 똑같은 요청사항을 매번 서버에 전달해야하는 클라이언트에게 불편한 상황이 될 수 있음
    //-- 다만, 포워딩과 다른 점은 어느 서버가 처리했는지를 확인할 수 있게 됨
    
      기억해야 할 것은
      최종적으로 수행해야 하는 작업은 새로운 요청에 의한 것이고
      이것을 클라이언트가 알고 있기 때문에
      브라우저 창의 주소가 처음 요청한 주소가 아니고
      최종 주소값으로 변하게 된다.
      또한, 하나의 요청에 담겨 있던 객체들은 소멸되고
      다음 작업까지 전달되지 않는다.
    =============================================================================================
    ※ 기본적으로 클라이언트의 입장에서 편한 것은 포워딩이지만,
       DB 에서 작업이 이루어지고, 다시 그에 대한 응답을 받은 클라이언트가
       새로운 요청을 하게끔 만들어야 하는 경우는 리다이렉트를 사용해야 한다.
    //-- 서버가 처리할 수 없는 업무를, 처리할 수 있는 서버로 전달하게 할 수 있기 때문에


    WebApp07
    데이터 송수신 실습
    • 데이터 송수신 실습 10
      - 리다이렉트, 포워딩
    <%@ page contentType="text/html; charset=UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Send10.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	<h1>데이터 송수신 실습 10</h1>
    	<hr>
    </div>
    
    <!-- Send10.jsp → Send10_re.jsp → Receive10.jsp --> 
    <!-- Send10.jsp → Send10_for.jsp → Receive10.jsp  -->
    
    <!-- 사용자 최초 요청 페이지 -->
    <!-- http://localhost:8090/WepApp07/Send10.jsp -->
    
    <div>
    	<h2>포워딩 및 리다이렉트</h2>
    </div>
    
    <div>
    	<!-- action 처리에 대한 분기 -->
    	<form action="" method="post" id="testForm">
    		이름
    		<input type="text" name="userName" class="txt">
    		<br><br>
    		
    		<!-- check -->
    		<!-- this는 해당 button  this.form 은 해당 폼 this.form.action 은 해당 폼의 액션 -->
    		<button type="submit" class="btn" style="width: 150px;"
    		onclick="this.form.action='Send10_re.jsp'">리다이렉트</button>	
    		
    		<button type="submit" class="btn" style="width: 150px;"
    		onclick="this.form.action='Send10_for.jsp'">포워드</button>
    		
    	</form>
    </div>
    
    </body>
    </html>

    • 리다이렉트
    더보기
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// 이전 페이지(Send10.jsp)로부터 데이터 수신
    	// → userName
    	
    	// ①
    	request.setCharacterEncoding("UTF-8");
    
    	String userName = request.getParameter("userName");
    	//-- setAttirbute한 값은 getAttibute로 가져와야 함
    
    	// 이 페이지에서 수행한 추가 작업
    	// ②
    	request.setAttribute("message", "반갑습니다.");
    	//-- request 객체의 key(message)의 값 안에
    	//   "반갑습니다." 를 value 로 넣는 작업 수행 
    	
    	//-- 3번을 수행하면서 2번까지의 속성은 사라지게 됨
    	
    	// ※ 리다이렉트
    	// ③
    	response.sendRedirect("Receive10.jsp");
    	//-- 해당 주소로 가세요~
    	
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Send10_re.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	<h1>데이터 송수신 실습 10</h1>
    	<hr>
    </div>
    
    <div>
    	<h2>리다이렉트</h2>
    </div>
    
    <div>
    	<!-- <p>이름 : 폼폼푸린</p> -->
    	<p>이름 : <%=userName %></p>
    </div>
    
    </body>
    </html>

    1. 브라우저가 Receive10.jsp 에서 결과를 확인함을 알 수 있다.
    2. 요청한 내용들이 null 로 표현 됨
        → 요청 사항을 전해 준 것은 Send10.jsp 이며 데이터를 수신한 것은 Send10_re.jsp 임
             최종 수신 페이지는 당연히 Send10_re.jsp 가 받은 데이터가 뭔지 알 수 없다!


    • 포워딩
    더보기
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// 이전 페이지(Send10.jsp)로부터 데이터 수신
    	// → userName
    	
    	// ①
    	request.setCharacterEncoding("UTF-8");
    
    	String userName = request.getParameter("userName");
    	
    	// 이 페이지에서 수행한 추가 작업
    	//②
    	request.setAttribute("message", "안녕하세요.");
    	//-- request 객체의 key (message)의 값 안에
    	//   "안녕하세요."를 value 로 넣는 작업 수행
    	
    	// 스크립릿 영역에서도 포워딩은 가능하나 좀 더 복잡한 기능 사용 필요...
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Send10_for.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	<h1>데이터 송수신 실습 10</h1>
    	<hr>
    </div>
    
    <div>
    	<h2>포워드</h2>
    </div>
    
    <div>
    	<!-- <p>이름 : 포챠코</p> -->
    	<p>이름 : <%=userName %></p>
    </div>
    
    <!-- ※ 포워드 -->
    <!-- 	포워딩을 수행하는 JSP 액션 태그 활용 -->
    <!-- 	③ -->
    <jsp:forward page="Receive10.jsp"></jsp:forward>
    <!-- jsp 접두어 태그가 붙으면 : 액션 태그  -->
    <!-- 컨테이너 내에서 해결하기 때문에 값이 날라가지 않음 --> 
    
    </body>
    </html>

    1. 브라우저가 나타내는 페이지는 Receive10.jsp 이나 Send01_for.jsp 에서 처리한 것으로 보임
    2. 이름과 내용 모두 잘 전달 됨

    사실 클라이언트를 만나는 것은 Receive10.jsp  (주소만 Send10_for.jsp)


    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// 이전 페이지(Send10_re.jsp)로부터 데이터 수신
    	// → userName, message
    	
    	request.setCharacterEncoding("UTF-8");
    
    	String userName = request.getParameter("userName");
    	
    	String message= (String)request.getAttribute("message");
    	
    	//-- 리다이렉트에서 사실 상 해당 값들은 Send10_re.jsp 에서 가져오는 것으로 이미 소멸 된 상태-- null
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Receive10.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	<h1>데이터 송수신 실습 10</h1>
    	<hr>
    </div>
    
    <div>
    	<h2>최종 수신 페이지(Receive10.jsp)</h2>
    </div>
    
    <div>
    	<!-- <p>이름 : 폼폼푸린</p> -->
    	<p>이름 : <%=userName %></p>
    	
    	<!-- <p>내용 : 푸딩같은 하루</p> -->
    	<p>내용 : <%=message %></p>
    </div>
    
    </body>
    </html>


    • 데이터 송수신 실습 11
      - Send11 - Forward11 - Receive11
      - 리다이렉트 방식에서 데이터를 수신해오는 방법
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Send11.html</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    <style type="text/css">
    	.txt { width: 100px;}
    </style>
    </head>
    <body>
    
    <div>
    	<h1>데이터 송수신 실습 11</h1>
    	<hr>
    </div>
    <div>
    <!-- ■■■ 포워딩 / 리다이렉트 관련 중요한 실습 ■■■ -->
    
    <!-- ① 사용자 최초 요청 페이지 -->
    <!-- 	사칙연산 수행을 위한 정수 입력 페이지 구성
            연산자를 함께 입력받을 수 있도록 처리
            정수1 / 정수2 / 연산자
            http://localhost:8090/WebApp07/Send11.html -->
    <!-- // 사전에 동적으로 받아오는 페이지라면 html 이 아닌 jsp 로 처리 -->
    
    <!-- ② 연산 전용 페이지 -->
    <!-- 	스크립릿 코드만 존재 + jsp:forward 액션 태그 // 액션태그만 스크립릿 영역을 벗어난다
            → 추후 이 코드를 java 로 분리하여 → Servlet 으로 구성할 예정
            http://localhost:8090/WebApp07/Forward11.jsp -->
    <!-- // 궁극적 목적 : 로직이기 때문에, html 이 아닌, Servlet (java)으로 구성하는 것이 좋다
    	 request.dispatcher 를 통해 액션태그도 java로 처리하는 방법을 추후 확인 -->
    
    <!-- ③ 최종 결과 출력 페이지 -->
    <!-- 	연산 전용 페이지에서 처리한 결과를 넘겨받아 클라이언트와 대면할 페이지로 구성
            → 추후 이 페이지는 jsp view 페이지의 역할을 수행할 예정
            http://localhost:8090/WebApp07/Receive11.jsp -->
    </div>
    
    <div>
    	<!-- name 속성값, submit 버튼, action속성 처리 // method : post나 get 상관없음 -->
    	<!-- jsp:forward 액션 태그 사용 페이지 -->
    	<!-- <form action="Forward11.jsp" method="post"> -->
    	
    	<!-- jsp:forward 액션 태그 없이 포워딩 처리 페이지 요청 -->
    	<form action="Forward11_1.jsp" method="post">
    		정수 1
    		<input type="text" class="txt" name="num1">
    		
    		연산자
    		<!-- <select name="op"> -->
    		<select name="calResult">
    			<option selected="selected">연산선택</option>
    			<option value="1">더하기</option>
    			<option value="2">빼기</option>
    			<option value="3">곱하기</option>
    			<option value="4">나누기</option>
    		</select>
    		
    		정수 2
    		<input type="text" class="txt" name="num2">
    		<input type="submit" class="btn control" value="확인">
    	</form>
    </div>
    	
    </body>
    </html>

    • Foward11.jsp : 액션 태그 없이 포워딩 처리
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// 클라이언트를 만나지 않는 Forward11.jsp 
    	
    	// 이전 페이지(Send11.html)로부터 데이터 수신
    	// → num1, num2, op
    	String num1Str  = request.getParameter("num1");
    	String num2Str  = request.getParameter("num2");
    	String op = request.getParameter("op");
    
    	int num1 = 0;
    	int num2 = 0;
    	String str = "";	
    	
    	try
    	{
    		num1 = Integer.parseInt(num1Str);
    		num2 = Integer.parseInt(num2Str);
    		
    		switch(Integer.parseInt(op))	// if~else 로도 처리 가능
    		{
    			case 1 : str = String.format("%d + %d = %d",num1,num2,(num1+num2));  break;
    			case 2 : str = String.format("%d - %d = %d",num1,num2,(num1-num2));  break;
    			case 3 : str = String.format("%d * %d = %d",num1,num2,(num1*num2));  break;
    			case 4 : str = String.format("%d / %d = %.1f",num1,num2,(num1/(double)num2));  break;
    		}
    		// 여기까지 수행하면 str 값은 수신한 데이터에 들어가있지 않음
    		// check !
    		request.setAttribute("result", str); 
    		//                   --------  ---
    		//             key값--(이름) (데이터)--value값 이라고 생각하면 됨
    	}
    	catch (Exception e)
    	{
    		System.out.println(e.toString());
    	}
    	
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Foward11.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <jsp:forward page="Receive11.jsp"></jsp:forward>
    <!-- 내부적으로 서블릿컨테이너가 forwarding 을 해달라고 확인하게 되는 구문 -->
    <!-- 자바의 영역이 아니기 때문에 -> 자바의 영역 안(스크립트 릿 영역)으로 넣는 것을 확인 -->
    
    </body>
    </html>

    • Forward11_1.jsp : 액션 태그 없이 포워딩 처리
      - RequestDispatcher 인터페이스
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	//Foward11_1.jsp
    	
    	// 이전 페이지(Send11.html)로부터 데이터 수신
    	// → num1, num2, calResult
    	
    	String num1Str = request.getParameter("num1");
    	String num2Str = request.getParameter("num2");
    	String calResult = request.getParameter("calResult");
    	
    	int num1 = 0;
    	int num2 = 0;
    	String result = "";
    	
    	try
    	{
    		num1 = Integer.parseInt(num1Str);
    		num2 = Integer.parseInt(num2Str);
    		
    		if(calResult.equals("1"))
    			result = String.format("%d + %d = %d", num1, num2, (num1+num2));
    		else if(calResult.equals("2"))
    			result = String.format("%d - %d = %d", num1, num2, (num1-num2));
    		else if(calResult.equals("3"))
    			result = String.format("%d * %d = %d", num1, num2, (num1*num2));
    		else if(calResult.equals("4"))
    			result = String.format("%d / %d = %.1f", num1, num2, (num1/(double)num2));
    	}
    	catch(Exception e)
    	{
    		System.out.println(e.toString());
    	}
    	
    	request.setAttribute("resultStr", result);
    	
    	// check~!
    	RequestDispatcher dispatcher = request.getRequestDispatcher("Receive11.jsp");
    	//--			튀어나온 비서= request 객체 로부터 RequestDispatcher를 얻어내고 (새로운 Servlet 할당)
    	dispatcher.forward(request, response);
    	//-- 비서는 request나 response를 생성할 수 없기 때문에 
    	//-- 비서가 request, response 를 갖고 가져갈 수 있게 해서 포워딩시킴
    	//-- Receive11.jsp 로 제어권이 넘어간다~~~
    	
    	//-- RequestDispatcher 도... ServletContainer 도 볼 수 없다
    	//-- 다만 도구로서 사용할 수 있게 상상해서 이해할 수 있도록 하자...
    	/* ======================================================================================================
    	■■■ 『RequestDispatcher』 인터페이스 ■■■
    	
    	※ 이 인터페이스는 『forward()』와 『include()』만 있다.
    	
    	※ 처리 과정 및 개념
    	
    	   일반적으로 HttpServlet 을 상속받는 *클래스*... 서블릿
    	   //-- 서블릿을 extends 하는 방법이 여러가지 있으나 웹기반에서는 HttpServlet 기반으로 작성多
    	   
    	   이렇게 작성된 클래스 내부에는
    	   실제 요청을 서비스하는 『doGet()』 과 『doPost()』 메소드가
    	   정의되어 있으며 (service() 메소드가 이들의 상위메소드)
    	   
    	  ServletContainer 는 『HttpServlet』의 인스턴스를 생성하고,
    	  『init()』메소드를 실행해 주고, 
    	  이 메소드에 의해 매핑된 URL 에							//-- 서비스 서비스 해주는 과정에서
    	  (페이지 요청 방식에 따라) doGet() 과 doPost() 중 선택하여
    	  메소드를 호출해 주고(실행시켜주고)
    	  Container 가 종료될 때 『destroy()』 메소드를 호출해 주고,
    	  관련된 처리 과정이 마무리 된다.
    	  
    	  즉,* ServletContainer 가 *	//-- 호출 주체!!!
    	  init()	→ 처음
    	  service()	→ 중간중간 요청이 있을 때 마다
    	  destroy()	→ 마지막
    	  메소드를 호출한다.
    	  (절대 우리가 직접 호출하는 것이 아니다.)
    	  
    	  결국 『HttpServlet』은 
    	  하나의 인스턴스만 생성되어 *멀티 스레딩*으로 돌아가게 된다.
    	  //-- cf) CGI 방식 : 인스턴스가 매번 생성되는 방식
    	  
    	  이렇게 구성되는 『HttpServlet』의 상속된 클래스의 인스턴스는
    	  스레드에 안전하게 설계(스레드 세이프티)되어야 하고
    		//-- 오라클의 트랜젝션과 비슷
    		//-- cf) 개인용 운영체제    vs    서버용 운영체제
    		//       개인만 사용              여러 사용자가 사용
    		//       전속쉐프가 있는 느낌     일반 식당 주방장(다른데도 서비스 제공)
    		//   즉, 멀티 스레드는 서벼용 운영체제 같은 느낌이다.
    		//   작업 요청을 해도 서비스를 받기까지 기다리는(대기하는) 시간이 존재
    	  따라서 스레드에 안전하게 설계하지 않은 경우
    	  상위 클래스를 마구 접근하게 되어 에러가 발생할 수 밖에 없다.
    	  
    	  이와 같은 이유로 환경 설정이나 J2EE 서비스에 관한 내용은
    	  	//-- J2EE : 자바 엔터프라이즈급 서비스
    	  『ServletContext』 에서 할 수 있게 된다.
    	  (※ ServletContext : 서블릿에 대한 환경, 상태 등을 설정할 수 있는 객체)
    	  	//	※ Context 
    	  	//     책에 쓰여진 글자는 텍스트
    	  	//     책에 쓰여진 문장도 텍스트, 문장이 내포하고 있는 의미를 서브텍스트라고 함
    	  	//	   서브텍스트를 읽어내어 그에 대한 파급효과를 생각해서 얻어내는 결과를 context 라고 함
    	  	//--   만들어왔던것 만들고 있는 것 앞으로 만들어 낼 것들도 context 라고 함
    	  이 『ServletContext』는 『getServletContext()』로만 받을 수 있다.
    	  그렇기 때문에 이 『get ServletContext()』는 
    	  동기화가 제대로 구현되어 있을 것이라고 예측할 수 있다.
    	  그 이유는 멀티스레드에 안전하게 설계(세이프티) 되어있어야 
    	  우리가 『ServletContext』의 『setAttribute()』 나 『getAttribute()』를
    	  스레드 걱정 없이 마음대로 읽고 쓸 수 있기 떄문이다.
    	  
    	  *『ServletContext』의 또 다른 커다란 기능 중 하나는
    	  다른 서블릿 인스턴스를 가져올 수 있다거나
    	  서블릿 환경 설정값을 가져올 수 있는 기능이다.*
    	  
    	  *『RequestDispatcher』역시 그 기능 중의 하나이다.
    	  사전적인 의미로는... 요청을 제공하는 도구*
    		//-- 실제 ServletContainer 와 ServletContext는 구분하여 별개로 생각하지 않아도 된다.
    		//-- ServletContainer라고 봐도 무방하다.
    	  즉, 요청을 보내주는 인터페이스이다.
    	  
    	  현재... 요청을 다른 서블릿(혹은 JSP)으로 보내야 하는 상황
    		//-- JSP도 일종의 Servlet 이기 때문
    	  그런데, 위에 언급한 바와 같이 서블릿의 인스턴스는 하나만 생성되고
    	  이것이 멀티 스레딩으로 돌아가고 있다.
    	  	//-- Servlet이 일하고 있는데 저기가서 일을 해줄 일꾼이 필요하고,
    	  	//-- 그 일꾼이 결국 Dispatcher 라는 느낌 
    	  
    	  그렇기 때문에 새로운 서블릿을
    	  그 서블릿을 실행하는 것 만으로는 안되고
    	  이미 돌아가고 있는 서블릿 인스턴스의 스레드를
    	  하나 더 추가해야한다.
    	  	//-- ServletContainer 에게 일을 시킬 때 개발자가 할 수 있는 가이드라인이 있고
    	  	//-- 즉, 서블릿에게 직접 이거 해 저거 해 마음대로는 못시킴(가이드라인이 있기 때문)
    	  	//-- 그 가이드라인이 JSP Servlet 인것.
    	  이것은 서블릿개발자가 처리해야 할 영역을 벗어났기 때문에
    	  이 일은 『Dispatcher』가 대신 수행해준다는 것이다.
    	  
    	  하지만, 이 『Dispatcher』는 
    	  『HttpServletRequest』, 『HttpServletResponse』를
    	  생성해 줄 수 없다.
    	  그렇기 때문에 『Dispatcher』가 생성해준 새로운 서블릿 스레드를
    	  실행시키기 위해 『doGet()』이나 『doPost()』를 호출해야 한다.
    	  
    	  이와 같은 이유로
    	  『dispatcher.forward(request, response);』구문을 통해
    	  request 와 response 를 넘겨주는 것이다.
    	
    	====================================================================================================== */
    
    %>

    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// 이전 페이지(Forward11.jsp)로부터 데이터 수신
    	// → resultStr 
    	//    ---------
    	//    setAttribute();   → getAttibute(); 로 꺼낸다
    	String num1Str = request.getParameter("num1");
    	String num2Str = request.getParameter("num2");
    	String op = request.getParameter("op");
    	
    	switch(Integer.parseInt(op))
    	{
    		case 1 : op="더하기"; break;
    		case 2 : op="빼기"; break;
    		case 3 : op="곱하기"; break;
    		case 4 : op="나누기"; break;
    	}
    	
    	String result = (String)request.getAttribute("result");
    	//              --------                     -------- key 값
    	//  (형변환: 다운캐스팅)------------------------------ Object 타입 
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Receive11.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    <div>
    	<h1>데이터 송수신 실습 11</h1>
    	<hr>
    </div>
    <div>
    	<h2>받은 데이터</h2>
    	정수1 : <%=num1Str %> <br> 정수2 : <%=num2Str %> <br> 연산자 : <%=op %>
    </div>
    <br>
    <div>
    	<!-- <h2>연산 결과 : 30 + 20 = 50</h2> -->
    	<h2>연산 결과 : <%=result %></h2>
    </div>
    </body>
    </html>


    • 데이터 송수신 실습 12
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Send12.html</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    <style type="text/css">
    	.txt { width: 100px;}
    </style>
    </head>
    <body>
    
    <div>
    	<h1>데이터 송수신 실습 12</h1>
    	<hr>
    </div>
    <div>
    <!-- ■■■ 포워딩 / 리다이렉트 관련 중요한 실습 ■■■ -->
    
    <!-- ① 사용자 최초 요청 페이지 -->
    <!-- 	사칙연산 수행을 위한 정수 입력 페이지 구성
            연산자를 함께 입력받을 수 있도록 처리
            정수1 / 정수2 / 연산자
            http://localhost:8090/WebApp07/Send12.html -->
    
    <!-- ② 연산 전용 페이지 -->
    <!-- 	response.sendRedirect() 를 포함한 스크립 릿 코드만 존재
            → 추후 이 코드를 java 로 분리하여 → Servlet 으로 구성할 예정
            http://localhost:8090/WebApp07/Redirect12.jsp -->
    
    <!-- ③ 최종 결과 출력 페이지 -->
    <!-- 	연산 전용 페이지에서 처리한 결과를 넘겨받아 클라이언트와 대면할 페이지로 구성
            → 추후 이 페이지는 jsp view 페이지의 역할을 수행할 예정
            http://localhost:8090/WebApp07/Receive12.jsp -->
    </div>
    
    <div>
    	<!-- name 속성값, submit 버튼, action속성 처리 // method : post나 get 상관없음 -->
    	<!-- Redirect 처리 페이지 요청 -->
    	<form action="Redirect12.jsp" method="post">
    		정수 1
    		<input type="text" class="txt" name="num1">
    		
    		연산자
    		<!-- <select name="op"> -->
    		<select name="calResult">
    			<option selected="selected">연산선택</option>
    			<option value="1">더하기</option>
    			<option value="2">빼기</option>
    			<option value="3">곱하기</option>
    			<option value="4">나누기</option>
    		</select>
    		
    		정수 2
    		<input type="text" class="txt" name="num2">
    		<input type="submit" class="btn control" value="확인">
    	</form>
    </div>
    
    </body>
    </html>

    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	//Redirect12.jsp
    
    	String num1Str = request.getParameter("num1");
    	String num2Str = request.getParameter("num2");
    	String calStr = request.getParameter("calResult");
    	
    	int num1 = 0;
    	int num2 = 0;
    	String str = "";
    	
    	try
    	{
    		num1 = Integer.parseInt(num1Str);
    		num2 = Integer.parseInt(num2Str);
    		
    		if(calStr.equals("1"))
    			str += String.format("%d",(num1+num2));
    		else if(calStr.equals("2"))
    			str += String.format("%d", (num1-num2));
    		else if(calStr.equals("3"))
    			str += String.format("%d", (num1*num2));
    		else if(calStr.equals("4"))
    			str += String.format("%.1f", (num1/(double)num2));
    	}
    	catch(Exception e)
    	{
    		System.out.println(e.toString());
    	}
    
    	//check!
    	// response 하면서 *내용이 사라진다는 것이 핵심*
    	// 결과 데이터 재전송 → sendRedirect() 메소드 사용
    	// ※ response 객체의 주요 메소드 중 하나인
    	//    『sendRedirect(String location)』
    	//    : 지정된 URL(location)로 요청을 재전송한다.
    	
    	// ex) reponse.sendRedirect("Receive12.jsp");
    	//    → 클라이언트에게 Receive12.jsp 페이지를 다시 요청할 수 있도록 **안내**
    
    	// 방식 1 -- post 방식
    	//pageContext.getSession().setAttribute("resultStr", str);
    	//response.sendRedirect("Receive12.jsp");
    	
    	// 방식 2 -- get 방식 (장점 : 여러형태로 요청 할 수 있다!!!!! -- 이래서 post 만 사용하기는 힘들다...)
    	//-- 즉, 주소 뿐만 아니라 요청받았던 값까지 메모해서 넘겨줄 수 있는 것
    	response.sendRedirect("Receive12.jsp?num1="+num1+"&num2="+num2+"&op="+calStr+"&str="+str);
    	//-- 클라이언트에게 Receive12.jsp 페이지를 요청하며 각 속성값들을 넘겨줄 수 있도록 **안내**
    	//-- 메모를 받은 브라우저가 직접 메모를 보고 찾아가는 것이기 때문에 "안내" 하는 것이다.
    %>

    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// 방식 1
    	//String result = (String)pageContext.getSession().getAttribute("resultStr");
    	
    	// 이전 페이지로(Redirect12.jsp)부터 데이터 수신
    	// → num1, num2, calStr, str
    		//-- Send12 가 Redirect12 로 데이터를 보냈고 해당 데이터는 Redirect12 에서 사라졌다. 
    	//-- 즉, Receive12는 직접 Redirect12.jsp 로부터 데이터를 넘겨받는 것이 아니라
    		//-- Redirect12가 주소랑 값을 메모해서 사용자 브라우저(클라이언트)로 주고
    		//-- 사용자의 브라우저가 Receive12 에 가서 사용자 브라우저가 메모를 건네주게 되는 것 
    	//   클라이언트가 새로운 요청을 하는 과정에서 넘긴값을 수신하게 되는 개념
    	
    	// ==> 클라이언트의 새로운 요청으로부터 데이터 수신 // check
    	//     → Receive12.jsp?num1="+num1+"&num2="+num2+"&calStr="+calStr+"&str="+str
    	
    	// 방식 2
    	String num1 = request.getParameter("num1");
    	String num2 = request.getParameter("num2");
    	String op = request.getParameter("op");
    	String str = request.getParameter("str");
    	
    	switch(Integer.parseInt(op))
    	{
    		case 1 : op="+"; break;
    		case 2 : op="-"; break;
    		case 3 : op="*"; break;
    		case 4 : op="/"; break;
    	}
    	
    	String result = String.format("%s %s %s = %s", num1, op, num2, str);
    %>
    
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Receive12.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	<h1>데이터 송수신 실습 12</h1>
    	<hr>
    </div>
    
    <div>
    	연산 결과 : <%=result %>
    </div>
    
    </body>
    </html>

    WebApp08
    서버 연동하기 (Oracle + Eclipse)
    • DBConn,java
    더보기
    /*=============================================
    	DBConn.java
    	- 데이터베이스 연결 전용 객체(Singleton)
    	- 예외 처리 : throws
     =============================================*/
    
    package com.util;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class DBConn
    {
    	private static Connection dbConn;
    	
    	public static Connection getConnection() throws ClassNotFoundException, SQLException
    	{
    		if (dbConn==null)
    		{
    			String url = "jdbc:oracle:thin:@localhost:1521:xe";
    			String user = "scott";
    			String pwd = "tiger";
    			
    			Class.forName("oracle.jdbc.driver.OracleDriver");
    			dbConn = DriverManager.getConnection(url,user,pwd);
    		}
    		return dbConn;
    	}
    	
    	public static Connection getConnection(String url, String user, String pwd) throws ClassNotFoundException, SQLException
    	{
    		if (dbConn==null)
    		{
    			Class.forName("oracle.jdbc.driver.OracleDriver");
    			dbConn = DriverManager.getConnection(url,user,pwd);
    		}
    		return dbConn;
    	}
    	
    	public static void close() throws SQLException
    	{	
    		if (dbConn != null)
    		{
    			if (!dbConn.isClosed())
    				dbConn.close();
    		}
    		
    		dbConn = null;
    	}
    	
    }

    SQL

    SELECT USER
    FROM DUAL;
    --==>> SCOTT
    
    SELECT *
    FROM TAB;
    
    -- 기존 테이블 제거
    DROP TABLE TBL_MEMBER;
    --==>> Table TBL_MEMBER이(가) 삭제되었습니다.
    
    -- 휴지통 비우기
    PURGE RECYCLEBIN;
    --==>> RECYCLEBIN이(가) 비워졌습니다.
    
    -- 기존 시퀀스 제거
    DROP SEQUENCE MEMBERSEQ;
    --==>> Sequence MEMBERSEQ이(가) 삭제되었습니다.
    
    -- ○실습 테이블 생성(TBL_MEMBER)
    CREATE TABLE TBL_MEMBER
    ( SID   NUMBER
    , NAME  VARCHAR2(30)
    , TEL   VARCHAR2(40)
    , CONSTRAINT MEMBER_SID_PK PRIMARY KEY(SID)
    );
    --==>> Table TBL_MEMBER이(가) 생성되었습니다.
    
    -- ○시퀀스 생성 
    CREATE SEQUENCE MEMBERSEQ
    NOCACHE;
    --==>> Sequence MEMBERSEQ이(가) 생성되었습니다.
    
    -- ○데이터 입력 쿼리문 구성
    INSERT INTO TBL_MEMBER(SID,NAME,TEL)
    VALUES(MEMBERSEQ.NEXTVAL,'둘아현','010-2222-2222');
    --> 한 줄 구성
    INSERT INTO TBL_MEMBER(SID,NAME,TEL) VALUES(MEMBERSEQ.NEXTVAL,'둘아현','010-2222-2222')
    ;
    --==>> 1 행 이(가) 삽입되었습니다.
    
    -- ○샘플 데이터 추가 입력
    INSERT INTO TBL_MEMBER(SID,NAME,TEL) VALUES(MEMBERSEQ.NEXTVAL,'기배리','010-2222-3333')
    ;
    INSERT INTO TBL_MEMBER(SID,NAME,TEL) VALUES(MEMBERSEQ.NEXTVAL,'수현양','010-2222-4444')
    ;
    INSERT INTO TBL_MEMBER(SID,NAME,TEL) VALUES(MEMBERSEQ.NEXTVAL,'키민킴','010-2222-5555')
    ;
    INSERT INTO TBL_MEMBER(SID,NAME,TEL) VALUES(MEMBERSEQ.NEXTVAL,'리서최','010-2222-6666')
    ;
    --==>> 1 행 이(가) 삽입되었습니다. * 4
    
    -- ○ 테이블 전체 조회 쿼리문 구성 (리스트 확인)
    SELECT SID, NAME, TEL
    FROM TBL_MEMBER
    ORDER BY SID;
    --> 한 줄 구성
    SELECT SID, NAME, TEL FROM TBL_MEMBER ORDER BY SID
    ;
    --==>>
    /*
    1	둘아현	010-2222-2222
    2	기배리	010-2222-3333
    3	수현양	010-2222-4444
    4	키민킴	010-2222-5555
    5	리서최	010-2222-6666
    */
    
    -- ○인원수 확인 쿼리문 구성
    SELECT COUNT(*)AS COUNT
    FROM TBL_MEMBER;
    --> 한 줄 구성
    SELECT COUNT(*)AS COUNT FROM TBL_MEMBER
    ;
    --==>> 5
    
    -- ○커밋
    COMMIT;
    --==>> 커밋 완료.

    • Test001.jsp
    <%@page import="com.util.DBConn"%>
    <%@page import="java.sql.Connection"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	String str = "";
    	
    	try
    	{
    		Connection conn = DBConn.getConnection();
    		
    		if(conn != null)
    			str += "데이터베이스 연결 성공";
    	}
    	catch (Exception e)
    	{
    		//System.out.println(e.toString());
    		str += e.toString();
    	}
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Test001.java</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    <div>
    	<h1>데이터베이스 연결 실습</h1>
    	<hr>
    </div>
    
    <div>
    	<!-- <h2>연결 결과 : 블라블라...</h2> -->
    	<h2>연결 결과 : <%=str %></h2>
    </div>
    
    </body>
    </html>
    728x90
Designed by planet-si