* 본 글은 [뉴렉처]의 Servlet&JSP 프로그래밍 강의를 듣고 정리한 글입니다.
2020 Servlet&JSP 프로그래밍
www.youtube.com
계산기 서블릿 완성하기
- 사용자가 누른 버튼의 값들(value, operator, dot)이 누적되어 입력창에 그 누적된 값들이 연산된 결과가 출력되어야 함
계산기 서블릿의 구동 과정
- 1) CalcPage.java의 화면에서 사용자가 값 버튼을 클릭해 POST 요청
- 2) Calc3.java에서 그 값들(value, operator, dot)을 누적한 값인 exp를 쿠키로 저장한 후 > CalcPage.java로 redirect
- 3) CalcPage.java는 Calc3.java에서 exp를 쿠키로 읽어서 printf( )메소드로 화면에 출력 (계산기에 최종 출력됨)
계산기 서블릿 완성하기 - CalcPage.java와 Calc3.java
- 1) [CalcPage.java] calc3.java에서 쿠키 객체와 쿠키를 읽어내는 코드를, CalcPage.java로 복사+붙여넣기
- Calc3.java의 exp를 배열 형태의 쿠키로 받는 작업을 제일 먼저 수행하도록 CalcPage.java 코드 맨위에 위치시킴
- 연산식 자체를 읽어내도록 operator를 exp(expression, 표현식)으로 변경
- 원래 아래의 코드였음
String operator = "";
for(Cookie c : cookies) {
if(c.getName().equals("op")) {
operator = c.getValue( );
break;
}
}
- 원래 아래의 코드였음
- 쿠키가 null일 경우를 대비
- 쿠키가 null이 아니면 쿠키를 읽어오는 조건식 사용
- 쿠키가 null이면 exp의 기본값은 0
// 1) Cookie[] cookies = request.getCookies(); String exp = "0"; if(cookies != null) { for(Cookie c : cookies) { if(c.getName().equals("exp")) { exp = c.getValue(); break; } } }
- 2) [CalcPage.java] 계산기에 연산식이 출력되도록, CalcPage.java의 html 코드 안 출력 서식은 %s로, 출력 내용은 exp로 변경
- out.printf("<td class = \"output\" colspan=\"4\">%s</td>", exp);
- printf( )메소드의 형식: out.printf ("출력 서식", 출력할 내용);
- 3) [calc3.java] 불필요한 코드 제거
- Application, Session 코드는 제거
- ServletContext application = request.getServletContext( );
HttpSession session = request.getSession( );
- ServletContext application = request.getServletContext( );
- calc3.java에서 출력할 일은 없으니까 출력 형식 코드 제거
- response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
- response.setContentType("text/html; charset=UTF-8");
- Application, Session 코드는 제거
- 4) [calc3.java] 클라이언트가 보낸 값들을 받는 문자열을 value, operator, dot 3개로 만듦
// 4) 사용자가 입력한 값들을 받는 문자열
String value = request.getParameter("value");
String operator = request.getParameter("operator");
String dot = request.getParameter("dot");
- 5) [calc3.java] 불필요한 코드 제거
- 서버가 쿠키를 배열로 받아들이는 코드, 사용자가 입력한 값들을 받아들이는 문자열 코드, 클라이언트로 redirect하는 코드를 제외한 모든 코드는 제거
@WebServlet("/calc3")
public class Calc3 extends HttpServlet {
@Override
protected void service(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");
//html 페이지로 redirect
response.sendRedirect("calc2.html");
}
}
- 6) [calc3.java] exp 쿠키를 저장하기 위해 쿠키 객체 생성
- Cookie expCookie = new Cookie("exp", exp);
- 쿠키 객체 생성하는 방법
- Cookie 쿠키객체명 = new Cookie(key, value);
- 7) [calc3.java] 클라이언트가 쿠키를 저장하도록 addCookie( ) 메소드 사용
- response.addCookie(expCookie);
- 서버에서 클라이언트로 쿠키 보내는 방법
- response.addCookie(쿠키 객체명);
- 브라우저는 response에 심어진 값을 읽어서 그 값을 자신이 가짐
- 8) [calc3.java] redirect 주소 변경
- response.sendRedirect("calcpage");
- Calc3.java에서 CalcPage.java로 넘어갈 때의 경로가 같기 때문에 경로(/, 루트)를 쓰지 않고 주소만 써도 됨 > /calcpage 대신 calcpage로 써도 된다는 뜻
- 이전에는 response.sendRedirect("calc2.html"); 였음
- response.sendRedirect("calcpage");
// 6), 7), 8) 쿠키에에서 값을 읽어와 사용자가 입력한 값에 덧붙인 값을 쿠키로 저장
Cookie expCookie = new Cookie("exp", exp);
response.addCookie(expCookie);
response.sendRedirect("calcpage");
- 9) [calc3.java] 문자열 exp 만들기
- 쿠키가 null일 경우와 아닌 경우를 나눠서 코드 작성
- 쿠키가 null이 아니면 쿠키를 읽어오는 조건식 사용
- 쿠키가 null이면 exp의 기본값은 빈 문자열
- String exp = "";
- 쿠키가 null일 경우와 아닌 경우를 나눠서 코드 작성
// 9) 쿠키에서 값을 읽어와 사용자가 입력한 값에 덧붙임
String exp = "";
if(cookies != null) {
for(Cookie c : cookies) {
if(c.getName().equals("exp")) {
exp = c.getValue();
break;
}
}
}
- 10) [calc3.java] exp에 value, operator, dot 누적시키기
- 사용자가 버튼을 클릭할 때 value, operator, dot 중 값 하나만 전달되므로 각각 코드를 작성
- value/operator/dot 중 하나가 쿠키로 전달됐을 때 value/operator/dot가 null이면 빈 문자열을, null이 아니면 value/operator/dot 중 하나를 exp에 붙임
- exp += (value == null) ? "" : value;
- exp += (operator == null) ? "" : operator;
- exp += (dot == null) ? "" : dot;
- 삼항 연산자 사용법
- 조건식 ? 반환값1 : 반환값2
- 예: result = (num1 - num2 > 0) ? num1 : num2;
- 11) [calc3.java] operator가 =일 경우엔 누적시키는 게 아니라 값을 계산해서 exp에 남겨야 하기 때문에 이를 위한 조건문 작성
- operator가 =이 아닌 경우(+, -, x, ÷), 값을 누적
- operator가 null이 아니고 =인 경우, 값을 계산
- 값을 계산하는 식이 Java나 JavaScript에서 구문상 차이가 없기 때문에, Java에서 JavaScript를 실행할 수 있는 라이브러리 ScriptEngine(javax.script의 인터페이스) 사용
- ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); engine.eval(exp);
- getEngineByName( )으로 엔진 이름을 얻어오고, eval( )로 JavaScript 실행
- engine.eval(exp); 은 예외처리를 해줘야 함
- engine.eval(exp)를 exp에 저장
- exp는 String이고 engine.eval(exp)는 Object라서 변환해줘야 함
- exp = String.valueOf(engine.eval(exp));
- ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); engine.eval(exp);
// 10), 11) 사용자가 입력한 값이 =이라면 계산을 위한 로직 구현
if(operator != null && operator.equals("=")) {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
exp = String.valueOf(engine.eval(exp));
} catch (ScriptException e) {
e.printStackTrace();
}
}
//사용자가 입력한 값이 value, operator, dot이라면 누적
else {
exp += (value == null) ? "" : value;
exp += (operator == null) ? "" : operator;
exp += (dot == null) ? "" : dot;
}
- 12) [CalcPage.java] <table>의 <input>에서 operator를 x가 아니라 *로, ÷이 아니라 /로 변경
- 곱셈 연산자를 *가 아니라 x, 나눗셈 연산자를 /가 아니라 ÷로 써놨기 때문에 계산식을 만들어 수행할 때 문제가 되기 때문
- x와 ÷를 계속 쓰려면 Calc3.java에서 해당 문자를 *와 /로 대치하는 작업을 해야 함
계산기 서블릿 완성하기 주의사항 - CalcPage.java와 Calc3.java
- 먼저 브라우저의 쿠키 제거
- 개발자 도구>Network>calcpage에서 오른쪽 클릭>Clear browser cookies 클릭
- CalcPage.java와 Calc3.java의 매핑 주소가 모두 정확해야 함
- CalcPage.java에서 @WebServlet("/calcpage")
- CalcPage.java의 HTML 코드에서 out.write("<form action=\"calc3\" method=\"post\">");
- Calc3.java에서 @WebServlet("/calc3")
계산기 서블릿 완성하기 결과 - CalcPage.java와 Calc3.java
계산식: 3*5 - 8/4 + 2
- [ 3 ] 숫자 3를 클릭하면 서버에 value: 3이 POST 요청으로 전달 > 쿠키로 저장됨 (3 누적)
- [ 3 * ] 연산자 *를 클릭하면 서버에 operator: *가 POST 요청으로 전달 > 쿠키로 저장 (3 다음에 *가 누적됨)
- [ 3 * 5 ] 숫자 5를 클릭하면 서버에 value: 5이 POST 요청으로 전달 > 쿠키로 저장됨 (3 다음 * 다음 5 누적됨)
- [ 3 * 5 - ] 연산자 -를 클릭하면 서버에 operator: -이 POST 요청으로 전달 > 쿠키로 저장됨 (3 다음 * 다음 5 다음 - 누적됨)
- [ 3 * 5 - 8 ] 숫자 8를 클릭하면 서버에 value: 8이 POST 요청으로 전달 > 쿠키로 저장됨 (3 다음 * 다음 5 다음 - 다음 8 누적됨)
- [ 3 * 5 - 8 / ] 연산자 /를 클릭하면 서버에 operator: /이 POST 요청으로 전달 > 쿠키로 저장됨 (3 다음 * 다음 5 다음 - 다음 8 다음 / 누적됨)
- [ 3 * 5 - 8 / 4 ] 숫자 4를 클릭하면 서버에 value: 4이 POST 요청으로 전달 > 쿠키로 저장됨 (3 다음 * 다음 5 다음 - 다음 8 다음 / 다음 4 누적됨)
- [ 3 * 5 - 8 / 4 + ] 연산자 +를 클릭하면 서버에 operator: +이 POST 요청으로 전달 > 쿠키로 저장됨 (3 다음 * 다음 5 다음 - 다음 8 다음 / 다음 4 다음 + 누적됨)
- [ 3 * 5 - 8 / 4 + 2 ] 숫자 2를 클릭하면 서버에 value: 2이 POST 요청으로 전달 > 쿠키로 저장됨 (3 다음 * 다음 5 다음 - 다음 8 다음 / 다음 4 다음 + 다음 2 누적됨)
- [ 3 * 5 - 8 / 4 + 2 = 15 ] =를 클릭하면 누적된 값들이 계산되어 exp에 저장 > exp가 쿠키에 담겨서 클라이언트(CalcPage.java)로 전달 > 클라이언트는 그 쿠키를 읽어서 화면에 출력 > 결과: 15
계산기 서블릿 코드 - CalcPage.java와 Calc3.java
- CalcPage.java
package com.newlecture.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
{
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 action=\\"calc3\\" 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=\\"x\\"></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>");
}
}
- Calc3.java
package com.newlecture.web;
import java.io.IOException;
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("/calc3")
public class Calc3 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("nashorn");
try {
exp = String.valueOf(engine.eval(exp));
} catch (ScriptException e) {
e.printStackTrace();
}
}
//사용자가 입력한 값이 value, operator, dot이라면 누적
else {
exp += (value == null) ? "" : value;
exp += (operator == null) ? "" : operator;
exp += (dot == null) ? "" : dot;
}
//쿠키에에서 값을 읽어와 사용자가 입력한 값에 덧붙인 값을 쿠키로 저장
Cookie expCookie = new Cookie("exp", exp);
response.addCookie(expCookie);
response.sendRedirect("calcpage");
}
}
'☕ Java 웹 프로그래밍 > Servlet & JSP' 카테고리의 다른 글
[Servlet&JSP] GET과 POST에 특화된 service( )메소드 (0) | 2023.06.04 |
---|---|
[Servlet&JSP] 쿠키 삭제하기 (0) | 2023.06.03 |
[Servlet&JSP] 처음이자 마지막으로 동적인 페이지를 서블릿으로 직접 만들기 (0) | 2023.06.02 |
[Servlet&JSP] 동적인 페이지(서버 페이지)의 필요성 (0) | 2023.06.02 |
[Servlet&JSP] 서버에서 페이지 전환하기(redirection) (0) | 2023.06.02 |