본문 바로가기
☕ Java 웹 프로그래밍/Servlet & JSP

[Servlet&JSP] 계산기 프로그램을 서블릿 하나로 합치기

by 일단연 2023. 6. 5.

* 본 글은 [뉴렉처]의 Servlet&JSP 프로그래밍 강의를 듣고 정리한 글입니다.

 

2020 Servlet&JSP 프로그래밍

 

www.youtube.com

 

 계산기 프로그램을 서블릿 하나로 합치기 

두 개의 서블릿으로 이루어진 계산기 프로그램

  • 현재: CalcPage 서블릿이 클라이언트, Cal3 서블릿이 서버로 작동하는 상태
  • CalcPage 서블릿과 Cal3 서블릿을 Calculator 서블릿으로 합침
    • CalcPage 서블릿은 GET 요청만 처리, Cal3 서블릿은 POST 요청만 처리하니까 GET 요청과 POST 요청을 Calculator 서블릿에서 한꺼번에 처리할 것
      • CalcPage 서블릿의 GET 요청은 Calculator 서블릿의 doGet( )메소드에서 처리
      • Cal3 서블릿의 POST 요청은 Calculator 서블릿의 doPost( )메소드에서 처리

 

계산기 프로그램을 하나의 서블릿으로 합치는 과정

  • [Calculator.java] doGet( )메소드에 CalcPage 서블릿의 service( )메소드 내용을 붙여넣고, doPost( )메소드에 Calc3 서블릿의 service( )메소드 내용을 붙여넣기
  • doGet( )메소드에서 <form>의 action 속성 제거
    • out.write(" <form method=\"post\">");
    • CalcPage 서블릿에서 <form>에 action 속성 값을 부여한 이유는 GET 요청을 하는 페이지 URL(/calcpage)와 POST를 담당하는 URL(/calc3)이 달랐기 때문
    • Calculator 서블릿으로 통합한 지금은 현재 페이지의 URL과 POST를 담당하는 URL과 같으면 <form>의 action 속성이 필요없음 (자기 페이지를 요청하는데 메소드를 post로 하는 것일 뿐)
  • doPost( )메소드에서 redirect 주소를 calculator로 변경
    • response.sendRedirect("calculator");
    • 자기가 자기를 호출하더라도 GET 요청을 위한 것
    • 경로(” / “) 쓸 필요 없음
  • 쿠키 path 옵션을 calculator로 설정
    • expCookie.setPath(”/calculator”);
    • 다른 URL에는 쿠키가 전달되지 않음. calculator만 쿠키를 사용할 수있음.
    • path 옵션에는 하나의 path만 입력할 수 있음

 

하나의 서블릿으로 통합된 계산기 프로그램 결과

  • value = 3, op = + 입력

  • value = 3과 6, op = + 입력

  • 계산 결과

 

Calculator.java 코드

package com.newlecture.web;

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

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/calculator")
public class Calculator extends HttpServlet {
  @Override
  protected void service(HttpServletRequest request
                        , HttpServletResponse response) 
                        throws ServletException, IOException
  {
    if(request.getMethod().equals("GET")) {
      System.out.println("GET 요청이 왔습니다.");
    }
    else if(request.getMethod().equals("POST")) {
      System.out.println("POST 요청이 왔습니다.");
    }
    super.service(request, response);
  }
	
  @Override
  protected void doGet(HttpServletRequest request
                        , HttpServletResponse response) 
                        throws ServletException, IOException {
    Cookie[] cookies = request.getCookies();
		
    String exp = "0";
    if(cookies != null) {
      for(Cookie c : cookies) {
        if(c.getName().equals("exp")) {
          exp = c.getValue();
          break;
        }
      }
    }
		
    response.setContentType("text/html; charset=UTF-8");
    response.setCharacterEncoding("UTF-8");
    PrintWriter out = response.getWriter();

    out.write("<!DOCTYPE html>");
    out.write("<html>");
    out.write("  <head>");
    out.write("    <meta charset=\"UTF-8\">");
    out.write("    <title>계산기 웹 프로그램</title>");
    out.write("    <style>");
    out.write("      input{");
    out.write("        width: 50px;");
    out.write("        height: 50px;");
    out.write("      }");
    out.write("      .output{");
    out.write("        height: 50px;");
    out.write("        background: #e9e9e9;");
    out.write("        font-size: 24px;");
    out.write("        font-weight: bold;");
    out.write("        text-align: right;");
    out.write("        padding: 0px 5px;");
    out.write("      }");
    out.write("    </style>");
    out.write("  </head>");
    out.write("  <body>");
    out.write("    <form method=\"post\">");
    out.write("      <table>");
    out.write("        <tr>");
    out.printf("          <td class = \"output\" colspan=\"4\">%s</td>", exp);
    out.write("        </tr>");
    out.write("        <tr>");
    out.write("          <td><input type=\"submit\" name=\"operator\" value=\"CE\"></td>");
    out.write("          <td><input type=\"submit\" name=\"operator\" value=\"C\"></td>");
    out.write("          <td><input type=\"submit\" name=\"operator\" value=\"BS\"></td>");
    out.write("          <td><input type=\"submit\" name=\"operator\" value=\"/\"></td>");
    out.write("        </tr>");
    out.write("        <tr>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"7\"></td>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"8\"></td>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"9\"></td>");
    out.write("          <td><input type=\"submit\" name=\"operator\" value=\"*\"></td>");
    out.write("        </tr>");
    out.write("        <tr>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"4\"></td>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"5\"></td>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"6\"></td>");
    out.write("          <td><input type=\"submit\" name=\"operator\" value=\"-\"></td>");
    out.write("        </tr>");
    out.write("        <tr>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"1\"></td>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"2\"></td>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"3\"></td>");
    out.write("          <td><input type=\"submit\" name=\"operator\" value=\"+\"></td>");
    out.write("        </tr>");
    out.write("        <tr>");
    out.write("          <td></td>");
    out.write("          <td><input type=\"submit\" name=\"value\" value=\"0\"></td>");
    out.write("          <td><input type=\"submit\" name=\"dot\" value=\".\"></td>");
    out.write("          <td><input type=\"submit\" name=\"operator\" value=\"=\"></td>");
    out.write("        </tr>");
    out.write("      </table>");
    out.write("    </form>");
    out.write("  </body>");
    out.write("</html>");
  }
	
  @Override
  protected void doPost(HttpServletRequest request
                        , HttpServletResponse response) 
                        throws ServletException, IOException {
    //브라우저가 POST 요청할 때 보낸 쿠키를 서버가 읽음
    Cookie[] cookies = request.getCookies();
		
    //사용자가 입력한 값들을 받는 문자열
    String value = request.getParameter("value");
    String operator = request.getParameter("operator");
    String dot = request.getParameter("dot");
		
    //쿠키에서 값을 읽어와 사용자가 입력한 값에 덧붙임
    String exp = "";
    if(cookies != null) {
      for(Cookie c : cookies) {
        if(c.getName().equals("exp")) {
          exp = c.getValue();
          break;
        }
      }
    }
		
    //사용자가 입력한 값이 =이라면 누적된 값을 계산
    if(operator != null && operator.equals("=")) {
      ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
      try {
        exp = String.valueOf(engine.eval(exp));
      } catch (ScriptException e) {
        e.printStackTrace();
      }
    }
    //사용자가 입력한 값이 C라면 누적된 값 삭제(쿠키 삭제)
    else if(operator != null && operator.equals("C")) {
      exp = "";
    }
    //사용자가 입력한 값이 value, operator, dot이라면 누적
    else {
      exp += (value == null) ? "" : value;
      exp += (operator == null) ? "" : operator;
      exp += (dot == null) ? "" : dot;
    }
		
    //쿠키에에서 값을 읽어와 사용자가 입력한 값에 덧붙인 값을 쿠키로 저장
    Cookie expCookie = new Cookie("exp", exp);
    // 브라우저를 끄지 않아도 C 버튼을 누르면 쿠키가 삭제됨
    if(operator != null && operator.equals("C")) {
      expCookie.setMaxAge(0);
    }
    expCookie.setPath("/calculator");
    //서버에서 클라이언트로 exp의 쿠키 보내기
    response.addCookie(expCookie);
    //계산기에서 버튼을 클릭하면 빈 화면이 출력되지 않고 Calculator.java의 화면이 출력됨
    response.sendRedirect("calculator");
  }
}