JSP & Servlet

DAY 43 - Servlet (2024.09.02)

summ.n 2024. 9. 2. 17:48

오늘부터 서버에 들어간다.


* Apache - 응답만 한다.

: 아파치 소프트웨어 재단의 오픈소스 프로젝트이다.

: 웹서버로 불려진다

: 클라이언트 요청이 왔을 때만 응답하는 정적 웹페이지에 사용된다. (HTML, CSS, 이미지 등)

: 웹서버 - 80번 포트로 클라이언트 요청(POST, GET, DELETE)이 왔을 때만 응답


* Tomcat

: Servlet이나 JSP의 컨테이너

: WAS(Web Application Server) - 외워두기

: 컨테이너, 웹 컨테이너, 서블릿 컨테이너라고 부른다

: dynamic(동적)인 웹을 만들기 위한 웹 컨테이너

디테일하게 나누지 않아도 된다.

톰캣은 자바언어때문에 만들어졌다.

 

* 언어별 웹 서버 구성

(JAVA) JSP, Servlet -> 아파치 톰켓 -> WAS 서버 (WEB서버 내장)

(C, C++) PHP -> RWAPM -> WAS 서버 (WEB서버 내장)

(MFC, .NET) ASP, ASPX -> IIS ->WAS 서버 (WEB서버 내장)


http://127.0.0.1:8080은 외우기


서버는 건들이면 안 된다.
서블릿과 JSP가 있다.


CONTEXT
톰캣의 메인화면

http://localhost:8080/ROOT/hello.html - X ← default Context명 ROOT는 쓰시면 안된다.

url에서는 ROOT 쓰면 안된다.

 

http://localhost:8080/hello.html - O

ROOT가 아닌 다른 Context일 경우에는 반드시 URL에 써 주어야 한다


Servlet

: 웹에서 실행하는 프로그램

: html in JAVA

: public static void main(String[] args) 메소드가 없다

: 주기함수(Life Cycle)

: 반드시 public 이어야한다.

: new X

: 서버 안에 저장

: 반드시 어노테이션(@WebServlet) 또는 web.xml 등록해야 한다.


주기함수(Life Cycle)

init() : 맨 처음에 1번만 호출

     ↓

service() - doGet() : 클라이언트가 요청시마다 호출

               - doPost(

     ↓

destroy()

 

자바 파일은 처음 찾는게 메인메소드

서블릿은 가장 먼저 찾는게   void init( )

 

clas Test {

        public static void maind(String[ ] args)

우리가 부른 게 없다.

반드시 생성 - new class( )

 

Servlet - void init( ) / new x new 절대 안함. ------> Life Cycle

 

class HelloServlet { -- 자바파일      class HelloServlet extends HttpServlet{ -- 상속받아야 서블릿파일
}                                                        }

 

interface Servlet -- 인터페이스 안에는 추상메소드만 있다.

    ↑

class GenericServlet -- 추상메소드 전부 오버라이드 해준다.

     ↑

class HttpServlet -- 위의 자식으로 HttpServlet이 태어난 것

     ↑

HelloServlet -- HttpServlet 밑으로 HelloServlet이 태어남

 

private < default(private, protected, public도 아닌 거) < protected < public

class 앞에 아무것도 안 쓴 것이 default

 

1. 반드시 Tomcat에 저장 ( Tomcat은 Servlet이나 JSP의 컨테이너이므로)

HelloServlet.java --- 자바의 파일명은 클래스명과 동일하게

 

Tomcat 9.0

           webapps 

                     ROOT (default Context) 

                            *.html

                             *.jsp (자바파일은 이 곳에 들어올 수가 없다.) 

                              WEB-INF (자바파일은 이 곳에 만들어야한다.)

                                       web.wml( 환경설정 파일 )

                                        src (자바가 들어간다.)

                                              HelloServlet.java

                                         classes(컴파일 된 거)

                                               com

                                                     hello (패키지는 컴파일된 내용을위해서 잡고간다)

                                                            HelloServlet.class

                                            

 

package com.hello; -- 패키지 단위로 움직여야 한다. (패키지는 컴파일될 때만 만들어진다는 거)


public class HelloServlet extends HttpServlet{
       public void init(){} --- 톰캣이 가장 먼저 찾음

        public void doGet(요청, 응답){}

        public void doGet(HttpServletRequest request, HttpServletResponse response){}

 

        public void destroy(){}
}


저장하기 전에 폴더 만들기

 


저장하기


cmd 창에서 저 위치까지 들어가기

 


2. 패키지 컴파일

> javac HelloServlet.java -- 이렇게 하면 안 된다.

우리가 컴파일 패키지까지 걸어놨기 때문에 패키지 컴파일을 해야한다.

> javac  -d   ../classes HelloServlet.java

 

 

나는 src에 있는데 package com.hello; 여기로 가야한다.

 > javac  -d   ../classes HelloServlet.java


이건 약간 잘못됨

 error가 뜬다.

HelloServlet을 모르겠다. ---> import해야한다.

java.lang 안에서 찾으니까 모르겠다. 알려줘야한다.


package com.hello;

import javax.servlet.http.HttpServlet; ----위치 알려줘야한다.
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet{
public void init(){}

public void doGet(HttpServletRequest request, HttpServletResponse response){}

public void destroy(){}
}



3. servlet-api.jar ( 환경변수 )

이 위치에 없으면 다른데로 찾아가라 시켜야한다.

 

CLASSPATH

C:\Tomcat 9.0\lib\servlet-api.jar

여기에 있으니 찾아가라

 


CMD 껐다가 다시 켜기 -> set 입력


오류 없는거 확인가능


Dynamic Web Project : testServlet

check 꼭 하기 !!!!!


HelloServlet.java

package com.hello;

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

public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	public void init(ServletConfig config) {
	
	}

	public void destroy() {

	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	}

}

 확인해보려고 콘솔 창에 찍어보기

package com.hello;

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

public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	public void init(ServletConfig config) {
		System.out.println("init...");
	}

	public void destroy() {
		System.out.println("destroy...");
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet...");
	}

}

 

저장하면서 컴파일이 자동으로 끝내진다.

HelloServlet 얘를 new할 필요가 없다.

톰캣 켜져있어서 뜨는것 톰캣 끄고 다시 실행


톰캣 올라옴


URL

 

http://localhost:8080/Context명(Project명)/파일

http://localhost:8080/testServlet/com.hello.HelloServlet.class --- 404 에러


<?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_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>testServlet</display-name>
  
  <servlet>
  	<servlet-name>HelloServlet</servlet-name>
  	<servlet-class>com.hello.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>HelloServlet</servlet-name>
  	<url-pattern>/HelloServlet</url-pattern>
  </servlet-mapping>
  
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    <welcome-file>default.htm</welcome-file>
  </welcome-file-list>
</web-app>

 

 

web.xml 수정하면 톰캣을 껐다가 다시 켜야한다.

http://localhost:8080/testServlet/com.hello.HelloServlet.class --- 404 에러

http://localhost:8080/testServlet/HelloServlet -- 이렇게 쓰기로 약속한 것

 

F5 누를 때마다 찍힌다.


자바 코드를 수정하면  ---> 컴파일 동작이 일어남 ---> 하지만 톰캣은 모르므로 반드시 톰캣을 껐다 켜야한다. (이클립스가 알아서 해준다.) 톰캣이 다운될 때  destroy가 호출되고 다시 켜면 init이 호출된다

이런식으로 코드 내용 새로 뭐 적었다가 지우면 알아서 톰캣이 껐다 켜지면서 destroy가 일어난다.


 

위 아래가 같은 의미이다.


1. 콘솔창에 출력

System.out.println("<html>"); 

 

2. result.txt 파일 안에 출력

PrintWriter out = new PrintWriter(new FileWriter("result.txt"));

out.println("<html>");

 

3. 네트워크 통해서 상대방의 위치에 가서 출력

ObjectOutputStream out = new ObjectOutputStream(소켓.getOutputStream);

out.println("<html>");


package com.hello;

import java.io.IOException;
import java.io.PrintWriter;

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

public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	public void init(ServletConfig config) {
		System.out.println("init...");
	}

	public void destroy() {
		System.out.println("destroy...");
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet...");
		
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter(); //웹
		out.println("<html>"); // 이 코드가 웹으로 나가게 된다.
		out.println("<body>");
		out.println("Hello Servlet !!<br/>");
		out.println("안녕하세요 서블릿 !!<br/>");
		out.println("</body>");
		out.println("</html>");
	}

}


ln 빼버리면

package com.hello;

import java.io.IOException;
import java.io.PrintWriter;

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

public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	public void init(ServletConfig config) {
		System.out.println("init...");
	}

	public void destroy() {
		System.out.println("destroy...");
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet...");
		
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter(); //웹
		out.print("<html>"); // 이 코드가 웹으로 나가게 된다.
		out.print("<body>");
		out.print("Hello Servlet !!<br/>");
		out.print("안녕하세요 서블릿 !!<br/>");
		out.print("</body>");
		out.print("</html>");
	}

}

 

페이지 소스보기 하면 밑에처럼 다 달라붙어서 나온다.


어노테이션에 의해 코드를 매우 간결하게 적을 수 있다.

 

대신 둘 다 쓰면 error 발생한다. 하나만 써야한다.


하나만 적으면 다시 리로딩된다.


Dynamic Web Project: testServlet2

Folder: person

File: person.html

 

Package: com.person

Servlet: PersonServlet.java


PersonServlet.java

package com.person;

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

public class PersonServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	}

}


person.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
table {
	border-collapse: collapse;
}

th, td {
	padding: 5px;
}
</style>
</head>
<body>
	<form action="">
		<table border="1">
			<tr>
				<th width="70">이름</th>
				<td><input type="text" name="name" /></td>
			</tr>	
			<tr>
				<th width="70">나이</th>
				<td><input type="text" name="age" size="7" /></td>
			</tr>	
			
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="보내기" />
					<input type="reset" value="취소" />
				</td>
			</tr>
		</table>
	</form>
</body>
</html>


web.xml

<?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_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>testServlet2</display-name>
  <servlet>
  	<servlet-name>PersonServlet</servlet-name>
  	<servlet-class>com.person.PersonServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>PersonServlet</servlet-name>
  	<url-pattern>/person</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    <welcome-file>default.htm</welcome-file>
  </welcome-file-list>
</web-app>

person.html

submit 버튼 누르면 servlet으로 가게 적기

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
table {
	border-collapse: collapse;
}

th, td {
	padding: 5px;
}
</style>
</head>
<body>
	<form action="http://localhost:8080/testServlet2/person">
		<table border="1">
			<tr>
				<th width="70">이름</th>
				<td><input type="text" name="name" /></td>
			</tr>	
			<tr>
				<th width="70">나이</th>
				<td><input type="text" name="age" size="7" /></td>
			</tr>	
			
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="보내기" />
					<input type="reset" value="취소" />
				</td>
			</tr>
		</table>
	</form>
</body>
</html>

PersonServlet.java

넘긴 데이터 받아서 출력하기

package com.person;

import java.io.IOException;
import java.io.PrintWriter;

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

public class PersonServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//넘어온 데이터 받기
		String name = request.getParameter("name");
		int age = Integer.parseInt(request.getParameter("age"));
		
		//응답해서 화면에 출력
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<body>");
		out.println(name + "님의 나이는 " + age + "살이므로 ");
		if(age >= 19) 
			out.println("성인입니다.");
		else
			out.println("청소년입니다.");			
		out.println("</body>");
		out.println("</html>");
	}

}

 

톰캣을 한 번 껐다가 켜는게 좋음


out.println("<font color='red'>성인</font>입니다.");


뒤로가기 버튼 만들기

package com.person;

import java.io.IOException;
import java.io.PrintWriter;

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

public class PersonServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//넘어온 데이터 받기
		String name = request.getParameter("name");
		int age = Integer.parseInt(request.getParameter("age"));
		
		//응답해서 화면에 출력
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<body>");
		out.println(name + "님의 나이는 " + age + "살이므로 ");
		if(age >= 19) 
			out.println("<font color='red'>성인</font>입니다.");
		else
			out.println("청소년입니다.");	
		out.println("<br><br>");
		out.println("<input type='button' value='뒤로' onclick='history.go(-1)'>");
		out.println("</body>");
		out.println("</html>");
	}

}


		out.println("""
				<input type='button' value='뒤로' onclick='history.go(-1)'>
				""");