포워딩

포워딩이란 원래 요청이 들어온 URI에서 다른 곳으로 이동시켜주는 것을 말한다.
서블릿에서 포워딩 방법은 크게 4가지가 있다.

  1. response객체의 sendRedirect
  2. response객체의 addHeader
  3. 브라우저 자바스크립트 기능을 이용한 location
  4. 서버에서 바로 이동시키는 dispatch

위에 1~3번 까지는 모두 최초요청 시 브라우저로 다시 돌아와서 재요청을 하는 것이다.
그렇기에 URL 정보가 바뀌게 된다.

하지만 4번의 경우에는 서버에서 바로 이동하기 때문에 브라우저에서 URL이 바뀌지 않는다.

FirstServlet - location

package sec01.ex03;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 자바스크립트 location 리다이렉트
 */
@WebServlet("/first")
public class FirstServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<script>");
        out.println("location.href='second'");
        out.println("</script>");
    }

}
  • first라는 URI요청을 받아 다시 second 서블릿으로 재요청한다.

SecondServlet

package sec01.ex03;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FirstServlet
 */
@WebServlet("/second")
public class SecondServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("location을 이용한 redirect 실습입니다.");
        out.println("</body></html>");
    }

}

요청 결과

  • 브라우저에서 재요청한 것이기에 브라우저 주소가 바뀌는 것을 알 수 있다.

FirstServlet - dispatch

package sec03.ex01;

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

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FirstServlet
 */
@WebServlet("/first")
public class FirstServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        RequestDispatcher dispatch = request.getRequestDispatcher("second?name=lee");
        dispatch.forward(request, response);

    }

}

SecondServlet

package sec03.ex01;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * disaptch 리다이렉트
 */
@WebServlet("/second")
public class SecondServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        String name = request.getParameter("name");

        out.println("<html><body>");
        out.println("이름: " + name + "<br>");
        out.println("dispatch 을 이용한 redirect 실습입니다.");        
        out.println("</body></html>");
    }

}

  • 서버에서 브라우저로 오지 않고 바로 실행 되었기에 URL주소가 바뀌지 않았다.

바인딩

바인딩이란 데이터의 묶음을 의미한다. 하나 이상의 데이터들을 전달할 때 하나로 묶어서 전달하는 기법을 말한다.

바인딩 기법 - 브라우저

package sec04.ex01;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/first")
public class FirstServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        request.setAttribute("adress", "서울시 동작구");
        response.sendRedirect("second");
    }

}
  • 브라우저에 의한 서블릿 재요청
package sec04.ex01;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FirstServlet
 */
@WebServlet("/second")
public class SecondServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        String adress = (String)request.getAttribute("adress");
        System.out.println("adress=" + adress);

        out.println("<html><body>");
        out.println("주소:" + adress + "<br>");
        out.println("</body></html>");
    }

}

  • 데이터가 없다고 나옴.

바인딩 기법 - 서버

package sec04.ex02;

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

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/first")
public class FirstServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        request.setAttribute("adress", "서울시 동작구");        
        RequestDispatcher dispatch = request.getRequestDispatcher("second");
        dispatch.forward(request, response);


    }

}
  • dispatch로 서버에서 바로 전달.
package sec04.ex02;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FirstServlet
 */
@WebServlet("/second")
public class SecondServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        String adress = (String)request.getAttribute("adress");
        System.out.println("adress=" + adress);

        out.println("<html><body>");
        out.println("주소:" + adress + "<br>");
        out.println("</body></html>");
    }

}

  • 정상적으로 출력.
  • 서버에서만 데이터 바인딩이 가능하다.
  • 단순한 요청은 브라우저를 통해서 가능하지만, DB 정보를 조회하거나 보안에 관련된 사항들은 dispatch를 이용하는 것이 바람직하다.

회원정보 바인딩하기

앞서 서버에서 바로 데이터를 넘겨줄 때는 dispatch를 이용한다고 하였다. DB에 있는 정보를 조회해 화면으로 데이터를 바인딩 시켜보자.

MemberSerlvet

package sec04.ex03;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/member")
public class MemberServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doHandle(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doHandle(request, response);
    }

    private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        MemberDAO dao = new MemberDAO();        
        List memberList = dao.listMembers();

        request.setAttribute("membersList", memberList);
        RequestDispatcher dispatch = request.getRequestDispatcher("viewMembers");
        dispatch.forward(request, response);

    }

}
  • 서블릿 요청이 들어오면 DAO 객체를 생성해 회원정보를 조회해 setAttribute 의 "membersList" 객체에 담아 dispatch를 활용해 viewMembers로 서블릿을 요청한다.

ViewServlet

package sec04.ex03;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/viewMembers")
public class ViewServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          request.setCharacterEncoding("utf-8");        
          response.setContentType("text/html;charset=utf-8");
          PrintWriter out = response.getWriter();    

          List membersList = (List) request.getAttribute("membersList");

          out.print("<html><body>");
          out.print("<table border=1><tr align='center' bgcolor='lightgreen'>");
          out.print("<td>아이디</td><td>비밀번호</td><td>이름</td><td>이메일</td><td>가입일</td><td >삭제</td></tr>");

          for(int i=0; i < membersList.size(); i++) {
              MemberVO memberVO = (MemberVO) membersList.get(i);
              String id = memberVO.getId();
              String pwd = memberVO.getPwd();
              String name = memberVO.getName();
              String email = memberVO.getEmail();
              Date joinDate = memberVO.getJoinDate();
              out.print("<tr><td>" + id + "</td><td>" + pwd + "</td><td>" + name + "</td><td>" + email + "</td><td>"
                    + joinDate + "</td><td>" + "<a href='/pro07/member3?command=delMember&id=" + id
                    + "'>삭제 </a></td></tr>");              
          }

          out.print("</table></body></html>");
          out.print("<a href='/pro07/memberForm.html'>새 회원 등록하기</a");        
    }

}
  • MemberServlet에서 넘어온 리스트를 받아서 회원정보를 출력해준다.

ServletContext 와 ServeletConfig

ServletContext

  • 전역 객체
  • 톰캣 컨테이너 실행 시 하나의 컨텍스트가 생성되고 컨테이너 종료시 소멸.
  • 어플리케이션 전체 공동 자원

ServletContext 객체 사용하기

package sec05.ex01;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/cset")
public class SetServletContext extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();        
        ServletContext context = getServletContext(); // 서블릿 컨테이너 생성.

        List member = new ArrayList();
        member.add("이순신");
        member.add(30);
        context.setAttribute("member", member);
        out.print("<html><body>");
        out.print("이순신과 30 설정");
        out.print("</body></html>");

    }
}
  • 컨텍스트 객체에 List 셋팅.

 

package sec05.ex01;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/cget")
public class GetServletContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();        
        ServletContext context = getServletContext(); // 서블릿 컨테이너 생성.

        List member = (List) context.getAttribute("member");
        String name = (String)member.get(0); // 이순신
        int age = (Integer)member.get(1); // 30

        out.print("<html><body>");
        out.print(name + "<br>");
        out.print(age + "<br>");
        out.print("</body></html>");

    }
}
  • 컨텍스트에 저장된 데이터 불러오기.

 

테스트

web.xml 에서 파라미터 설정

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <context-param>
      <param-name>menu_member</param-name>
      <param-value>회원등록 회원조회 회원수정</param-value>
  </context-param>

  <context-param>
      <param-name>menu_order</param-name>
      <param-value>주문조회 주문등록 주문수정 주문취소</param-value>
  </context-param>

  <context-param>
      <param-name>menu_goods</param-name>
      <param-value>상품조회 상품등록 상품수정 상품삭제</param-value>
  </context-param>    

  <display-name>pro08</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>
  • context-param 테그안에 컨텍스트 생성 시 초기화할 파라미터를 설정한다.

 

ContextParamServlet

package sec05.ex02;

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.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/initMenu")
public class ContextParamServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        ServletContext context = getServletContext(); // web.xml 에 <context-param> 에 있는 변수를 가져옴.

        String menu_member = context.getInitParameter("menu_member");
        String menu_order = context.getInitParameter("menu_order");
        String menu_goods = context.getInitParameter("menu_goods");

        out.print("<html><body>");
        out.print("<table border=1 cellspacing=0><tr>메뉴 이름</tr>");
        out.print("<tr><td>" + menu_member + "</td></tr>");
        out.print("<tr><td>" + menu_order + "</td></tr>");
        out.print("<tr><td>" + menu_goods + "</td></tr>");
        out.print("</tr></table></body></html>");            

    }
}
  • web.xml 에서 서블릿 컨텍스트의 초기 파라미터를 설정하였으므로, 바로 컨텍스트에 접근하여 값을 가져올 수 있다.

외부파일을 파라미터로 사용하기

외부텍스트 파일에서 값을 읽어와 출력하기.

WEB-INF/bin/init.txt 추가

package sec05.ex03;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/cfile")
public class ContextFileServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=euc-kr");
		PrintWriter out = response.getWriter();
		
		ServletContext context = getServletContext();
		InputStream is = context.getResourceAsStream("/WEB-INF/bin/init.txt");
		BufferedReader buffer = new BufferedReader(new InputStreamReader(is));
		
		String menu = null;
		String menu_member = null;
		String menu_order = null;
		String menu_goods = null;
		
		while((menu=buffer.readLine()) != null) {
			StringTokenizer tokens = new StringTokenizer(menu, ",");
			menu_member = tokens.nextToken();
			menu_order = tokens.nextToken();
			menu_goods = tokens.nextToken();			
		}
		
		out.print("<html><body>");
		out.print(menu_member + "<br>");
		out.print(menu_order + "<br>");
		out.print(menu_goods + "<br>");
		out.print("</body></html>");
		out.close();
		
		
	}
}

- 외부파일을 스트림으로 읽어와 html 로 출력하였음.

출력결과

 

출처: 자바 웹을 다루는 기술

블로그 이미지

파니동

,