열심히 끝까지
디바이스 융합 자바(Java) day36 - 서버,클라이언트,HTTP명령(GET,POST),아파치 톰캣,JSP파일,서블릿(Servlet),자바 빈즈(JAVA BEANS),JSP&HTML&Servlet&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;
}
}