본문 바로가기

수업 정리

48일차 수업정리(HttpServlet, JSP)

**Java Web Programming을 하기 위한 환경설정

1. JDK 툴 설치

    => Java EE 버전을 설치해야 java Web programming을 할 수 있음

        - 웹 컨테이너를 이용하거나 Spring같은 프레임워크 사용시 Java SE버전으로도 가능

    => Oracle 웹 사이트 나 Open JDK웹 사이트에서 JDK SE버전을 다운로드 받아서 설치

    => 환경 변수 설정 : MAC은 할 필요가 없음(Window나 Linux에서만 수행)

  1) JAVA_HOME : 원래 없는 항목으로 경로를 줄여쓰기 위해 자바가 설치된 경로를 설정. 환경변수 생성하여 설정

  2) CLASSPATH : 원래 없는 항목으로 JAVA가 실행될 때 클래스를 찾는 순서 설정(자바 설치경로의 lib\tools.jar로 설정)

    - .은 현재 디렉토리, tools.jar파일은 자바의 기본 클래스를 가지고 있는 파일

    - IDE를 사용하여 개발하는 경우 IDE가 설정하여 실행하므로 대부분 생략

  3) path : 원래 존재하는 항목으로 콘솔에 명ㄹ여어 입력시 명령어를 찾는 위치를 설정(자바 디렉토리의 bin디렉토리)

    - Linux : 파일을 직접 열어서 설정

  4) JRE_HOME : 원래 없는 항목으로 Java로 만들어진 프로그램이 사용할 JRE의 경로를 설정하는 항목

                     (Java가 여러버전이 설치되어 있는 경우 설정)

    => Mac은 기본 프로그램이 Java, Python으로 만들어져있어 별도 설정없이 설치만 하면 됨

 

2. Web Container 설치

    => Javascript가 아닌 프로그래밍 언어로 개발한 내용을 HTML로 변환하여 Web Server에게 전달하는 프로그램

        - 다른 말로 Web Application Server 라고도 함

    => Java Web Container는 여러종류가 있는데 우리는 Apache Tomcat을 사용

    => Windows는 설치버전과 압축버전이 있는데, 압축버전은 압축해제만 하면됨

        - Mac, LInux에서는 압축버전만 존재

    => 서버 시작시 startup.bat(startup.sh - Mac)파일을 실행, 종료시 shutdown.bat(shutdown.sh - Mac)을 실행

    => 설정하지 않고 사용시 포트 충돌로 인해 실행이 안되는 경우가 있음

        - config 디렉토리의 server.xml 파일을 열어서

         <Connection port="8080" redirect="8443".../> 부분의 8080을 다른 포트 번호로 변경

         (오라클이 설치된 경우 오라클 포트가 8080라서 발생하는 현상)

        - <Server port="-1" shutdown="SHUTDOWN"/> 이 태그의 포트번호가 -1로 된 경우 8005형태로 수정

 

3. IDE 설치

  1) Eclipse - Java EE 버전으로 설치

    => 전자정부 프레임 워크, STS, AnyFramework등은 전부 Eclipse에 플러그 인만 설정한 IDE

  2) Intelli J

    => community 버전은 Web Programming을 못함

  3) Windows 용을 설치한 경우 인코딩을 전부 UTF-8로 변경

 

**Web Project 생성

1. Dynamic Web Project 생성

2. 프로젝트 이름 설정

3. 컴파일 되어야 하는 파일(java)을 작성하는 위치와 컴파일되어 클래스가 만들어지면 위치하게되는 디렉토리 설정

    (WebContent/WEB-INF/classes)

4. 루트 디렉토리 설정(WebContent)

    => 컴파일 할 필요가 없는 파일들을 생성하는 디렉토리로 IDE에 따라 webapp디렉토리로 만들어 지기도 함

    => web.xml은 프로젝트 설정파일로 WebContent/WEB-INF 디렉토리에 생성됨

    => 없으면 tomcat 설치 디렉토리의 config 디렉토리에서 복사해와도 됨

 

**HttpServlet 과 JSP

1. HttpServlet

    => URL을 이용하여 실행할 수 있는 JavaEE의 클래스

        - Java SE를 설치한 경우, Tomcat 디렉토리에서 Servlet-api.jar 파일을 프로젝트의 WEB-INF/lib 디렉토리에 복사해

         야 사용 가능

    => 이 클래스를 상속받는 클래스를 만들어 매핑되는 URL요청이 처음 들어왔을 때 웹 컨테이너가 인스턴스를 생성하

         고 하나의 인스턴스를 이용하여 모든 요청을 스레드로 처리

    => 이 클래스는 웹 브라우저에 HTML 출력할 수 있는 데 자바 코드 안에 작성해야 하므로 작성이 어려움

    => 서블릿은 주로 Controller의 역할(요청이 오면 필요한 로직을 호출)만 수행하는 경우가 많음

    => 이 클래스의 내용 수정시 컨테이너를 다시 실행시켜야 변경 내용이 적용

 

2. JSP(Java Server Pages)

    => HttpServlet을 이용해서 HTML을 출력하는 것이 너무 번거로워서 만든 Spect

    => HTML 페이지 안에 Java코드를 작성 할 수 있ㅋ도록 만든것

    => JSP 페이지에 해당하는 URL 호출시 JSP -> HttpServlet 클래스의 코드로 변환, 인스턴스를 만들어 요청을 처리

    => JSP 와 Servlet은 쌍으로 발전

 

3. 차이점

    => 서블릿 : 코드를 작성후 실행시 class 형태로 존재, 첫번째 요청시 인스턴스(1개)를 만들고, 모든 요청을 처리

    => JSP : 코드 작성후 실행시 코드상태로 존재, 요청시 서블릿 클래스로 변환, 인스턴스를 만들어 요청처리 후 삭제됨

 

    => 서블릿 : 수정시 컴파일을 다시 해야하기 때문에 애플리케이션은 다시 배포해야 함

    => JSP : 수정한 후 요청만 다시하면 됨

 

4. 애플리케이션을 재배포하여 다시 실행하는 상황은 가급적 만들지 않는 것이 좋음

 

**프로젝트 구조

1. Java Resources/src

    => 컴파일을 수행하는 디렉토리

    => .java 파일은 반드시 이 디렉토리 안에 만들어 져야 함

    => .java 파일은 컴파일을 하여 WebContent/WEB-INF/classes 디렉토리에 배치

         - 컴파일을 할 필요가 없는 파일은 Webcontent 디렉토리에 배치

    => 이 디렉토리에 만든 파일이 제대로 동작하지 않을 경우 [Project] - [clean]이라는 메뉴를 실행하여 기존의 클래스

        들을 전부 삭제하고 새로 컴파일하여 클래스를 만들어 달라고 할 수 있음

        - 이 경우 클래스를 지우고 다시 작성하기도 함

        - 이클립스는 현재 작성중인 소스 코드를 컴파일하는 특성이 있어 클래스로 만들어지지 않은 자바코드 재작성시

         실행되는 경우가 있음

2. WebContent

    => 루트 디렉토리

    =>이 안에 있는 내용만 애플리케이션이 사용 할 수 있음

    => WebContent/META-INF : web.xml을 제외한 설정 파일들을 저장하는 디렉토리

        - context.xml 파일을 여기에 배치하고, 최근에는 이 디렉토리는 거의 사용하지 않음

    => WebContent/WEB-INF : web.xml파일이 존재해야 하는 디렉토리

        - web.xml 파일은 반드시 이 디렉토리에 위치해야 함

    => WebContent/WEB-INF/lib : 외부 라이브러리가 위치해야 하는 디렉토리

    => WebContent/WEB-INF/classes : 클래스가 위치해야 하는 디렉토리

 

**JSP

1. JSP 문서의 기본구조

    => HTML 안에 JSP 문법의 코드를 삽입하는 방식

    => JSP 파일은 JSP 문법의 코드를 먼저 컴파일하여 실행하고 그 결과를 HTML에 추가하는 방식으로 동작

    => JSP 문법의 코드가 위치에 상관없이 먼저 수행

 

2. 실행 원리

    => 사용자의 요청 -> JSP페이지를 찾음 -> 서블릿 코드로 변환 -> 서블릿 인스턴스 생성 -> 필요 메소드를 호출하여

        요청을 처리 -> 결과를 HTML코드에 추가하여 출력

    => 매 요청마다 클래스를 만들고 인스턴스를 만들어서 처리

    => 내용이 변경되면 바로 적용이 됨

 

3. 구성요소

  1) Directive

  2) Script : Scriptlet, Expression, Declaration

  3) Implicit Object(내장객체)

  4) Expression Language(표현식)

  5) Action Tag - JSP 문법의 태그

  6) Custom Tag - 사용자 정의 태그로 JSTL이 대표적

 

4. Directive

    => JSP 페이지에 대한 설정을 위한 것

    => <% @ 디렉티브이름 속성="값" 속성="값" ... %>

  1) 디렉티브 명

    => page : 페이지에 대한 설정

    => taglib : 사용자 정의 태그 라이블러리를 설정

    => include : 다른 문서를 포함

  2) page 디렉티브 속성

    => import : 패키지 이름을 생략하기 위해서 사용

    => session : 세션 사용 여부를 설정하는 것으로 기본값은 true

    => errorPage : 에러가 발생했을 때 보여질 페이지 설정

    => isErrorPage : 에러 페이지 여부를 설정하는 것으로 이 설정이 true이면 exception 객체를 사용할 수 있음

    => pageEncoding : 문자 인코딩 설정으로 이 설정이 없거나 utf-8이 아니면 경고 발생

    => trimDirectiveWhitespaces: 공백 제거

 

5. Script

  1) Scriptlet : jsp 파일에서 자바코드를 쓰기 위한 방법

    - <% 자바코드 %>

  2) Expression : jsp 파일에서 자바의 데이터를 출력하기 위한 방법

    - <%= 자바데이터 %>

 

6. 랜덤한 1~45의 숫자 6개를 생성하여 출력

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<!-- 빈 줄을 없애주는 옵션 -->
<%@ page trimDirectiveWhitespaces="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>랜덤한 숫자 생성</title>
</head>
<body>
	<%
	//랜덤 객체 생성
	Random random = new Random();
	//1~45 사이의 6개의 랜덤한 숫자를 정렬해서 저장하기
	//숫자는 중복되면 안됨
	
	//데이터를 저장할 자료구조 생성
	TreeSet<Integer> lotto = new TreeSet<>();
	//데이터의 개수가 6개가 될 때 까지
	while(lotto.size() < 6){
		//set은 중복 데이터를 저장하지 않으므로 6개가 될 때 까지 수행
		//nextInt는 숫자로 나눈 나머지를 랜덤하게 리턴
		lotto.add(random.nextInt(45) + 1);
	}
	%>
	
	<!-- java 데이터 출력하기  -->
	<h3><%=lotto %></h3>
</body>
</html>

7. VO(Variable Object - Data Transfer Object - Domain Class : 여러개의 데이터를 묶어 하나의 데이터로 표현하기 위한 클래스 - 관계형 데이터베이스의 테이블과 유사한 개념) 클래스의 list를 만들어서 제어문을 이용하여 출력하기

public class DataStructure {
	//프로퍼티 선언
	private String name;
	private String description;
	
	public DataStructure() {
		super();
	}

	public DataStructure(String name, String description) {
		super();
		this.name = name;
		this.description = description;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}

	//디버깅을 위한 메소드
	@Override
	public String toString() {
		return "DataStructure [name=" + name + ", description=" + description + "]";
	}

}

2) jsp 파일을 생성하여 위 클래스의 List를 생성하고 출력하기

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="domain.*, java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>자료구조</title>
</head>
<body>
	<%
		List<DataStructure> list = new ArrayList<>();
		list.add(new DataStructure("list", "데이터의 연속적인 모임"));

		DataStructure set = new DataStructure("set", "데이터를 순서와 상관없이 중복없이 저장");
		list.add(set);

		DataStructure map = new DataStructure();
		map.setName("map");
		map.setDescription("key와 value 쌍으로 저장하는 자료구조");
		list.add(map);
		
		for(DataStructure ds : list){
			%>
			<h3><%=ds %></h3>
			<%
		}
	%>
</body>
</html>

  3) 새로운 클래스를 생성했기 때문에 서버를 중지시키고 다시 실행시켜야 함

 

8. 선언

  1) <%  선언  %>

    => 위와 같이 선언한 내용은 인스턴스가 각각 별도로 소유

    => jsp 파일을 2번 요청시 2번 선언

  2) <%!  선언  %>

    => 위와 같이 선언한 내용은 클래스가 소유 : static

    => jsp 파일을 2번 요청해도 1번 선언

  3) jsp 파일에 quick sort를 위한 메소드를 생성하고 사용

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>quick sort</title>
<style>
	span{
		border:1px solid blue;
	}
</style>
</head>
<body>
<%!
	//quick sort
	//배열에서 첫번째 데이터를 기준데이터로 선정
	//첫번째 데이터와 나머지 모든 데이터를 비교하여 작으면 왼쪽 크면 오른쪽으로 배치
	//기준데이터의 왼쪽, 오른쪽 부분 배열을 재귀적으로 다시 작업을 수행
	//데이터의 개수가 1개이면 종료(1개 = 시작위치보다 종료위치가 크지 않은 경우)
	//시작 위치와 종료위치, 배열을 매개변수로 받아서 quick sort 수행해주는 메소드	
	public void quicksort(int left, int right, int[] data) {
		//현재 배열의 상태 출력
		for (int i : data) {
			System.out.print(i + "\t");
		}
		System.out.println();
		
		//기준이 되는 위치를 설정
		int pivot = left;
		
		//기준데이터가 이동해야 할 위치를 저장한 변수
		//pivot 위치의 데이터보다 작은 데이터를 만나면 1증가
		int j = pivot;
		//비교할 위치를 저장 할 변수 - 반복문에서 사용
		int i = left + 1;
		
		//데이터가 2개 이상이면
		if(left < right){
			//기준위치 다음부터 끝까지 기준위치의 데이터와 비교
			for(; i <= right; i+=1){
				//기준위치의 데이터가 더 크다면
				if(data[i] < data[pivot]){
					//기준 데이터가 위치해야할 지점을 1칸 이동
					j+=1;
					//i번째와 j번째 데이터를 교환
					int temp = data[j];
					data[j] = data[i];
					data[i] = temp;
				}
			}
			//기준데이터를 자신의 자리로 이동
			int temp = data[left];
			data[left] = data[j];
			data[j] = temp;
			
			//기준의 위치를 수정
			pivot = j;
			
			//왼쪽 부분과 오른쪽 부분을 재귀적으로 수행
			quicksort(left, pivot-1, data);
			quicksort(pivot+1, right, data);
		}
	}
%>
<% 
	//정렬할 데이터 만들기
	int[] ar = {30, 28, 29, 38, 51, 7, 21, 5, 19};
%>

<h2>정렬 전 데이터</h2>
<%	for(int temp : ar){ %>
<span><%=temp %></span>
<%} %>

<h2>정렬 데이터</h2>
<%	quicksort(0, ar.length-1, ar); %>
<%	for(int temp : ar){ %>
<span><%=temp %></span>
<%} %>

</body>
</html>

9. Commit( <%-- 주석 --%> )

    => html, java주석이 존재하기 때문에 java 코드 작성시는 java주석(//, /* */), html사용시 html주석(<!-- -->) 사용

 

**내장 객체

    => 별도로 생성하지 않고 jsp 파일에 포함되어 있는 객체

    => 이 객체들은 실제로는 거의 Servlet에서 사용하고 jsp에서는 잘 사용하지 않음

    => jsp에서는 9개 모두 제공되지만 Servlet에서는 request와 response만 제공되고 직접 생성하여 사용해야 함

1. 종류

  1) HttpServletRequest request : 클라이언트의 요청 정보를 저장한 객체

  2) HttpServletResponse response : 클라이언트에게 전송하는 응답정보를 저장한 객체

  3) JspWriter out : 출력객체 - HTML 출력

  4) ServletContext application : 웹 애플리케이션 객체 - 1개만 생성

  5) ServletConfig config : 파일의 구성정보를 저장한 객체

  6) PageContext pagecontext : jsp 페이지에 해당하는 객체

  7) HttpSession session : 세션 - 클라이언트 브라우저 1개에 해당하는 객체(접속 클라이언트가 10명이면 세션도 10개)

  8) Object page : jsp 페이지에 의해 생성된 서블릿 객체

  9) Throwable exception : 예외 객체