• Home
  • About
    • Jiwon Jeong photo

      Jiwon Jeong

      끊임없이 배우며 성장하는 엔지니어

    • Learn More
    • Email
    • Github
  • Posts
    • All Posts
    • All Tags
    • All Categories
  • Projects

Ajax & JSP

19 Apr 2021

Reading time ~3 minutes

Ajax(XMLHTTPRequest 통신)

  • 웹에 데이터를 갱신할 때, 브라우저 새로고침 없이 서버로부터 데이터를 받는 것이 좋겠다는 생각에서 출발
  • 아래 방법은 XMLHTTPRequest 객체를 사용하는 표준방법
function ajax(data) {
 var oReq = new XMLHttpRequest();
 oReq.addEventListener("load", function() {
   console.log(this.responseText); // type = String
   var jsonobj = JSON.parse(this.responseText);
   console.log(jsonobj.key)
 });    
 oReq.open("GET", "http://www.example.org/getData?data=data");//parameter를 붙여서 보낼수있음. 
 oReq.send();
}
  1. XMLHttpRequest객체를 생성해서, open메서드로 요청을 준비하고, send메서드로 서버로 보냄
  2. 요청처리가 완료되면(서버에서 응답이 오면) load이벤트가 발생하고, 콜백함수가 실행
  3. 콜백함수가 실행될 때는 이미 ajax함수는 반환하고 콜스택에서 사라진 상태

중요

  • 서버에서 받아온 JSON 데이터는 문자열 형태 => 브라우저에서 바로 실행할 수 없음
  • 따라서 브라우저에서 제공하는 JSON 객체를 이용하여 자바스크립트 객체로 변환해야함
var json객체로변환된값 = JSON.parse("서버에서 받은 JSON 문자열");

JSP 실행 순서

  1. 브라우저가 웹서버에 JSP에 대한 요청 정보를 전달한다.
  2. 브라우저가 요청한 JSP가 최초로 요청했을 경우만 JSP로 작성된 코드가 서블릿으로 코드로 변환한다. (java 파일 생성)
  3. 서블릿 코드를 컴파일해서 실행가능한 bytecode로 변환한다. (class 파일 생성)
  4. 서블릿 클래스를 로딩하고 인스턴스를 생성한다.
  5. 서블릿이 실행되어 요청을 처리하고 응답 정보를 생성한다.

JSP 내장 객체

  • JSP를 실행하면 서블릿 소스가 생성되고 실행된다.
  • JSP에 입력한 대부분의 코드는 생성되는 서블릿 소스의 _jspService() 메소드 안에 삽입되는 코드로 생성된다.
  • _jspService()에 삽입된 코드의 윗부분에 미리 선언된 객체들이 있는데, 해당 객체들은 jsp에서도 사용 가능하다.
  • response, request, application, session, out과 같은 변수를 내장객체라고 한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
    StringBuffer url = request.getRequestURL();

    out.println("url : " + url.toString());
    out.println("<br>");
%>
</body>
</html>
  • 여기서 request, url 같은 객체는 따로 선언해주지 않아도 갖다 쓰면 된다!
  • 내장객체를 JSP 선언문 (<%! %>) 에서 쓸 수 없다. 왜냐하면 내장객체는 _jspService() 메소드 내에서 선언된 객체들이기 때문

Redirect

  • 리다이렉트는 HTTP프로토콜로 정해진 규칙이다.
  • 서버는 클라이언트의 요청에 대해 특정 URL로 이동을 요청할 수 있다. 이를 리다이렉트라고 한다.
  • 서버는 클라이언트에게 HTTP 상태코드 302로 응답하는데 이때 헤더 내 Location 값에 이동할 URL 을 추가한다. 클라이언트는 리다이렉션 응답을 받게 되면 헤더(Location)에 포함된 URL로 재요청을 보내게 된다. 이때 브라우저의 주소창은 새 URL로 바뀌게 된다.
  • 클라이언트는 서버로부터 받은 상태 값이 302이면 Location헤더값으로 재요청을 보내게 된다. 이때 브라우저의 주소창은 전송받은 URL로 바뀌게 된다.
  • 서블릿이나 JSP는 리다이렉트하기 위해 HttpServletResponse 클래스의 sendRedirect() 메소드를 사용한다
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    response.sendRedirect("redirect02.jsp");
%>    

핵심 : Redirect 시 요청 응답이 2번 이루어짐!

Forward

Redirect와의 차이점


요청이 하나(Forward)인지, 요청이 서로다른 2개(Redirect)인지 구분!

  • forward는 요청이 들어와서 서버가 내부적으로 다른놈(servlet2)한테 옮겨주었을 뿐이지 새로운 요청이 들어온것은 아니다!
  • 따라서 Client가 한번 요청했을 때 만들어졌던 요청 응답객체(request, response)가 그대로 유지될 것!
  • servlet1에서 처리한 결과를 servlet2에서도 사용해야 한다면 반드시 해당 결과를 request 객체에 저장해야함

<FrontServlet.java>

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            int diceValue = (int)(Math.random() * 6) + 1; 
            request.setAttribute("dice", diceValue); //여기가 핵심! => request 객체에 저장하기 위한 setAttribute
            
            RequestDispatcher requestDispatehcer = request.getRequestDispatcher("/next");
            requestDispatehcer.forward(request, response);
    }
  • request.setAttribute(“dice”, diceValue); 여기가 핵심! => request 객체에 저장하기 위한 setAttribute

<SecondServlet.java>

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head><title>form</title></head>");
        out.println("<body>");

        int dice = (Integer)request.getAttribute("dice"); //여기서 Attribute 가져옴
        out.println("dice : " + dice);
        for(int i = 0; i < dice; i++) {
            out.print("<br>hello");
        }
        out.println("</body>");
        out.println("</html>");
    }

Servlet과 JSP의 연동

  • Servlet은 프로그램 로직이 수행되기에 유리하다. IDE 등에서 지원을 좀 더 잘해준다.
  • JSP는 결과를 출력하기에 Servlet보다 유리하다. 필요한 html문을 그냥 입력하면 됨.
  • 프로그램 로직 수행은 Servlet에서, 결과 출력은 JSP에서 하는 것이 유리하다.
  • Servlet과 JSP의 장단점을 해결하기 위해서 Servlet에서 프로그램 로직이 수행되고, 그 결과를 JSP에게 포워딩하는 방법이 사용되게 되었다. 이를 Servlet과 JSP연동이라고 한다.

<LogicServlet.java>

  • doGet, doPost가 service() 메소드가 호출되면서 작동하기 떄문에 service메소드 하나면 충분
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int v1 = (int)(Math.random() * 100) + 1;
        int v2 = (int)(Math.random() * 100) + 1;
        int result = v1 + v2;
        
        request.setAttribute("v1", v1);
        request.setAttribute("v2", v2);
        request.setAttribute("result", result);
        
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/result.jsp");
        requestDispatcher.forward(request, response);
	}

<result.jsp>

<%
    int v1 = (int)request.getAttribute("v1");
    int v2 = (int)request.getAttribute("v2");
    int result = (int)request.getAttribute("result");
%>

<%=v1%> + <%=v2 %> = <%=result %>


WebProgrammingservletjsptomcat Share Tweet +1