Web Architecture
package lesson01.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;
@SuppressWarnings("serial")
@WebServlet("/calc")
public class CalculatorServlet extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
String op = req.getParameter("op");
int v1 = Integer.parseInt(req.getParameter("v1"));
int v2 = Integer.parseInt(req.getParameter("v2"));
int result = 0;
res.setContentType("text/html;charset=UTF-8");
PrintWriter out = res.getWriter();
switch(op) {
case "+": result = v1+v2; break;
case "-": result = v1-v2; break;
case "*": result = v1*v2; break;
case "/":
if(v2==0) {
out.println("0으로 나눌 수 없습니다");
return;
}
result = v1/v2;
break;
}
out.println(v1+" " + op + " " + v2 + " = " + result);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>계산기</title>
</head>
<!--
action : "서버의 주소"(대응되는 App)
method : get/post 전송 방식
name : 서버에 전송하는 변수명
value : 변수에 입력된 값
-->
<body>
<h1>계산기</h1>
<form action="calc" method="post">
<input type="text" name="v1" style="width:50px;">
<select name="op">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text" name="v2" style="width:50px;">
<input type="submit" value="=">
</form>
</body>
</html>
HTTP
package lesson02.get;
public interface Operator {
public String getName();
public double execute(double a, double b) throws Exception;
}
package lesson02.get;
public class PlusOperator implements Operator {
@Override
public String getName() {
// TODO Auto-generated method stub
return "+";
}
@Override
public double execute(double a, double b) throws Exception {
// TODO Auto-generated method stub
return a+b;
}
}
package lesson02.get;
public class MinusOperator implements Operator {
@Override
public String getName() {
// TODO Auto-generated method stub
return null;
}
@Override
public double execute(double a, double b) throws Exception {
// TODO Auto-generated method stub
return 0;
}
}
package lesson02.get;
public class MultipleOperator implements Operator {
@Override
public String getName() {
// TODO Auto-generated method stub
return null;
}
@Override
public double execute(double a, double b) throws Exception {
// TODO Auto-generated method stub
return 0;
}
}
package lesson02.get;
public class DivOperator implements Operator {
@Override
public String getName() {
// TODO Auto-generated method stub
return "/";
}
@Override
public double execute(double a, double b) throws Exception {
// TODO Auto-generated method stub
return a/b;
}
}
package lesson02.get;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
@WebServlet("/CalculatorServlet") //form의 action과 일치해야함.
public class CalculatorServlet extends HttpServlet {
private Hashtable<String, Operator> opTable =
new Hashtable<String, Operator>();
public CalculatorServlet() {
opTable.put("+", new PlusOperator());
opTable.put("-", new MinusOperator());
opTable.put("*", new MultipleOperator());
opTable.put("/", new DivOperator());
}
@Override
// 변수와 값이 url에 나온다.
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("get 요청 ");
process(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("post 요청 ");
process(req, resp);
}
private void process(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 클라이언트가 보내온 변수값을 추출
String op = req.getParameter("op");
double v1 = Double.parseDouble(req.getParameter("v1"));
double v2 = Double.parseDouble(req.getParameter("v2"));
// 2. 우리가 보내는 데이터를 utf-8로 해석해
resp.setContentType("text/html;charset=UTF-8");
// 3.클라이언트와 연결된 스트림을 포함하고 있는 연결 객체 추출
PrintWriter out = resp.getWriter();
// 4. 클라이언트(브라우저)에 데이터 전송
out.println("<html><body>");
out.println("<h1>계산결과</h1>");
out.println("결과 : ");
try {
Operator operator = opTable.get(op);
if(operator==null)
out.println("존재하지 않는 연산자!");
else {
double result = operator.execute(v1, v2);
out.println(String.format("%.3f", result));
}
}catch(Exception e) {
out.println("연산 오류 발생!");
}
out.println("</body></html>");
}
}
package lesson02.post;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 브라우저에 한글이 포함되면 깨지므로 설정을 해야 한다
// 브라우저 정보를 utf-8로 해석을 함
req.setCharacterEncoding("UTF-8");
// 2. 브라우저가 보낸 변수값을 추출
String id = req.getParameter("id");
String password = req.getParameter("password");
// 3. 브라우저에 utf-8로 전송하겠다고 알려줌
resp.setContentType("text/html;charset=UTF-8");
// 4. 브라우저와 연결된 통신 객체를 얻어야 함
PrintWriter out = resp.getWriter();
// 5. 결과를 전송한다
out.println("<html><body>");
if(password.equals("1111")) {
out.println("<h1>로그인결과</h1>");
out.println("<strong>" + id + "</strong>님을 환영합니다 ");
} else {
out.println("암호가 틀렸습니다!");
}
out.println("</body></html>");
}
}
Servlet Life Cycle
package lesson03.servlets;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloWorld implements Servlet {
ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init() 호출됨 ");
this.config = config;
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("service() 호출됨 ");
}
@Override
public void destroy() {
System.out.println("destroy() 호출됨 ");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig() 호출됨 ");
return this.config;
}
@Override
public String getServletInfo() {
System.out.println("getServletInfo() 호출됨 ");
return "version=1.0;author=bitcamp;copyright=bitcamp 2021";
}
}
: @WebServlet("/LoginServlet") 처럼 annotation을 이용하여 불러오는 방식은 편의성을 위해서이다. xml 방식을 이용하게 되면 나중에 유연하게 변경이 가능하다. (차차 알아볼 것)
실행시 파일은 welcome-file-list의 순서대로 불러오게 된다.
<?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>_04_ServletLifeCycle</display-name>
<!-- 서블릿 선언(객체로 만들어 컨테이너에 주입한다) -->
<servlet>
<!-- 내가 정해준다. 이 이름과 매칭되는 객체를 찾는다. -->
<servlet-name>Hello</servlet-name>
<!-- 패키지와 파일 이름, 이 경로를 찾아가서 객체로 만든다. 컨테이너에 포함시킨다. -->
<servlet-class>lesson03.servlets.HelloWorld</servlet-class>
</servlet>
<!-- 서블릿을 url과 연결 -->
<!-- /Hello : /는 컨텍스트 루트를 의미한다 (http://localhost:9999/_04_ServletLifeCycle 까지가 context root) -->
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/Hello</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>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>환영합니다 </title>
</head>
<body>
<h1>default.html</h1>
<p>환영합니다</p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>환영합니다 </title>
</head>
<body>
<h1>index.html</h1>
<p>먼저 선언된 것을 먼저 찾는다</p>
</body>
</html>