열심히 끝까지

디바이스 융합 자바(Java) day36 - 서버,클라이언트,HTTP명령(GET,POST),아파치 톰캣,JSP파일,서블릿(Servlet),자바 빈즈(JAVA BEANS),JSP&HTML&Servlet&JAVA 이용한 계산기 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)

디바이스 융합 자바(Java) day36 - 서버,클라이언트,HTTP명령(GET,POST),아파치 톰캣,JSP파일,서블릿(Servlet),자바 빈즈(JAVA BEANS),JSP&HTML&Servlet&JAVA 이용한 계산기

노유림 2022. 8. 1. 15:46

[오늘 수업]

서버
       Server
       서비스를 제공하는 컴퓨터
       웹 호스팅
       요청(사용자)을 받아서 서비스를 제공하는 쪽(응답하는 쪽)

클라이언트
       Client
       서비스를 이용하는 컴퓨터
       사용자(==브라우저, 클라이언트 라고도 가능)
       브라우저(브라우저에서 요청이 들어감)
       요청을 시도하는 쪽

HTTP(프로토콜) 명령 : GET, POST
                 사용자의 요청에 의해 서버에서 전송된 HTML 태그(페이지가 응답)는
                 웹 브라우저에 의해 해석되어
                 화면 구성 및 배치 작업 등을 거쳐 제공됨 

   <방식 종류>
        GET 
                : URL에 정보가 노출됨(보안 불리)
                : 전달할 수 있는 데이터 크기에 제한이 존재
                : URL ? 뒤에 매개변수=값&매개변수=값 방식으로 진행
                : CRUD 중에 R(데이터를 로드) 작업에 많이 활용 - 특히 SELECT에 사용
                      -> 서버에서 정보를 가져오려고 사용하는 방법
        POST
                : URL에 값이 표시되지 않음
                : 요청헤더에 데이터를 넣어 전송하기 때문에,
                  데이터 크기에 제한이 없음
                : CRUD 중에 CUD(데이터를 전달) 작업에 많이 활용
                      -> 서버에 정보를 전달하려고 사용하는 방법

        
        >>     사용자의 요청에 의해 서버에서 전송된 HTML 태그(페이지가 응답)는
                 웹 브라우저에 의해 해석되어
                 화면 구성 및 배치 작업 등을 거쳐 제공됨 

    >> CRUD는 절대적이지 않음, 주로 그렇게 진행된다는 이야기

 

- [클라이언트와 서버 간의 동작 과정(웹 서비스 진행 과정)]
    1) URL 입력
    2) IP 주소로 변환
    3) HTML 페이지 요청
    4) 3의 요청 내용을 분석
    5) HTML 파일 전송
    6) HTML 태그를 분석하여 화면 구성

 

[아파치 톰캣]
          : 웹 서버의 역할을 맡을 것
         - 웹서버란?
             : JSP가 운영될 환경(JSP 운영체제)
               >> 서블릿 컨테이너★
                       : 서블릿과 JSP를 실행하기 위한 환경을 제공함

           : WEB/WAS의 기능을 가진 자바 어플리케이션
           : JAVA EE 기반으로 만들어짐

 


[WAS]
           : 자바로 만들어진 JSP와 Servlet을 구동하기 위한 서블릿 컨테이너 역할을 수행
           : 이 때, 컨테이너란? - JSP를 서블릿으로 바꿔서 실행해주는 역할과 서블릿 생명주기를 관리하며
                                         웹 환경에서 서블릿이 구동될 수 있도록 해주는 프로그램
           : 여러 개의 컨테이너를 구성해서 각각 독립적인 서비스로 구동시키는 것 가능
           : WAS의 컨테이너는 
            1. 웹서버에서 보내준 요청을 가지고 스레드를 생성 후,
            2. 필요한 JSP나 Servlet 파일을 구동해서 로직을 수행
            3. 결과로 생성된 응답 객체를 웹서버에 보내주는 역할
           : 하나의 WAS에 하나의 컨테이너만 사용한다면 
            굳이 WAS와 컨테이너를 나눠서 생각할 필요는 없을 것 같음 

 

JSP 파일 
    : HTML과 비슷하게 생김(두 줄 제외)
    : JSP는 JAVA언어를 사용할 수 있게 해주는 서버 프로그래밍 언어
 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP</title>
</head>
<body>

<!-- HTML 주석 -->
<%-- JSP 주석 --%>
<!-- 단축키 사용 불가 -->
<%-- Date가 자바 유틸안에 있어서 빨간 줄 --%>
<%-- 1. 풀로 작성하는 방법 <%= new java.util.Date() %> --%>
<%-- 2. import 속성 사용, 위에 import(import="java.util.*") 하고 <%= new Date() %> --%>
<h1><%= new Date() %></h1>
<p>JAVA 언어를 사용할 수 있게 해주는 서버 프로그래밍 언어</p>

</body>
</html>


주석 방법
HTML : <!-- -->
JSP : <%-- --%>

수정하는 법
<%에 빨간 글씨 뜨면 진행
project properties > java buildpath > classpath 
 > Server Runtime [Apache Tomcat v9.0]이 없어서 컴파일 안되는 것
 > 추가할 것 

 - [<%@  %>] 
    : '지시어' 라고 함
    : @뒤에 page가 오면 'page 지시어' 라고 함
        >> language속성이 기술되어 있는 이유는 
             다른 언어와 결합이 될 때 사용될 수 있게 기술
            >> 하지만.. 잘 안쓰임..
        >> contentType 속성
        >> java 로직에 대한 인코딩 방식 

 

- [JSP]란?
        : HTML 코드 내부에 JAVA 언어를 사용할 수 있게 해주는 서버 프로그래밍 언어
     D:\0607RYO\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\day36\org\apache\jsp
       >>의 NewFile_jsp.java 파일 존재
       >> 컴파일 결과로 .java로 끝나는 파일을 생성함
            => 서블릿 Servlet 파일 이라고 함

 

package test;

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

/**
 * Servlet implementation class Test
 */
@WebServlet("/Test")
public class Test extends HttpServlet { // 많은 것들이 자동 import 됨
	private static final long serialVersionUID = 1L;
      
    public Test() {
        super();
        // TODO Auto-generated constructor stub
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("<!DOCTYPE html>\r\n"
				+ "<html>\r\n"
				+ "<head>\r\n"
				+ "<meta charset=\"UTF-8\">\r\n"
				+ "<title>서블릿 예제</title>\r\n"
				+ "</head>\r\n"
				+ "<body>"
				+ "<h1>APPLE BANANA</h1>");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
	
}


[서블릿 Servlet] 만들기
        : .java로 끝남
        : 패키지가 항상 존재해야 함!
        : JAVA 언어에서 HTML를 작성할 수 있게 해줌
        : 기본 생성자 필수
        : doGet(), doPost() 메서드로 GET, POST 요청에 대해 수행할 것을 작성
        : 일반적으로 public class Student와는 다른 클래스 파일
              -> Student를 POJO라고 함
              => Servlet 서블릿은 'POJO(plain of java object)가 아닌 클래스' 라고 함
        : @WebServlet(/"xxx") 어노테이션(애너테이션)
              >> 오버라이딩할 때 나옴
               : "/xxx 요청에 대해 이 서블릿 파일을 실행시켜라!"

        : 옛날에 쓰던 방식
     >> 위의 NewFile_jsp.java 보면..
        : jspInit(), jspDestroy()
        : 돌리면 웹브라우저로 결과가 뜨게 됨(console창이 아님)

 

     >> 강사님이 받고 싶은 질문
          > 이게 화면에 나왔는데 
             "doGet()이 실행"된 것은 어느 누구도 반박 불가능함 
              -> 메서드 수행 주체(==객체)가 생겼다는 뜻

             xxx.doGet();(누군가가 doGet() 실행)
             >> xxx가 생성되었다는 뜻!
                 -> xxx는 Test 서틀릿으로 만든 객체 
             => new Test();가 생성되었어야 하는데? 왜 생성이 안되어진거지..?

             => ★Test 서블릿이 객체화(인스턴스화, new)되지 않았는데
                  어떻게 doGet()이 호출되었지?????
                   >> 누군가가 new Test()하고,
                        doGet()도 호출했다!!!!

                       >> 그 누군가는!! 위에 달린
                            ★서블릿 컨테이너
                                   : 컨테이너란? - 객체화를 담당하는 기관
                                   : 서블릿을 객체화하는 기관이 서블릿 컨테이너  

 

[JSP 전체 동작 과정]
    !그림 참고!
 1) URL 입력
 2) IP 주소로 변환
 3) JSP 페이지 요청
 4) JSP 서블릿 처리
          : 웹 서버가 요청 내용을 분석,
            서블릿 컨테이너에게 요청을 넘겨서 처리
            -> new 서블릿() 객체화
            -> .doGet() 호출
 5) HTML 페이지 응답
          : 화면에 출력될 내용을 HTML 문서형태로
            웹 브라우저에게 전송               

[정리]
[JSP]
      - 확장자가. jsp인 파일
      - Java Server Page
      - html 문서 안에 자바 언어를 삽입해 사용할 수 있도록 해줌

[Servlet(서블릿)]
       - 확장자가 .java인 파일
       - 자바의 일반적인 클래스와 동일한 개념
       - 웹을 다룰 수 있도록 해주는 "HttpServlet" 클래스를 상속받는 클래스를 의미함
       - 기본 생성자 필수

>> JSP와 Servlet은 완전 다른 개념이 아니며, Servlet을 사용해 웹을 만들 경우
     화면 인터페이스 구현이 워낙 까다로운 단점을 보완하기 위해 만든 스크립트 언어가 
     JSP라고 볼 수 있음

 

<예제 계산기 - 1>
input, select
  > name 속성 값 존재
  >> name 속성으로 해당 값으로 접근할 수 있게 함

form의 submit을 통해 post 방식으로 '요청'
   : 요청에 대한 모든 정보는 '☆request 객체'에 저장되어 있음!
>> 웹에서는 모든 정보가 String으로 관리

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%
int result = 0; // 초기화 필수
if (request.getMethod().equals("POST")) {
	int num1 = Integer.parseInt(request.getParameter("num1"));
	int num2 = Integer.parseInt(request.getParameter("num2"));
	String op = request.getParameter("op");
	// 처음 보는 식은 꼭 자료형을 봐줄 것

	if (op.equals("+")) {
		result = num1 + num2;
	} else if (op.equals("-")) {
		result = num1 - num2;
	} else if (op.equals("x")) {
		result = num1 * num2;
	} else if (op.equals("/")) {
		result = num1 / num2;
	}
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>계산기 - 1</title>
</head>
<body>

	<h1>계산기</h1>
	<hr>
	<form method='post'> <!-- 초기 방식이 GET이라면 초기의 화면을 로드하는 방식(위부터 진행) -->
		<!-- 다시 돌아올 예정이기 때문에 action은 지움 -->
		<input type="text" name="num1"> <select name="op">
			<option>+</option>
			<option>-</option>
			<option>x</option>
			<option>/</option>
		</select> <input type="text" name="num2"> <input type="submit"
			value="계산 결과보기">
	</form>
	<hr>
	<h2>
		계산 결과 :
		<%=result%></h2>
	<!-- result를 정의(초기화)하기 위해서는 위에 넣기 -->
</body>
</html>

 

-----------------------------------------

<예제 계산기 - 2>
- Bean 
     : 자바 빈즈 라고도 함
     : JSP 서버 프로그램에서 로직을 갖는 클래스를 Bean 클래스라고 부름

package test;

public class CalcBean {
	// Bean
	private int num1;
	private int num2;
	private String op="";
	private int result;
	
	// null 인 것이 문제이니 만들어 주기
	// java 작업자라고 생각하고 진행
	//public CalcBean() {
		// 정색대로 해결하려면 뭔가 넣어놓아야하는데
		// 뭔가를 넣으면 계산을 진행할 것이기에.. 그냥 if문 다 동작 안하게
		// 아무것도 아닌 것을 넣기
		//this.op="";
	//}
	
	// getter setter 만들어 주기
	public int getNum1() {
		return num1;
	}
	public void setNum1(int num1) {
		this.num1 = num1;
	}
	public int getNum2() {
		return num2;
	}
	public void setNum2(int num2) {
		this.num2 = num2;
	}
	public String getOp() {
		return op;
	}
	public void setOp(String op) {
		this.op = op;
	}
	public int getResult() {
		return result;
	}
	public void setResult(int result) {
		this.result = result;
	}
	
	// 계산 기능
	// 다른 곳에서도 사용 가능하기 때문에 public으로 만들기
	public void calc() {
		if (op.equals("+")) {
			result = num1 + num2;
		} else if (op.equals("-")) {
			result = num1 - num2;
		} else if (op.equals("x")) {
			result = num1 * num2;
		} else if (op.equals("/")) {
			result = num1 / num2;
		}
	}
	
}

 

<jsp:useBean id="cb" class="test.CalcBean" />
<%-- test 패키지에 있는 CalcBean라는 이름의 클래스를 cb라는 이름으로 객체화 --%>
>> CalcBean cb = new CalcBean();
  > 다음 할 것은 setter 들을 호출하여 멤버변수를 초기화
      cb.setNum1(Integer.paseInt(request.getParameter("num")));
      cb.setNum2(Integer.paseInt(request.getParameter("num")));
      cb.setOp(request.getParameter("num"));
     >> 이 때, 자료형을 String으로 받아오기 때문에 int로 만들어주는 식 사용

>> JSP에서 자동 매핑 가능
<%-- cb라는 이름을 가진 객체의 setter 메서드 자동매핑 호출 all : * 를 의미 --%>
<jsp:setProperty property="*" name="cb"/>
    name 속성의 이름과 객체의 멤버변수명(setter명)을 비교하기 때문에
    식별자 규칙이 매우 중요!

<jsp:getProperty property="result" name="cb"/>
 >> cb.getResult();

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:useBean id="cb" class="test.CalcBean" />
<%-- test 패키지에 있는 CalcBean라는 이름의 클래스를 cb라는 이름으로 객체화 --%>
<%-- java로 치면 CalcBean cb = new CalcBean(); --%>
<%-- 다음 할 것은 setter 들을 호출하여 멤버변수를 초기화 --%>
<%-- cb라는 이름을 가진 객체의 setter 메서드 자동매핑 호출 all : * 를 의미 --%>
<jsp:setProperty property="*" name="cb"/>

<% cb.calc(); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>계산기 - 2</title>
</head>
<body>

	<h1>계산기</h1>
	<hr>
	<form method='post'> <!-- 초기 방식이 GET이라면 초기의 화면을 로드하는 방식(위부터 진행) -->
		<!-- 다시 돌아올 예정이기 때문에 action은 지움 -->
		<input type="text" name="num1"> <select name="op">
			<option>+</option>
			<option>-</option>
			<option>x</option>
			<option>/</option>
		</select> <input type="text" name="num2"> <input type="submit"
			value="계산 결과보기">
	</form>
	<hr>
	<h2>
		계산 결과 : <jsp:getProperty property="result" name="cb"/></h2>

</body>
</html>

<코드 설명>
3번라인
  : 자바에 만들어진 객체를 cb라는 이름으로 new 하겠다! 라는 것
    >> 근데 무조건적으로 new 를 하는 것은 아님
         1) 기존에 cb객체가 존재 했나?
         2-1) True : cb를 기존의 객체로 세팅
         2-2) False : cb를 new
                ex ) 
                       1) cb = request.getAttribute("cb");
                       2) if(cb==null){
                                 CalcBean cb = new CalcBean();
                           }
             >> D:\0607RYO\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\day36\org\apache\jsp
                  에 NewFile2-jsp.java 보면 비슷한 모양 존재 확인할 것

  >> 궁금한 점
        : request 선언이 안되어있는데 어떻게 서술된거죠?
   ☆ request 객체
        : 선언, 초기화, 객체화도 한 적이 없음. 
          하지만 계속 서술 가능
        : jsp => 서블릿으로 변환할 때, 자동으로 생성해주는 객체
        : jsp를 서비스 할 때, 인자로 만들어 줌
        : 서블릿을 직접 만들어봤을 때, 
          거기서도 request와 response는 자동 생성해주는 객체임
          == 'JSP 내장 객체' 라고 함
        ex ) request, response, pageContext, session, applicateion, config, out, page, ... 존재

 

※ JSP는 Servlet 파일을 생성한다는 사실!
※ JSP 내부에 JAVA 로직을 포함
<쓸 수 있는 방법>
※ JSP + 자바 빈즈(외부 JAVA 클래스 파일) // 가장 많이 볼 형태
※ HTML + Servlet
※ HTML + Servlet + JAVA 클래스 파일

 

>> HTML + 서블릿

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>계산기 - 3</title>
</head>
<body>

<!-- 로직을  -->
	<h1>계산기</h1>
	<hr>
	<form method='post' action="/day36/CalcServlet">
		<!-- 다시 돌아올 예정이기 때문에 action은 지움 -->
		<input type="text" name="num1"> <select name="op">
			<option>+</option>
			<option>-</option>
			<option>x</option>
			<option>/</option>
		</select> <input type="text" name="num2"> <input type="submit"
			value="계산 결과보기">
	</form>

</body>
</html>
package test;

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;

/**
 * Servlet implementation class CalcServlet
 */
@WebServlet("/CalcServlet")
public class CalcServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public CalcServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//response.getWriter().append("Served at: ").append(request.getContextPath());
		doPost(request,response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//doGet(request, response);
		int num1 = Integer.parseInt(request.getParameter("num1"));
		int num2 = Integer.parseInt(request.getParameter("num2"));
		String op = request.getParameter("op");
		int result=0;
		// 처음 보는 식은 꼭 자료형을 봐줄 것

		if (op.equals("+")) {
			result = num1 + num2;
		} else if (op.equals("-")) {
			result = num1 - num2;
		} else if (op.equals("x")) {
			result = num1 * num2;
		} else if (op.equals("/")) {
			result = num1 / num2;
		}

		PrintWriter out=response.getWriter();
		// 가독성 위해 대문자로 쓰는 것이 일반적
		out.println("<HTML>");
		out.println("<HEAD><TITLE>계산기 - 3 결과화면</TITLE></HEAD>");
		out.println("<BODY><H1>result</H1>");
		out.println("<HR>");
		out.println(num1+" "+op+" " +num2+" = "+result);
		out.println("</BODY>");
		out.println("</HTML>");
	}

	public int calc(int num1, int num2, String op) {
		int result=0;

		if (op.equals("+")) {
			result = num1 + num2;
		} else if (op.equals("-")) {
			result = num1 - num2;
		} else if (op.equals("x")) {
			result = num1 * num2;
		} else if (op.equals("/")) {
			result = num1 / num2;
		}

		return result;
	}
}

 

 

 

>> HTML + Servlet + JAVA 클래스 파일 예시

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>계산기 - 3</title>
</head>
<body>

<!-- 로직을  -->
	<h1>계산기</h1>
	<hr>
	<form method='post' action="/day36/CalcServlet2">
		<!-- 다시 돌아올 예정이기 때문에 action은 지움 -->
		<input type="text" name="num1"> <select name="op">
			<option>+</option>
			<option>-</option>
			<option>x</option>
			<option>/</option>
		</select> <input type="text" name="num2"> <input type="submit"
			value="계산 결과보기">
	</form>

</body>
</html>
package test;

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;

/**
 * Servlet implementation class CalcServlet2
 */
@WebServlet("/CalcServlet2")
public class CalcServlet2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CalcServlet2() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//response.getWriter().append("Served at: ").append(request.getContextPath());
		doPost(request,response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//doGet(request, response);
		int num1 = Integer.parseInt(request.getParameter("num1"));
		int num2 = Integer.parseInt(request.getParameter("num2"));
		String op = request.getParameter("op");
		Calc calc = new Calc(num1, num2, op);
		int result=calc.getResult();
		// 처음 보는 식은 꼭 자료형을 봐줄 것

		PrintWriter out=response.getWriter();
		// 가독성 위해 대문자로 쓰는 것이 일반적
		out.println("<HTML>");
		out.println("<HEAD><TITLE>계산기 - 4 결과화면</TITLE></HEAD>");
		out.println("<BODY><H1>RESULT PAGE</H1>");
		out.println("<HR>");
		out.println(num1+" "+op+" " +num2+" = "+result);
		out.println("</BODY>");
		out.println("</HTML>");
	}

}
package test;

public class Calc {
	int result=0;
	public Calc(int num1, int num2, String op) {
		if (op.equals("+")) {
			result = num1 + num2;
		} else if (op.equals("-")) {
			result = num1 - num2;
		} else if (op.equals("x")) {
			result = num1 * num2;
		} else if (op.equals("/")) {
			result = num1 / num2;
		}
	}
	
	public int getResult() {
		return result;
	}
}