GitHub

https://github.com/Backcoder-June

BackCoder 기록 그리고 숙달

Back to the Servlet

[Servlet] RequestDispatcher / set/getAttribute / sendReirect("url");

Backcoder 2022. 8. 8. 20:17

[ RequestDispatcher ]
: 요청 공유해서 처리하기

- HTTP 통신에서 [ 요청 - 응답 ] 이 많으면 서버에 무리를 줄 수 있다.

- 요청에 대한 처리 작업이 A 서블릿 코드도 거쳐야 하고, B 서블릿 코드도 거쳐야 한다면,
원래대로라면 A 에서도 http [ 요청 - 응답 ] 발생, B 에서도 http[ 요청- 응답 ]이 발생한다.

=> RequestDispatcher 를 사용해서 A 서블릿에서 받은 요청 정보B에 넘겨 공유할 수 있다.

- A 서블릿은 받아온 요청의 입력값을 ( req.getParameter ) 1차 처리 한다.
=> 1차 처리한 결과물을, RequestDispatcher을 이용해 B 서블릿한테 넘겨준다.
=> B 는 http 요청을 할 필요 없이,
서버에서 친구 A 서블릿으로부터, 바로 입력값을 받아서 처리하고 응답할 수 있다.

@WebServlet("/first")
public class firstServlet 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 writer = resp.getWriter();

        String id = req.getParameter("id");
        id = id.toUpperCase();
        
        req.setAttribute("upperid", id);
        RequestDispatcher rd = req.getRequestDispatcher("second");
        rd.forward(req, resp);



(1) req.setAttribute ( " key 값" , value );
- 담아서
(2) RequsetDispatcher rd = req.getRequestDispatcher( " 받을 서블릿 url " );
- 보낸다.
(3) rd.forward( req, resp );
- forward 방식으로.

@WebServlet("/second")
public class secondServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setContentType("text/html; charset=utf-8");
        req.setCharacterEncoding("utf-8");
        
        // getAttribute 는 Object 타입으로 반화함. 형변환 해서 받자
        String upperid = (String)req.getAttribute("upperid");
        resp.getWriter().println(upperid + "회원님 반갑습니다.");
    }
}


- url ("second") 로 날린걸 @WebServlet("/second") 가 받는다.

(1) Object upperid = req.getAttribute( " key 값 " );
- key 값으로 Attribute 꺼내온다.
(2) 리턴타입이 Object 디폴트 이므로, 적절히 형변환 해서 사용한다.


순서 : setAttribute, getRequestDispatcher 등 세팅을 다 하고 나서
=> rd.forward(req, resp) forward 실행
=> getAttribute 로 받아서 사용


- setAttribute 에는 데이터 타입 다 담을 수 있다. ( 객체 O )
- 현재 서버, 현재 컨텍스트 내부 파일로만 이동 가능하다. ( 친구끼리만 RequestDispatcher 사용 가능 )

- 특히 JSP 에서,
1.뷰단 JSP 따로,
2. 자바 비지니스 로직단 JSP 따로, 짜놓고
=> RequestDispatcherforward 시켜서 합쳐서 사용한다.




- forward : A 서블릿에서 B 서블릿으로 forward 방식으로 넘기면,
요청처리에 대한 "주도권"이 아예 B 서블릿으로 넘어간 것.


=> 웹클라이언트에 응답하는 주체도 B서블릿이 하는 것

( 클라이언트 입장에서는 A 서블릿 한테 요청한 것이다.
즉, URL 상 요청처음 요청을 받은 A 서블릿이 받는다.
서버안에서 자기들끼리 넘겨가면서, 마지막 응답은 B 서블릿이 해주는 것 )


- include : A 서블릿에서 B서블릿으로 주도권을 빌려줬다가
=> 다시 A 서블릿에게 주도권이 돌아오는 방식


-----------------------

[ response.sendRedirect( " url "); ]


@WebServlet( "/login" )
원래는 form action = "url" 을 서블릿에서 받았고,
원래 그 주소에다가 응답을 주는데,

doGet 메소드 안에

resp.sendRedirect("http://localhost:8090/webServlet_war/join.html");

이렇게 redirect 위치 지정해 두면
form action / WebServlet 에서 지정한 url 무시하고,
최종적으로 redirect 로 설정해둔 url로 보낸다.


( MVC @PostMapping 에서 return redirect:" url "; 과 같은 역할 )