TIL #31 - Servlet, 톰캣 (2)
톰캣 서버는 아래와 같은 구조를 가지고 있다.
web.xml 은 서버실행 시 꼭 거쳐가는 아주 중요한 파일이고,
classes는 컴파일 된 .class 파일들이 모이는 곳이다.
src는 자바 파일들을 넣는 곳이다.
ROOT 파일은 기본 파일이지만 URL 을 입력할 때는 생략해도 되는 폴더명이다.
보통 URL을 입력할 때는 아래와 같은 형식이다.
http://localhost:8080/Context 명/ html 파일 명 |
context 명 이전 까지가 webapps 의 범위이므로 ROOT 파일의 경우 Context 명을 적을 자리에 ROOT 명을 적어주어야하지만 ROOT의 경우엔 디폴드 값이므로 적어주지 않는다.
아래의 예시는 이름과 나이를 입력받아 나이가 20살 이상이면 00님은 성인입니다 를 띄우고
19살 미만이면 00님은 미성년자입니다 라는 메시지를 띄운다.
정리하자면 아래와 같은 구조를 띄게 된다.
단, 아직 db 연결은 하지 않는다.
get 방식은 주소값에 데이터를 그대로 내보인다.
? 를 기준으로 앞이 주소, 뒤가 데이터이며 데이터와 데이터의 구분자는 & 이다.
먼저 web.xml 의 셋팅이다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>ResultServlet</servlet-name>
<servlet-class>com.calc.ResultServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ResultServlet</servlet-name>
<url-pattern>/ResultServlet</url-pattern>
</servlet-mapping>
</web-app>
맨 위의 코드는 줄바꿈을 해서도, 수정을 해서도 안되는 코드이다.
그 아래로 web-app 태그에 대한 코드는 의미를 이해할 필요없이 기본 web.xml 셋팅이므로 손대지 않는다.
우리가 직접 설정할 부분은 servlet부분이다.
servlet-name 은 원하는 이름대로 하되 servlet-class 는 시정한 servlet의 패키지 명을 써준다.
아래의 servlet-mapping 태그 내의 servlet-name도 마찬가지로 원하는 이름으로 해준다.
단, url-pattern은 꼭 슬래쉬를 붙여준다.
html도 역시 간단하게 보고 넘어간다.
server 측에 넘겨줄 값은 이름인 name 과 나이인 age 이다.
이 둘을 form 태그로 감싸 form 태그의 method 를 get으로 한뒤 action 속성에 servelt 주소값을 넣어줌으로써
데이터를 넘겨줄 수 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form method="get" action="http://localhost:8080/testServlet/ResultServlet">
<table border="1">
<tr>
<td width="70" align="center">X</td>
<td>
<input type="text" name="x" size="7">
</td>
</tr>
<tr>
<td width="70" align="center">Y</td>
<td>
<input type="text" name="y" size="7">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" name="submit" value="계산">
<input type="reset" name="cancel" value="취소">
</td>
<tr>
</table>
</form>
</body>
</html>
그러면 아래와 같은 형태의 웹페이지를 만들 수 있다.
서블릿의 주기함수는 init() > doGet() > destroy() 이므로 이에 따라 servlet 코드를 작성한다.
doGet을 하는 이유는 html 코드에서 데이터를 get 형식으로 넘겨주기 때문이다.
만약 post 형식으로 넘겨준다면 doPost() 메서드를 사용한다.
서블릿 클래스는 HttpServlet 을 상속받아야한다.
package com.param;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
public class ParamServlet extends HttpServlet {
public void init(){}
또한 패키지명은 web.xml 에서 지정해준 패키지명과 동일하게 해준다.
(본 프로젝트는 이클립스가 아닌 에디터플러스로 작성하고 있기 때문에 패키지명에 신경을 요한다..)
또 중요한 점이 클래스를 반드시 public 으로 지정해주어야한다는 것이다.
그렇지 않으면 500번 에러가 발생한다.
doGet() 메서드에서는 html 파일에서 넘겨받은 name, age 를 받아서 웹상에 뜨도록 해준다.
public 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("<head>");
out.println("<title>Servlet</title>");
out.println("<body>");
out.println(name + "님의 나이는 " +age+"살 이므로");
if(age >= 19) out.println("성인입니다.");
else out.println("청소년입니다");
out.println("<br>");
out.println("<br>");
out.println("<input type=button value=뒤로 onclick=javascript:location.href='http://localhost:8080/parameter.html'>");
out.println("<input type=button value=뒤로 onclick=javascript:history.go(-1)>");
out.println("</body>");
out.println("</head>");
out.println("</html>");
}
public void destroy(){
}
}
만약 html 에서 지정한 변수명(name, age)와 servlet 클래스에서의 변수명이 다르면 에러가 발생하므로 똑같이 지정해준다.