오봉이와 함께하는 개발 블로그

Servlet - 포워딩 본문

BE/Servlet

Servlet - 포워딩

오봉봉이 2021. 12. 29. 13:07
728x90

서블릿 포워드

  • 서블릿에서 다른 서블릿이나 JSP, 웹 브라우저로 요청을 전달하는 기능
  • 요청에 대한 추가 작업을 다른 서블릿에게 수행하게 하는 역할
  • 요청에 포함된 정보를 다른 서블릿이나 JSP와 공유
  • 요청에 정보를 포함시켜서 다른 서블릿에 전달
  • 모델2 개발 시 서블릿에서 JSP로 데이터 전달하는데 사용

서블릿 포워드 방법

  1. redirect
    • HttpServletResponse 객체의 sendRedirect() 메소드 사용
    • 웹 브라우저에게 재요청하는 방식
    • 형식 : sendRedirect(“포워드할 서블릿 또는 JSP”);
  2. Refresh
    • HttpServletResponse 객체의 addHeader() 메소드 사용
    • 웹 브라우저에게 재요청하는 방식
    • 형식 : response.addHeader("Refresh", 경과시간(초);url=요청할 서블릿 또는 JSP0)
  3. location
    • 자바스크립트 location 객체의 href 속성 이용
    • 자바스크립트에서 재요청하는 방식
    • 형식 : location.href = "요청할 서블릿 또는 JSP";
  4. dispatch
    • 일반적으로 포워딩 기능 지칭
    • 서블릿이 직접 요청하는 방식
    • 내용은 출력 되지만 URL이 바뀌지 않음
    • RequestDispatcher 클래스의 forward() 메소드 사용
    • 형식
      • RequestDispatcher dis = request.getRequestDispatcher("포워드할 서블릿 또는 JSP");
      • dis.forward(request, response);
  • redirect, refresh, location
    • 서블릿이 웹 브라우저를 거쳐 다른 서블릿이나 JSP에게 요청하는 방법
  • dispatch
    • 클라이언트 거치지 않고 서블릿에서 바로 다른 서블릿에게 요청하는 방법

redirect 이용한 포워딩(GET 방식 : URL 사용한 포워딩) - FirstServlet01.java, SecondServlet01.java

package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/sec08/first01")
public class FirstServlet01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        response.sendRedirect("second01");
    }
}
package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/sec08/second01")
public class SecondServlet01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("<html><body>");
        out.print("sendRedirect를 이용한 redirect 포워딩");
        out.println("</body></html>");
    }
}

refresh 이용한 포워딩(GET 방식 : URL 사용한 포워딩) - FirstServlet02.java, SecondServlet02.java

package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/sec08/first02")
public class FirstServlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.addHeader("Refresh", "2;url=second02");
        // response.addHeader("Refresh", "시간(초);url=매핑이름");
    }
}
package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/sec08/second02")
public class SecondServlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("<html><body>");
        out.print("refresh를 이용한 포워딩");
        out.println("</body></html>");
    }
}

location 이용한 포워딩(GET 방식 : URL 사용한 포워딩) - FirstServlet03.java, SecondServlet03.java

package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/sec08/first03")
public class FirstServlet03 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    // location을 이용한 포워딩
    // 자바스크립트의 location 객체 사용
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.print("<script type='text/javascript'>");
        out.print("location.href='second03';");
        out.println("</script>");
    }
}
package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/sec08/second03")
public class SecondServlet03 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("<html><body>");
        out.print("location을 이용한 포워딩");
        out.println("</body></html>");
    }
}

포워딩 하면서 데이터 전달(redirect 이용)(GET 방식 : URL 사용한 포워딩) - FirstServlet04.java, SecondServlet04.java

package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/sec08/first04")
public class FirstServlet04 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendRedirect("second04?name=hong");
    }
}
package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/sec08/second04")
public class SecondServlet04 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        // url 뒤에 붙어서 전송된 데이터 받기
        String name = request.getParameter("name");
        out.print("<html><body>");
        out.print("redirect 이용한 포워딩으로 데이터 전달 받기<br>");
        out.print("이름 : " + name);
        out.println("</body></html>");
    }
}

dispatch 이용한 포워딩(GET 방식 : URL 사용한 포워딩) - FirstServlet05.java, SecondServlet05.java

package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/sec08/first05")
public class FirstServlet05 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        RequestDispatcher dispatcher = request.getRequestDispatcher("second05?name=lee");
        dispatcher.forward(request, response);
    }
}
package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/sec08/second05")
public class SecondServlet05 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        // url 뒤에 붙어서 전송된 데이터 받기
        String name = request.getParameter("name");
        out.print("<html><body>");
        out.print("dispatcher 이용한 포워딩으로 데이터 전달 받기<br>");
        out.print("이름 : " + name);
        out.println("</body></html>");
    }
}

GET 방식으로 데이터 전달 시 문제

  • 대량의 데이터를 전달할 때 GET방식의 문제
    • 길이 제한, 안전성, 불편 등
  • 바이딩(binding) 기능 사용으로 해결
    • 웹 프로그래밍 실행 시 자원(데이터)을 서블릿 객체에 저장하는 방법 사용
    • 저장된 데이터는 서블릿이나 JSP에서 공유
    • 방법
      • 포워딩할 때 setAttribute(“바인딩이름”, 데이터) 메소드 사용해서 바인딩이름과 데이터를 묶어서 설정한 후 포워딩된 문서에서 getAttribute("바인딩 이름") 메소드를 이용해서 바인딩된 데이터를 추출해서 사용
    • redirect 방식으로는 서블릿에서 바인딩한 데이터를 다른 서블릿으로 전송할 수 없다.
      • dispatch 포워딩 방법일 경우에만 바인딩 가능

redirect 방식을 통한 바인딩 예제(바인딩 안되는 예시) - FirstServlet06.java, SecondServlet06.java

package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

// sendRedirect() 사용해서 바인딩
@WebServlet("/sec08/first06")
public class FirstServlet06 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        request.setAttribute("address", "서울시 강남구");
        response.sendRedirect("second06");
    }
}
package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/sec08/second06")
public class SecondServlet06 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    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();
        // url 뒤에 붙어서 전송된 데이터 받기
        String address = (String)request.getAttribute("address");
        out.print("<html><body>");
        out.print("redirect 이용한 바인딩<br>");
        out.print("주소 : " + address);
        out.println("</body></html>");
//        redirect 이용한 바인딩
//        주소 : null
    }
}

dispatch 방식을 통한 바인딩 예제 - FirstServlet07.java, SecondServlet07.java

package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/sec08/first07")
public class FirstServlet07 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        request.setAttribute("address", "서울시 강남구");
        request.setAttribute("name", "홍길동");
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("second07");
        requestDispatcher.forward(request, response);
    }
}
package com.example.servlet4.sec08;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/sec08/second07")
public class SecondServlet07 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    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();
        // url 뒤에 붙어서 전송된 데이터 받기
        String address = (String)request.getAttribute("address");
        String name = (String)request.getAttribute("name");
        out.print("<html><body>");
        out.print("dispatch 이용한 바인딩<br>");
        out.print("주소 : " + address + "<br>");
        out.print("이름 : " + name);
        out.println("</body></html>");
//        URL 변경 없음
//        http://localhost:8080/sec08/first07
    }
}

데이터베이스의 회원 정보를 ArrayList객체에 저장 후 바인딩 - MemberVO.java, MemberDAO.java, MemberBindingServlet.java, MemberViewServlet.java

package com.example.servlet4.sec09;

import java.util.Date;

public class MemberVO {
    private String id;
    private String pwd;
    private String name;
    private String email;
    private Date joinDate;

    // 디폴트 생성자
    public MemberVO() { }
    // 현재는 매개변수 있는 생성자 필요 없다.
    public MemberVO(String id, String pwd, String name, String email, Date joinDate) {
        this.id = id;
        this.pwd = pwd;
        this.name = name;
        this.email = email;
        this.joinDate = joinDate;
    }

    public MemberVO(String id, String pwd, String name, String email) {
        this.id = id;
        this.pwd = pwd;
        this.name = name;
        this.email = email;
    }

    // Getter / Setter
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPwd() {return pwd;}

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getJoinDate() {
        return joinDate;
    }

    public void setJoinDate(Date joinDate) {
        this.joinDate = joinDate;
    }
}
package com.example.servlet4.sec09;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;

public class MemberDAO {
    private Connection con = null;
    DataSource dataSource = null;
    // 생성자에서 DB연결 설정
    public MemberDAO() {
        try {
            Context init = new InitialContext();
            dataSource = (DataSource)init.lookup("java:comp/env/jdbc/mysql");
            System.out.println("연결 성공");
        } catch (Exception e) {
            System.out.println("연결 실패");
            e.printStackTrace();
        }
    }

    // 회원 정보 조회 메소드(전체 회원 정보 select : MemberVO 반환)
    // MemberVO를여러 행 반환 : ArrayList<MemberVO>
    public ArrayList<MemberVO> memberSelect() {
        Connection con = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        ArrayList<MemberVO> memList = new ArrayList<MemberVO>();

        try {
            con = dataSource.getConnection();
            String query = "select * from member";
            preparedStatement = con.prepareStatement(query);
            resultSet = preparedStatement.executeQuery(query);

            while(resultSet.next()) { // 결과 세트에서 한 행씩 처리
                // 한 행(회원 1명당) 처리
                String id = resultSet.getString("memId");
                String pwd = resultSet.getString("memPwd");
                String name = resultSet.getString("memName");
                String email = resultSet.getString("memEmail");
                Date joinDate = resultSet.getDate("memJoinDate");
                // 한 행 정보 가져와 memberVO에 Setter 이용하여 저장
                MemberVO vo = new MemberVO();
                vo.setId(id);
                vo.setPwd(pwd);
                vo.setName(name);
                vo.setEmail(email);
                vo.setJoinDate(joinDate);
                // 각 memberVO를 ArrayList에 저장
                memList.add(vo);
            }
            System.out.println("회원 조회 성공");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("회원 조회 실패");
        } finally {
            try {
                resultSet.close();
                preparedStatement.close();
                con.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return  memList;
    }
    // 회원 정보 등록하는 메소드
    public void memberInsert(MemberVO memberVO) {
        try {
            con = dataSource.getConnection();

            String sql = "insert into member values(?, ?, ?, ?, default)";
            PreparedStatement preparedStatement = con.prepareStatement(sql);

            preparedStatement.setString(1, memberVO.getId());
            preparedStatement.setString(2, memberVO.getPwd());
            preparedStatement.setString(3, memberVO.getName());
            preparedStatement.setString(4, memberVO.getEmail());
            int result = preparedStatement.executeUpdate();
            if (result > 0) {
                System.out.println("회원 정보 입력 성공");
            }
            preparedStatement.close();
            con.close();
        } catch (Exception e) {
            System.out.println("insert 오류 발생!");
            e.printStackTrace();
        }
    }

    // 회원 정보 삭제 메소드
    public void memberDelete(String id ) {

        try {
            con = dataSource.getConnection();

            String sql = "delete from member where memId=?";
            PreparedStatement preparedStatement = con.prepareStatement(sql);

            preparedStatement.setString(1, id);
            // 쿼리문 실행 : 영향을 받은 행의 수 반환
            //select : executeQuery - 결과 행 resultSet 반환.
            //insert / update / delete : executeUpdate() - 영향을 받은 행의 수 반환
            int result = preparedStatement.executeUpdate();

            if(result > 0) {
                System.out.println("회원 정보 삭제 성공!");
            }
            // 모든 객체 close() : 리소스 반납
            preparedStatement.close();
            con.close();
        } catch (Exception e) {
            System.out.println("delete 발생!");
            e.printStackTrace();
        }
    }
}
package com.example.servlet4.sec09;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.ArrayList;

@WebServlet("/sec09/memBinding")
public class MemberBindingServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doProcess(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doProcess(request, response);
    }
    protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        MemberDAO dao = new MemberDAO();
        ArrayList<MemberVO> memList = dao.memberSelect();

        request.setAttribute("memList", memList); // name, data
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("memView");
        requestDispatcher.forward(request, response);
    }
}
package com.example.servlet4.sec09;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@WebServlet("/sec09/memView")
public class MemberViewServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doProcess(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doProcess(request, response);
    }
    protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        // 서버에서 클라이언트로 데이터 전송에 자바 IO스트림 이용
        PrintWriter out = response.getWriter();
//      비즈니스 로직 처리 : 바인딩 된 값 추출
        List memList = (List)request.getAttribute("memList");
//        ArrayList<MemberVO> memList = (ArrayList<MemberVO>)request.getAttribute("memList");
        out.print("<html><head></head><body>");
        out.print("<table border=1><tr align='center' bgcolor='gold'>");
        out.print("<td>아이디</td><td>비밀번호</td><td>이름</td><td>이메일</td>" +
                "<td>가입일</td><td>삭제</td></tr>");
        for(int i = 0; i < memList.size(); i++) {
            // 오브젝트 반환 MemberVO 타입으로 형변환
            MemberVO vo = (MemberVO)memList.get(i);
            String id = vo.getId();
            String pwd = vo.getPwd();
            String name = vo.getName();
            String email = vo.getEmail();
            Date joinDate = vo.getJoinDate();
            // 한 행씩 출력
            out.print("<tr><td>" + id + "</td><td>" +
                    pwd + "</td><td>" +
                    name + "</td><td>" +
                    email + "</td><td>" +
                    joinDate + "</td><td>" +
                    "<a href='/MemberDeleteServlet?id=" + id + "'>삭제</a></td></tr>");
        }
        out.print("</table></body></head>");
    }
}
728x90
Comments