WAS의 서블릿이나 JSP가 요청을 받은 후 그 요청을 처리하다가, 추가적인 처리를 같은 웹 어플리케이션 안에 포함된 다른 서블릿이나 JSP에게 위임하는 경우가 있습니다. 이렇게 위임하는 것을 포워드 forward 라고 합니다. 이번 시간에는 포워드에 대해서 좀 더 자세히 알아보도록 하겠습니다.
forward 란?
Servlet 1 이 클라이언트로부터 요청을 받았는데, 이 작업을 혼자서 모두 수행하지 않고 Servlet 2로 넘겨주는 것을 forward 라고 합니다. 그리고 위임받은 Servlet 2 는 응답을 만들어서 응답을 보내주는데요. 이러한 과정을 forward 라고 합니다. 포워드랑 리다이렉트를 헷갈려하시는 분들이 많습니다. 정확하게 이해하고 넘어가야 뒤에 헷갈리는 일을 방지할 수 있습니다. 리다이렉트는 클라이언트가 서버에게 요청을 보낸 이후 서버가 일을 처리하고 클라이언트에게 새로운 작업을 요청하라고 응답을 보내는 것이 리다이렉트입니다. 리다이렉트의 결과는 실행을 한 이후에 첫 실행 URL에서 출력 URL이 바뀌게 된다는 것도 확인했었습니다. 포워드는 클라이언트가 요청을 보낸 이후 서버 쪽에서 요청에 대해서 혼자 처리하는 것이 아니라 다른 부분에 처리를 맞기는 것을 포워드라고 하는데, 이때 클라이언트는 요청한 Servlet 이 혼자서 작업을 처리했는지 혹은 다른 Servlet 이 처리를 도왔는지 알 방법이 없고 알 필요도 없습니다. 따라서 클라이언트의 URL이 바뀌지 않습니다. 이 차이점이 중요한 이유는우선실제 클라이언트가 서버에게 요청을 하면 반드시 생성되는 객체가 2가지가 있다고 했었습니다. request 와 response 객체였습니다. 이런 특성에 착안하였을 때 Forward 는 response 와 request 가 한번 생성됩니다. 하지만 반대로 redirect 는 request 와 response 가 최소 두 번씩 생성됩니다.
forward 실습
Front Servlet 과 NextServlet 을 작성하여 forward 를 구현하여 보겠습니다. 기본적으로 FrontServlet 에서는 랜덤한 주사위 값을 구하고, 그 값을 NextServlet 에게 Forward 해주고 NextServlet 에서는 FrontServlet 으로부터 전달 받은 주사위 값만큼 "hello"를 출력하겠습니다. 우선 기본적으로 Math.randon( ) 함수를 사용하여 주사위 정수 값을 무작위로 생성하여 diceValue에 저장합니다. 그 다음 diceValue 를 NextServlet 에게 전달해줘야 하는데, NextServlet 도 기본적으로 서블릿이기 때문에 동작을 할 때는 request 객체의 정보를 받아서 response 객체를 반환하는 작업을 수행합니다. 즉, 우리가 FrontServlet 에서 생성한 diceValue 라는 변수의 값을 NextServlet 의 request 객체에 담아주어야 합니다. 이런 일을 수행하는 함수가 request.setAttribute( , ) 함수입니다. 이 코드는 세탁소를 생각하면 이해하기가 쉽습니다. 세탁소에 옷을 맡길 때 이름 혹은 주소를 맞기는데요. 바로 그 값이 request.setAttribute 라고 이해하면 됩니다. 여기에 저장한 값은 다시 값을 찾아갈 때 기준 값이 된다고 생각하면 되겠습니다. 즉, FrontServlet 에서 A 라고 setAttribute 로 저장했다면, NextServlet 에서 똑같이 A 라는 값을 찾아갈 수 있다는 것이죠. 이렇게 값을 저장했다면 실제로 forward 를 수행하는 코드를 작성해야 합니다. 앞선 강의에서 redirect 를 수행할 때 response.redirect( ) 를 사용했던 것처럼 말이죠. 실제로 forward( ) 라는 메서드는 RequestDispatcher 라는 객체가 가지고 있습니다. forward 는 같은 어플리케이션 내에서만 가능하다. (다른 웹서버는 불가능). forward 를 수행하는 객체는 RequestDispatcher 인데, request 객체의 getRequestDispatcher 메서드를 사용하여 생성한다. getRequestDispatcher 메서드는 이동할 경로를 인자로 가져간다. 인자는 / 로 시작한다. RequestDispatcher 객체를 생성했다면, 해당 객체가 가지고 있는 forward( ) 메서드를 사용하면 된다.forward( ) 메서드는 request 와 response 를 인자로 갖는다. NextServlet 에서는 FrontServlet 에서 맞긴 값을 꺼내서 써야 한다. 역시나 서블릿은 request 와 response 라는 객체를 중심으로 돌아간다는 것에 초점을맞추어 본다면, 값도 request 의 담겨서 올 것이라는 것을 생각할 수 있다. request.getAttribute( ) 코드를 통해서 FrontServlet 에서 request.setAttribute( ) 코드를 통해서 담아 주었던 값에 접근할 수 있다. 다만 여기서 반환되는 값의 형태는 Object 이기 때문에 우리가 원하는 값 형태로 강제 형 변환 시켜서 사용해야 한다. 이렇게 값이 반환되는 이유는 setAttribute 메서드에서 두 번째 인자가 Object 형을 받기 때문에 그렇다. Object 형이어야 어떤 값이든 받을 수 있기 때문에 이렇게 설정되어 있다. 실제로 FrontServlet 을 실행시켜보았습니다. 우선 눈여겨 볼 점은 URL 주소인데요. URL 주소가 redirect 와는 다르게 변경되지 않은 것을 확인할 수 있습니다. 그리고 새로고침할 때마다 dice 의 숫자가 바뀌는 것을 확인할 수 있습니다. 동작하는 과정을 확인해보겠습니다. FrontServlet 에서는 random 함수를 실행하여 diceValue 에 값을 대입한 다음 request 객체에 setAttribute 메서드로 값을 담았습니다. 그리고 RequestDispatcher 객체를 생성한 다음 forward 메서드를 실행시켜 forward 가 구동하도록 설정하였습니다. 이후 NextServlet 은 request.getAttribute( ) 메서드를 통해서 담겨진 값을 꺼낸 다음 사용하여 화면을 구현하였습니다.