컴파일 방식 : 속도가 빠르다. 하지만 로직이 변경되면 서비스하고 있던 것을 중지하고 다시 올려야하는 단점이 있다.
인터프리터 : 스크립트로 된 파일로, 스크립트가 읽어서 한줄씩 실행하므로 중간에 변경해도 서비스를 중단할 필요가 없다. 하지만 속도가 느리다.
~servlet 이름의 유래~
: application -> applet -> servlet
(혹은 server application이 조각났다)
server application : 동적으로 문서를 만들기 위한 코드
WAS : web application server
아파치 : 웹서버(웹문서를 제공해주는 서비스)
서블릿 컨테이너(톰캣) : 비지니스 로직을 갖는 자바 객체를 담아 실행시킨다. 서버에서 동작하는 프로그램을 담는 역할이다.
servlet 인터페이스를 상속받아 인터페이스가 정의한 메서드를 구현한다.
XML이라는 dd파일을 읽어 등록된 클래스를 찾아 서블릿 객체로 만든다.
그리고 컨테이너가 로딩하여 실행한다.
service()는 반드시 구현해야 한다.
But!
interface는 특성상 모두 구현해줘야 한다. 구현하지 않은 메서드가 하나라도 있으면 추상클래스이므로 객체화 할 수 없다.
-->쓰지도 않을 메서드를 항상 구현해야하는 것이 번거롭기 때문에
서블릿을 구현하는 방법에 추상클래스를 상속받는 방법이 나왔다.
GenericServlet
: service()만 추상메서드로 남겨놓고 나머지 메서드는 default처리를 해놓았다. 그러므로 상속받았을 때 default로 구현된 상태이기 때문에 굳이 손대지 않아도 된다.
package lesson03.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class CalculatorServlet extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
int a = Integer.parseInt(req.getParameter("a"));
int b = Integer.parseInt(req.getParameter("b"));
resp.setContentType("text/plain"); // 브라우저한테 평문 텍스트보낸다고 알려줌 (html이 아님)
//내가 앞으로 출력하는 애들은 UTF-8로 보내는거야
// "내가 character를 이렇게 보낼테니까"
resp.setCharacterEncoding("UTF-8");
//니가 한글 해석할 수 있는 여러 코드 테이블 중에서 utf를 읽어야해 라고 심어준다.
//브라우저가 보고 해석할 수 있도록 심어줘야 한다.
//(사용자가 받았는데 어떻게 해석할 것인지 정보를 보내야 한다)
// "넌 이걸로 읽어라 "
// resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("a=" + a + "," + "b=" + b + "의 계산결과 ");
out.println("a+b=" + (a+b));
out.println("a-b=" + (a-b));
out.println("a*b=" + (a*b));
out.println("a/b=" + (a/b));
out.println("a%b=" + (a%b));
}
}
: 소스를 수정하지 않아도 xml파일에서만 변경해 주면 가능하다.
매핑의 주소가 들어오면 name으로 찾는다.
dd파일 생성
web.xml
url-pattern
: 사용자에게 제공되는 서블릿 이름 (사용자는 직접 Calculator를 요청하는게 아니라 /calc를 통하여 요청)
톰캣은 요청이 왔을때 요청에 해당되는 서블릿 클래스를 찾아서 실행한다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>_05_GenericServlet</display-name>
<!-- 서블릿 선언 -->
<servlet>
<servlet-name>Calculator</servlet-name>
<servlet-class>lesson03.servlets.CalculatorServlet</servlet-class>
</servlet>
<!-- 서블릿 매핑 -->
<servlet-mapping>
<servlet-name>Calculator</servlet-name>
<url-pattern>/calc</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
출력 결과 (get 방식 이용)
프로젝트를 복사하여 수정할 때는 context root도 바꿔줘야 한다.
: annotation을 이용하면 소스파일을 열어 수정해줘야 한다. 그래서 잘 안바뀔 것 같은 경우에 쓴다.
package lesson03.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
@WebServlet("/calc")
public class CalculatorServlet extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
int a = Integer.parseInt(req.getParameter("a"));
int b = Integer.parseInt(req.getParameter("b"));
resp.setContentType("text/plain"); // 브라우저한테 평문 텍스트보낸다고 알려줌 (html이 아님)
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter();
out.println("a=" + a + "," + "b=" + b + "의 계산결과 ");
out.println("a+b=" + (a+b));
out.println("a-b=" + (a-b));
out.println("a*b=" + (a*b));
out.println("a/b=" + (a/b));
out.println("a%b=" + (a%b));
}
}
get방식에서 한글을 받을 경우를 대비하여 인코딩 utf-8 추가하였다.