본문 바로가기

Spring/Servlet

뉴렉처 서블릿2 (동적 페이지 | doGet, doPost)

@WebServlet("/calcpage")            //경로가 같을때는 /를 생략하고 calcpage로 쓸 수 있다.

 

html 페이지를 자바 클래스(서블릿 코드)로 가져와 출력하고 있다

out.write("html태그들");

 

동적으로 주고 싶을 때 out.write 대신 out.printf 쓴다

out.printf("~~~%d~~", exp); -> 7

 

출력하는 페이지 [순서상 두번째 혹은 초기화면]

package com.newlecture.web; [CalcPage.java파일]

@WebServlet("/calcpage")
public class CalcPage extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response){
    	//쿠키를 읽어오는 작업
    	String exp ="0"; //기본은 0 [계산기니까]
        Cookie[] cookies = request.getCookies();
        if(cookies != null)
          for(Cookie c: cookies)
              if(c.getName().equals("exp")){ //exp라는 이름의 쿠키가 있다면
                  exp = c.getValue(); //exp에 그 값을 저장
                  break;
              }
    	response.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=utf-8");
        PrintWriter out = response.getWriter(); //출력을 위한 도구
        
        //html태그 처음부터 끝까지 그대로 복사한 후 
        out.write("html태그 복붙") 문자열 출력도구
        out.printf("%s", exp ); //문자열이니까 s, 변수[계산식]
    }

 


쿠키 지우는 법

개발자도구 - 네트워크 - 우클릭- clear browser cookies

값을 받아 연산하는 페이지 [순서상 첫번째]

 

자바에서 자바스크립트 사용 (ScriptEngine 혹은 GraalVM [최신버전 JDK])

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");

engine.eval(exp); // exp 연산식을 그대로 실행할 수 있음

Calc3.java
public class calc3 extends HttpServlet{

	protected void service(HttpServletRequest request, HttpServletResponse response){
    	Cookie[] cookies = request.getCookies();
        
        String value = request.getParameter("v");
        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");
            //exp라는 연산식을 그대로 실행 (try-catch 예외처리필요)
            exp = String.valueOf(engine.eval(exp)); //계산 결과를 String으로 바꾸어 출력
        }
        else if(operator != null && operator.equals("C")){ //Clear을 눌렀을 때
            exp = ""; //쿠키 지우기 1단계 : 빈문자열로 주기
        }
        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); //쿠키 지우기 2단계 Clear
        }
        expCookie.setPath("/"); //전역범위로 쿠키를 설정하거나 아니면 하나의 페이지만 가능
        response.addCookie(expCookie);
        response.sendRedirect("calcpage"); //같은 경로이기 때문에 /없이 써줌

Service함수

요청에 따른 함수 호출[doGet, doPost]

super.service(request, response);

 

부모가 가지는 service함수는 사용자 요청을 판단해 메소드를 호출한다. 이때 해당 메소드가 오버라이드 되어있어야 한다.

 

 

init() → service() → doGet() 혹은 doPost()

사용자 요청이 들어오면 doGet(), doPost() 중 service함수가 알아서 판단해서 각 메소드를 자동호출함

 

 1. service를 오버라이드한 후 그 안에서 get, post를 처리할 것인지 [조건처리] 

     - service함수 내에서 조건처리하지 않고 super.service()를 사용한다면 필요한 메소드 오버라이드 필수

     - 조건처리할 경우 super.service()를 삭제하면 됨

     - doGet, doPost를 호출하기 전에 공통으로 할 일(한번에 처리)이 있다면 service를 오버라이드 해야함

 

 2. service를 오버라이드하지 않고 doGet, doPost 중 필요한 메소드만 오버라이드하기 [특화된 메소드]  

    공통의 작업이 필요하지 않다면 service함수를 오버라이드하지 않는다.

    doGet, doPost중 필요한 함수만 오버라이드해서 작성한다면 이에 따라 알아서 doGet, doPost함수가 호출된다.

 

 

404에러 - 해당 URL이 없을 때

405에러 - URL은 있는데 요청을 처리할 로직이 없을 때

 

 

package com.newlecture.web;

@WebServlet("/calculator") //해당 url로 요청
public class Calculator extends HttpServlet{
	@Override
    protected void service(HttpServletRequest request, HttpServletResponse response){
    	//방법1
 		if(request.getMethod().equals("GET")){ //항상 대문자로 비교해야함
        	System.out.print("get요청이 들어왔습니다.");
        } else if(request.getMethod().equals("POST")){
        	System.out.print("post 요청이 들어왔습니다.");
        }
        
		//super.service(request, response); //해당 메소드가 오버라이드 되어있다면 이제 호출함
        
        //방법2 : 공통의 작업이 없을 때 service함수 호출 없이 바로 호출
        @Override
        protected void doGet(HttepServletRequest request, HttpServletResponse response){
        	System.out.print("get요청이 들어왔습니다.");
        }
        @Override
        protected void doPost(HttepServletRequest request, HttpServletResponse response){
        	System.out.print("post 요청이 들어왔습니다.");
        }
    }
}


+ 
WebContent에 calculator.html 추가
<form action="calculator" method ="get"["post"]>
 <input type="submit" value="요청">
 </form>
 

 


기존에는 CaclPage[출력 페이지]에서 GET요청을 처리, Cacl3[입력 값을 바탕으로 연산페이지]에서 POST요청을 나눠 처리했다.

그러나 쿠키의 사용 범위를 설정할 때 특정 URL페이지 하나 혹은 전역범위로만 가능하기 때문에

하나의 URL에서 요청을 처리할 수 있도록 기존의 코드를 바꿔줄 필요가 있다.

 

- 자기 페이지로 요청할 땐 form태그에서 action을 넣지 않아도 된다.

- redirection에서도 마찬가지로 자기자신이기 때문에 response.sendRedirect("calculator"); //경로 쓸 필요X, GET요청

- 같은 서블릿에서 처리하고 출력하기 때문에 이제 URL이 바뀌지 않음

 

package com.newlecture.web;

@WebServlet("/calculator") //해당 url로 요청
public class Calculator extends HttpServlet{
	@Override
    protected void service(HttpServletRequest request, HttpServletResponse response){        
        @Override
        protected void doGet(HttepServletRequest request, HttpServletResponse response){
          //쿠키를 읽어오는 작업
          String exp ="0"; //기본은 0 [계산기니까]
          Cookie[] cookies = request.getCookies();
          if(cookies != null)
            for(Cookie c: cookies)
                if(c.getName().equals("exp")){ //exp라는 이름의 쿠키가 있다면
                    exp = c.getValue(); //exp에 그 값을 저장
                    break;
                }
          response.setCharacterEncoding("utf-8");
          response.setContentType("text/html; charset=utf-8");
          PrintWriter out = response.getWriter(); //출력을 위한 도구

          //html태그 처음부터 끝까지 그대로 복사한 후 
          out.write("html태그 복붙") 문자열 출력도구
          out.printf("%s", exp ); //문자열이니까 s, 변수[계산식]
          //<form 태그 내 action=경로 삭제>
        }
        
        @Override
        protected void doPost(HttepServletRequest request, HttpServletResponse response){
          Cookie[] cookies = request.getCookies();

          String value = request.getParameter("v");
          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");
              //exp라는 연산식을 그대로 실행 (try-catch 예외처리필요)
              exp = String.valueOf(engine.eval(exp)); //계산 결과를 String으로 바꾸어 출력
          }
          else if(operator != null && operator.equals("C")){ //Clear을 눌렀을 때
              exp = ""; //쿠키 지우기 1단계 : 빈문자열로 주기
          }
          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); //쿠키 지우기 2단계 Clear
          }
          expCookie.setPath("/calculator"); //URL하나로 한정(자기호출)
          response.addCookie(expCookie);
          response.sendRedirect("calculator"); //GET요청, 자기 호출 ("/"쓰지 않음)

        }
    }
}

localhost:8090/calculator로 요청