JSP/Servlet - 시작!

Apache Tomcat

웹서버는 클라이언트의 요청을 기다리고,
요청이 온다면 응답을 Data로(html, image 등)을 클라인언트에게 보낸다.
클라이언트는 응답받은 데이터를 Chrome 같은 웹브라우저에 출력한다.

하지만 클라이언트는 항상 똑같은 요청을 하지 않고 웹서버도 항상 똑같은 응답을 하지 않는다. 클라이언트별로 각각 다른 데이터를 보내면 서버는 각각 다른 데이터에 대한 다양한 Data로 응답을 한다. 다양한 Data를 만들어 응답하는 서버를 WAS라한다.

WASWeb Application Server의 약자로 Web Server기능과 Web Container 기능이 합쳐진 서버이다.

image1-1

웹서버: 클라이언트에 대한 응답 Data(html, js, image) 를 보내는 서버
WAS: 동적인 데이터를 만들어 클라이언트에 응답하는 서버

Apache Tomcat은 WAS역할을 하는 플러그인(서버 역할을 할수있게 해주는 소프트웨어)

출처: https://gap85.tistory.com/45

WAS 하나만으로 WEB 서버역할을 할수 도 있지만 성능향상을 위해 웹서버만큼은 따로 두는 경우도 있다.

Apache Tomcat설치, 이클립스 연동

Apache Tomcat 설치주소: https://tomcat.apache.org/download-80.cgi

8.5.39 ver 64bit Windows 버전으로 설치…

CATLINA_PATH 환경변수를 만들고
image1

아파치 톰캣 설치경로를 넣으면 된다.

PATH에가서 bin 위치정보를 다음과 같이 설정.
image2

웹서버 프로그래밍을 위해 오라클에서 Dynamic WebProject 생성
image3

Target runtime 코드를 실행시킬 웹서버를 설정, 다운받은 아파치 톰켓 플러그인 버전에 맞춰 설정할것.

image4

image5

image6

컴파일된 .class파일은 build/classes 에 저장된다.

image7

Generate web.xml deployment descripter(배포서술, 이하 DD) 체크

image8

Context rooturl상에서 루트디렉토리라 할 수 있다(client 입장에서 url, port 뒤에 나오는 문자열).
Content directory는 우리가 실제 html, jsp 파일을 만들때 사용되는 공간.

체크하면 Deployment Descriptor 라는 web.xml 파일이 생긴다.
DD안에서 웹서버 환경설정을 할 수 있다.

image9

원활한 웹 프로그래밍을 위해 모든 인코딩을 UTF-8로 통일.
workspace뿐 아니라 html, jsp, java 모두 UTF-8로 설정한다.

image10

이제 테스트를 위해 WebContent에서 html파일 생성

image11

image12

NewFile.html 만들고 간단히 html을 제작

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	홍길동 사이트
</body>
</html>

<!DOCTYPE html> HTML5로 작성되었음을 알림.
<meta charset="UTF-8"> 브라우저에게 문서가 UTF-8로 만들어져있기 때문에 UTF-8로 읽으라는 의미.

웹 프로그래밍에서 컴파일은 아래 사진과 같이 진행
image13

image14

위과정이 Tomcat v8.5 Server at localhost [started, Synchronized] 문구로 변경되며 서버가 실행중임을 알 수 있다.

항상 접속할수 없습니다, 혹은 거부 메세지가 발생하면 Server가 시작됬는지 확인해보자.

컴파일이 끝나면 Servers라는 폴더가 생기면서

image15

에러가 뜬다…

image16

에러뜨는 8080포트와 오라클 포트가 겹처서 그런다.

생긴 Servers폴더에서 server.xml안의 8080포트를 80으로 변경

image17

image18

이클립스에서 xml파일을 text로 열고싶다면 source선택…

참고: tomcat설치시 JAVA_HOMECATALINA_HOME설정을 해야한다.
(검색 필요…)

Servlet 개요

서블릿은 JSP 가 나오기 전에 만들어진 기술이다.
java 파일에서 각종 연산작업을 하고 그 결과를 out.printWrite() 메서드를 통해 html 태그와 함께 출력버퍼에 write한다.

이런 용도로 사용되는 객체를 서블릿 객체라 하는데
서블릿 객체를 만들기 위해 몇가지 규칙이 있다.

  1. 접근 지정자는 public
  2. HttpServlet 클래스를 상속해야함.
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;

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

public class NowServlet extends HttpServlet{

	public String getNow() {
		return LocalDateTime.now().toString();
	}

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 출력 스트림 객체 PrintWriter 사용, 출력버퍼에 html 텍스트를 작성
		PrintWriter out = response.getWriter();
		String name = "홍길동";
		int age = 20;
		String today = getNow();
		resp.setContentType("text/html; charset=UTF-8"); // html의 인코딩을 결정
		out.print("<!DOCTYPE html>");
		out.print("<html>");
		out.print("<head>");
		out.print("</head>");
		out.print("<body>");
		out.print("Hello Servlet");
		out.print("</body>");
		out.print("</html>");
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 아무처리하지 않은 그냥 200 OK 반환 
    }

}

상속받은 HttpServlet클래스의 doGet()doPost()메서드를 override해야한다.
클라이언트가 tomcat 에게 html 페이지를 요청하면 컴파일된 서블릿 객체의 doGet() 메서드를 호출하게 되고
클라이언트는 tomcat 으로 부터 출력버퍼에 저장되있던 html 페이지를 받게 된다.

이제 클라이언트가 서블릿 객체를 사용할 수 있도록 매핑작업을 해주어야 한다.

클라이언트가 url 을 통해서 위 doGet 메서드로 인도되도록 url 과 메서드를 매핑해야함

매핑 작업은 라는 배포 서술자(DD) 파일인 web.xml에서 할 수 있다.

tomcatweb.xml을 읽어서 서블릿 이름, 이름과 매칭되는 서블릿 객체, 이름과 url 패턴을 매핑하여 클라이언트에게 응답하기 때문에
작성한 서블릿객체와 서블릿이 사용할 이름을 매핑해주어야 한다.

배포서술자

<!-- WebContent\WEB-INF\web.xml -->
<servlet>
  <servlet-name>now</servlet-name>
  <servlet-class>days01.NowServlet</servlet-class> 
  <!-- 패키지명까지 써야한다. -->
</servlet>

<servlet-mapping>
  <servlet-name>now</servlet-name>
  <url-pattern>/sample</url-pattern>
  <url-pattern>/now</url-pattern>
  <url-pattern>/days01/now</url-pattern>
</servlet-mapping>

서블릿 객체 매핑은 간단하다, 서블릿 객체가 사용할 이름을 <servlet-name>태그를 통해 지정하고
해당 서블릿 객체를 <servlet-class>태그를 통해 지정한다.
보다싶이 하나의 서블릿 객체에 대해 여러가지 url 패턴을 사용 가능하다.

http://127.0.0.1/jspPro/sample
http://127.0.0.1/jspPro/now
http://127.0.0.1/jspPro/days01/now

위 url 패턴을 요청한 클라이언트는 모두 NowServlet 이라는 서블릿 객체가 생성한 html 페이지를 응답받는다.

서버가 컴파일되어 실행, 서블릿 객체가 생성되고 클라이언트가 요청한 페이지를 응답받기까지 과정은 다음과 같다.

  1. 자바 코드를 컴파일 해서 클레스 파일을 생성한다.
  2. /WEB-INF/classes 폴더에 클래스 파일을 저장한다.
  3. tomcat 등의 컨테이너를 실행한다.(web.xml확인)
  4. tomcatweb.xml 파일에 서블릿 객체와 url 매핑 확인
  5. Clienttomcat 에게 HTTP Request 요청 Http Reponse 수신

톰켓 컨테이너

웹 컨테이너 라고도 부르는 이것은 객체가 생성되서 들어가 있다.

과거 컨테이너가 없을땐 일일이 배포서술자(web.xml)에 서블릿 객체를 등록하고 이름을 지정하고 매핑해야 했지만
컨테이너를 사용하면 배포서술자에 지정할 필요 없다.
어노테이션을 등록해놓으면 컨테이너가 알아서 서블릿 객체를 찾아 doGet()을 호출하고 응답해주기 때문

웹 컨테이너를 사용하는 서블릿 객체를 만드는 방법은 다음과 같다.

Java Resources/src -> new 를 선택, 서블릿 파일 생성, 클래스명을 HelloServlet으로 설정
서블릿 객체 이름을 지정하고 url 패턴을 추가, 변경할 수 있다.

image01
image02

컨테이너를 사용한 서블릿 객체가 만들어졌다!

package days01;

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 HelloServlet
 */
@WebServlet({ "/hello", "/hi" })
public class HelloServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

    public HelloServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    response.getWriter()
		.append("<html>")
		.append("<head>")
		.append("<title>")
		.append("어노테이션을 사용해서 서블릿 자동 등록")
		.append("</title>")
		.append("</html>")
		.append("<body>")
		.append("Served at: ")
		.append(request.getContextPath()) //context root를 뜻함, 최상위 디렉토리명 jspPro
		.append("<h2>Hello First Servlet<h2>")
		.append("</body>")
		.append("</html>");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response); // post 도 get 과 동일하게 동작하도록 설정  
	}

}

response.getWriter()을 사용해 간단한 html 페이지를 작성하였다.

@WebServlet({ "/hello", "/hi" }) 어노테이션으로 url 매핑 된것을 확인

웹컨테이너와 어노테이션을 사용하면 각 web.xml 설정이 필요 없다. 하지만 url 패턴이 중복되어 실수할 확률이 커짐
또한 web.xml 사용 url 매핑 수정시 톰켓이 url 매핑에 관여하여 바로 서블릿 객체로 Request 를 인도해 톰켓 재시작만 하면 되지만
웹컨테이너 사용시 웹컨테이너가 url 매핑에 관여하며 재컴파일을 해야 수정사항이 처리된다.
한가지만 사용하는 것 보단 적절히 섞어 쓰는것을 권장한다.

JSP 개요

서블릿과 마찬가지로 동적인 웹 처리를 위해 사용하는 웹 기술이다.
서블릿만으로 클라이언트에게 동적인 HTML 을 제공하는 것은 수많은 노력이 필요하기에 JSP 를 사용해 HTML 코드는 별도의 파일에 작성한다.

JSP, Servlet 두개의 웹 기술이 어떻게 동작하는지 알아보자.

JSP개요

JSP(Java Server Page)의 약자로 Java를 사용하는 웹 기술이다.

일단 톰캣의 버전에 따라 사용되는 JSP/Servlet 버전도 달라진다.

현재 사용중인 톰캣 버전은 Tomcat v8.5 Server, JSP버전은 2.4이다.(eclipse에서 자동 설정됨)

jsp파일의 기본 형식은 다음과 같다.

<%@ page trimDirectiveWhitespaces="true" language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.Date"%>
<%@ page import="java.time.LocalDateTime"%>

<% Date now = new Date(); %>
<%!	String name = "홍길동"; %>

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<meta charset="UTF-8">
<title>JSP / Servelet Class - kouzie(2019. 4. 23.-오후 4:38:14)</title>
<script>
   $(document).ready(function (){
   
   });
</script>
</head>
<body>
	날짜: <input type="text" value="<%=now.toLocaleString() %>"/>
	이름: <input type="text" value="<%=name %>"/>
</body>
</html>

익숙한 html태그들과 <% ... %>, <%@ ... %>, <%! ... %>, <%= ... %>와 같은 낯선 태그들이 있다.

위의 JSP문서는 모두 아래 항목으로 구분된다.

  1. 지시자 - 디렉티브(Directive)
  2. 스크립트 - 스크립트릿(Scriptlet), 표현식(Expression), 선언부(Declaration)
  3. 표현 언어(Expresstion Language)
  4. 기본 객체(Implicit Object)
  5. 정적인 데이터
  6. 표준 액션 태그(Action Tag)
  7. 커스텀 태그(Custom Tag)와 표준태그 라이브러리(JSTL)

1. 지시자 - 디렉티브(Directive)

<%@ ... %> 요렇게 생긴 녀석이 JSP의 디렉티브이다.

디렉티브는 page, taglib, include 3가지가 있고 page에 대해서만 간단히 알아보자.

page디렉티브는 JSP페이지의 각종 설정정보를 지정한다,
문서타입(HTML, JSON, XML, MIME등), 출력버퍼 크기, import할 자바 클래스, JSP 인코딩 등…

다른 디렉티브 타입과 page디렉티브의 다른 여러가지 속성을 후에 알아보자.

contentType: contentType은 해당 문서가 어떤 타입인지를 표현하는데 문자 인코딩이 기본 ISO-8859-1이기 때문에 charset속성을 다음과 같이 필수 정의해야 한다.
contentType="text/html; charset=UTF-8"

디렉티브에서 encoding 설정 속성이 두가지다. contentTypecharset, pageEncoding속성.

우리가 작성한 jsp파일의 encoding을 tomcat에게 알려줘야 하는데 이 때 사용하는 속성이 pageEncoding 서버에서 클라이언트에게 응답하는 html파일 인코딩을 charset에서 설정한다.

eclipse설정에선 UTF-8로 jsp파일 encoding을 지정했는데 pageEncoding속성이 다른 encoding이라면 깨진다.

따라서 pageEncoding 또한 utf-8로 설정.

지시자의 종류는 3가지로 나뉘는데 2, 3번째 지시자는 후에 알아가도록 하자.

  1. 페이지 지시자
  2. 태그 라이브러리 지시자
  3. include지시자

2. 스크립트

JSP에서 스크립트는 자바 코딩임을 알리는 태그로 3가지로 나뉜다.

스크립트릿 표현식 선언부
<% ... %> <%= ... %> <%! ... %>

스크립트릿은 JSP페이지에서 자바코드를 실행할 때 사용하는 코드블록이다.

표현식은 어떤값을 출력결과에 포함시키고자 할때 사용된다.

이름: <input type="text" value="<%=name %>"/> 이런식으로 사용됨 스크립트릿, 선언부에서 정의한 변수name이 출력된다.

선언부는 JSP페이지에서 메서드를 작성할때 사용된다.

<html>
...
<%!
  public int multiply(int a, int b)
  {
    int c = a*b;
    return c
  }
%>
</html>
...

3. 표현 언어(EL: Expresstion Language)

form 태그에서 namen1n2인 숫자를 받아 더한 값을 출력하려면 다음과 같이 코딩해야 한다.

<body>
<% 
	//스크립트릿
	int n1 = Integer.parseInt(request.getParameter("n1"));
	int n2 = Integer.parseInt(request.getParameter("n2"));
%>
n1 + n2 = <%= n1+n2 %>
</body>

request.getParameter메서드를 통해 문자열로 받아와 Integer클래스로 형변환 까지 해주어야 하는데….
너무 복잡하다.

EL을 사용하면 간단하게 해결 가능하다.

<body>
n1 + n2 = ${param.n1 + param.n2}
</body>

4. 기본 객체(Implicit Object)

JSP페이지에 기본적으로 내장되어 있는 객체를 뜻한다.

내장 객체 리턴 타입(Return Type) 설명
request javax.servlet.http.HttpServletRequest 웹 브라우저의 요청 정보를 저장하고 있는 객체
response javax.servlet.http.HttpServletResponse 웹 브라우저의 요청에 대한 응답 정보를 저장하고 있는 객체
out javax.servlet.jsp.jsp.jspWriter JSP 페이지에 출력할 내용을 가지고 있는 출력 스트림 객체이다.
session javax.servlet.http.HttpSession 하나의 웹 브라우저의 정보를 유지하기 위한 세션 정보를 저장하고 있는 객체
application javax.servlet.ServletContext 웹 어플리케이션 Context의 정보를 저장하고 있는 객체
pageContext javax.servlet.jsp.PageContext JSP 페이지에 대한 정보를 저장하고 있는 객체
page java.lang.Object JSP 페이지를 구현한  자바 클래스 객체
config javax.servlet.ServletConfig JSP 페이지에 대한 설정 정보를 저장하고 있는 객체
exception java.lang.Throwable JSP 페이지서 예외가 발생한 경우에 사용되는 객체

위에서 get방식으로 받은 페이지의 를 request 기본객체를 사용하여 변수를 전달받았다.
request.getParameter("n1")

위에서 사용한 구성요소 이외에도 아래 3개정도의 구성요소가 더 있다.

  1. 정적인 데이터
  2. 표준 액션 태그(Action Tag)
  3. 커스텀 태그(Custom Tag)와 표준태그 라이브러리(JSTL)

카테고리:

업데이트: