그럼에도 불구하고

👨‍💻

[Servlet] service / doGet / doPost 본문

Java, Servlet/Servlet, Jsp

[Servlet] service / doGet / doPost

zenghyun 2022. 11. 5. 00:53

service/ doGet / doPost에 대해 알아보자

 

우선, service와 doGet, doPost를 사용하지 않고 두 개의 java을 이용하여 계산기를 만들어보자.

 

calcPage.java

package com.zenghyun.web;

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

import javax.servlet.ServletContext;
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;
import javax.servlet.http.HttpSession;

@WebServlet("/calcPage")
public class calcPage extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		String exp ="0";
		Cookie[] cookies = request.getCookies();
		if(cookies !=null)
		for( Cookie c : cookies) {
			if(c.getName().equals("exp")) {
				exp = c.getValue();
				break;
			}
			}
		PrintWriter out = response.getWriter();
		
		out.write("<!DOCTYPE html>");
		out.write("<html>");
		
		
		out.write("<head>");
		out.write("<meta charset=\"UTF-8\">");
		out.write("<title>calculator</title>");
		out.write("<style>");
		out.write("	input { width:50px; height:50px;}");
		out.write("	.output { height:50px; background:#e9e9e9; font-size: 24px; font-weight: bold; text-align: right; padding:0px 5px;}");
		out.write("</style>");
		out.write("</head>");
		out.write("<body>");
		out.write("<form action=\"calculator3\" method=\"post\">");
		out.write("<h2>계산할 값을 입력하세요.</h2>");
		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=\"\" 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><input type=\"submit\" name=\"operator\" value=\"±\"></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>");
	}
}

 

html파일을 사용하지 않고 java 파일에서 html을 구현하기 위해 out.write에 모든 내용을 담았다. 

 

굉장히 비효율적인 방법이다. 

 

JSP를 사용하면 되기 때문

 

이번에만 이렇게 할 것이다.

 

JSP를 사용하면 편하다는 것을 뼈저리게 느끼기 위함..?

 

 

 

String exp ="0";
Cookie[] cookies = request.getCookies();
if(cookies!=null)
for( Cookie c : cookies) {
if(c.getName(). equals("exp")) {
exp = c.getValue();
break;
}
}

 

cookies라는 배열을 담을 변수로 선언하고 cookies가 null이 아니라면 for문을 사용하여 exp에 값을 넣는 코드이다.

 

 

out.write("<form action=\"calculator3\" method=\"post\">");

form 태그를 사용하여 calculator3.java에 data를 post 한다.

 

out.printf(" <td class=\"output\" colspan=\"4\">%s</td>",exp);

exp 값을 출력한다.

 

 

 

calculator3.java

package com.zenghyun.web;

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

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.servlet.ServletContext;
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;
import javax.servlet.http.HttpSession;

@WebServlet("/calculator3")
public class calculator3 extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		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("graal.js");
			try {
				exp = String.valueOf(engine.eval(exp)); // 자바스크립트 실행 코드 
			} catch (ScriptException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else if(operator != null && operator.equals("C")) {
			exp = ""; //빈 문자열 만들기 
		
		}
		else {
		exp += (value == null)? "" : value;
		exp += (operator == null)? "" : operator;
		exp += (dot == null)? "" : dot;
		}
		
		Cookie expCookie = new Cookie("exp", exp);
		if(operator != null && operator.equals("C"))
			expCookie.setMaxAge(0); //쿠키를 지움 
		expCookie.setPath("/"); //쿠키 받을 page 설정 
		response.addCookie(expCookie);
		response.sendRedirect("calcPage"); //html 페이지를 새로 요청함 
		}
		
 	}

 

 

 

String value = request.getParameter("value");
String operator = request.getParameter("operator");
String dot = request.getParameter("dot");

 

calcPage에서의 value : 0~9까지의 숫자

calcPage에서의 operator : 각종 연산자 및 기호 

calcPage에서의 dot: 소수점을 표현하기 위한 "."

 

즉. request.getParameter로 value, operator, dot을 담는다.

 


   

String exp ="";
if(cookies!=null)
for( Cookie c : cookies) {
if(c.getName(). equals("exp")) {
exp = c.getValue();
break;
}
}

 

cookies라는 배열을 담을 변수로 선언하고 cookies가 null이 아니라면 for문을 사용하여 exp에 값을 넣는 코드이다.

 


 

if(operator!= null && operator.equals("=")) {
ScriptEngine engine = new ScriptEngineManager(). getEngineByName("graal.js");
try {
exp = String.valueOf(engine.eval(exp)); // 자바스크립트 실행 코드 
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

내가 받아온 operator가 null이 아니고 "="라면 exp에 내가 입력한 값을 받아 계산한다. 

ex) 5+4 = 9와 같이 표현하기 위함 

 

ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js");

 

처음에 이 코드를 사용하고자 하면 에러가 발생한다. 

※ engined이 null이라는 오류 발생

 

 

 

스크립트 엔진 안될 때 해결법 

1. 프로젝트 우클릭 -> configure -> convert to maven project 클릭

 

2. 생성된 pom.xml 파일에

<dependencies> <dependency> <groupId>org.graalvm.js</groupId> <artifactId>js</artifactId> <version>19.2.0.1</version> </dependency> <dependency> <groupId>org.graalvm.js</groupId> <artifactId>js-scriptengine</artifactId> <version>19.2.0.1</version> </dependency> </dependencies> 삽입

( <build> 바로 위 )

 

3. Calc3.java에 ScriptEngine engine = new ScriptEngineManager(). getEngineByName("graal.js"); 삽입

 

 

이렇게 해주면 해결된다.

 

 


 

else if(operator!= null && operator.equals("C")) {
exp = ""; //빈 문자열 만들기 

}

 

계산기에서 "C"가 눌리면 계산기를 초기화한다. 

※뒤에 다른 코드 더 써야 한다.

 


 

else {
exp += (value == null)? "" : value;
exp += (operator == null)? "" : operator;
exp += (dot == null)? "" : dot;
}

 

value가 null이면 ""를  + / null이 아니면 value를 + 

operator가 null이면 ""를  + / null이 아니면 operator를 + 

dot이 null이면 ""를  + / null이 아니면 dot을  + 

 


 

Cookie expCookie = new Cookie("exp", exp);
if(operator!= null && operator.equals("C"))
expCookie.setMaxAge(0); //쿠키를 지움 
expCookie.setPath("/"); //쿠키 받을 page 설정 
response.addCookie(expCookie);
response.sendRedirect("calcPage"); //html 페이지를 새로 요청함 
}

 

exp를 "exp"라는 이름으로 expCookie에 담고,

operator가 null이 아니고 "C"와 같다면 쿠키를 지운다.

 

 

 

출력 화면

최초화면

 

 

값 입력

 

 

"="  눌렀을 때

 

"C" 눌렀을 때

 

이렇게 계산기를 완성해봤다.

 

하지만, 너무 불편한 점이 많은 계산기이다. 

 

request와 response를 나눠서 받아야 하고, 

 

java file을 두 개씩이나 사용해야 한다. 

 

 


service와 doGet, doPost를 이용하면 하나의 java file로 해결할 수 있다.

 

 

 

 

service method와 doGet doPost를 이용하여 request와 response를 하나의 파일에서 해결하는 것이다.

 

getPostCalculator.java

package com.zenghyun.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("/getPostCalculator39")
public class getPostCalculator39 extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		if (request.getMethod().equals("GET")) // 요청이 get이냐 post냐를 확인 대문자로 비교해야 함!
		{
			System.out.println("GET 요청이 왔습니다.");
		} else if (request.getMethod().equals("POST")) {
			System.out.println("POST 요청이 왔습니다.");
		}
		super.service(request, response);
	}

	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;
				}
			}
		
		PrintWriter out = response.getWriter();

		out.write("<!DOCTYPE html>");
		out.write("<html>");

		out.write("<head>");
		out.write("<meta charset=\"UTF-8\">");
		out.write("<title>calculator</title>");
		out.write("<style>");
		out.write("	input { width:50px; height:50px;}");
		out.write(
				"	.output { height:50px; background:#e9e9e9; font-size: 24px; font-weight: bold; text-align: right; padding:0px 5px;}");
		out.write("</style>");
		out.write("</head>");
		out.write("<body>");
		out.write("<form  method=\"post\">"); //현재 get요청하는 페이지와 post하는 페이지가 같기 때문에 action 필요 없음
		out.write("<h2>계산할 값을 입력하세요.</h2>");
		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=\"\" 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><input type=\"submit\" name=\"operator\" value=\"±\"></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 {
		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("graal.js");
			try {
				exp = String.valueOf(engine.eval(exp)); // 자바스크립트 실행 코드
			} catch (ScriptException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else if (operator != null && operator.equals("C")) {
			exp = ""; // 빈 문자열 만들기
			

		} else {
			exp += (value == null) ? "" : value;
			exp += (operator == null) ? "" : operator;
			exp += (dot == null) ? "" : dot;
		}

		Cookie expCookie = new Cookie("exp", exp);
		if (operator != null && operator.equals("C"))
			expCookie.setMaxAge(0); // 쿠키를 지움
		expCookie.setPath("/JSPPrj/getPostCalculator39"); // 쿠키 받을 page 설정
		response.addCookie(expCookie);
		response.sendRedirect("getPostCalculator39"); // html 페이지를 새로 요청함
		//	자기가 자기를 호출해도 get 요청을 의미한다. 
	}

}

 

getPostCalculator.java는 calc.java와 calculator3.java를 합친 file이다.

 

@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

if (request.getMethod(). equals("GET")) // 요청이 get이냐 post냐를 확인 대문자로 비교해야 함!
{
System.out.println("GET 요청이 왔습니다.");
} else if (request.getMethod(). equals("POST")) {
System.out.println("POST 요청이 왔습니다.");
}
super.service(request, response);
}

 

service method를 이용하여 

request.getMehod가 "GET" 인지 " POST"인지 구분하여 sevice 자신에게 request, response 한다. 

 

doGet, doPost 없이 super.service(req, resp);만 선언하면 405 오류가 발생한다.

URL을 처리할 메서드가 없기 때문

 

 


 

아래의 코드에서 특별하게 달라진 부분이 있다면, 

 

doPost method의 마지막에서 

expCookie.setPath("/JSPPrj/getPostCalculator39"); // 쿠키 받을 page 설정

쿠키를 받을 page의 경로를 설정하고, 

 

response.sendRedirect("getPostCalculator39"); // html 페이지를 새로 요청함

자기가 자기 자신을 호출하는 것이다. 

 

※ form 태그에서 post로 보냈는데 doGet method를 사용해야 하는 이유

하나의 java file로 request, response를 하기 위해서는 자기 자신을 호출해야 한다. 

 

자기 자신을 호출하는 것은 get 요청을 의미한다. 

 

 

 

Comments