728x90

JSP를 이용하여 프로그램할 경우 특정작업을 완료한 후 다음 페이지로 이동할 때 흔히 HttpServletResponse의 sendRedirect()를 이용한다.
HttpServletResponse의 sendRedirect()는 두번의 Request를 통해 하나의 작업을 완료하는 방식이다. 즉, 첫번째 요청이 서버에서 처리된 다음 서버는 이동할 다음 페이지의 경로를 클라이언트에서 응답하면 클라이언트의 브라우저는 서버에게 새로운 페이지를 다시 요청하여 이동하는 방식이다. 이와 같이 할 경우 두번의 네크워크 Traffic이 발생하기 때문에 실행속도에 늦어질 수 밖에 없다. 또한 새로운 요청을 하기 때문에 요청하는 페이지에 객체를 전달하기 힘들다는 문제점이 있다.
이 같은 문제점을 해결하기 위하여 RequestDispatcher가 탄생하게 되었다. RequestDispatcher는 일련의 작업이 완료된 후 다음페이지로 이동할 경우 클라이언트에 응답을 한 후 다시 요청하도록 하는 방식이 아니라 서버에서 서버로 페이지를 요청하여 실행한 후 응답을 하도록 한다. 이럴 경우 네트워크 Traffic이 한번 발생하게 되며, 서버에서 서버로 페이지를 요청하기 때문에 String만이 아닌 객체의 전달도 가능하다.

RequestDispatcher를 이용할 경우 한번의 요청으로 인해 모든 작업이 서버에서 처리되기 때문에 실행속도는 Response의 sendRedirect를 사용할 때보다 빠르다. 또한 Response의 sendRedirect을 이용할 경우에는 String밖에 전달 할 수 없다. 즉, 객체를 다른 페이지에 전달하는 것이 힘들다. 물론 세션을 이용하면 가능하지만 세션 또한 시스템의 메모리를 차지하기 때문에 매번 세션을 이용하는 것은 좋은 방법은 아니다.
이에 대한 대안으로 RequestDispatcher를 이용하면 된다. RequestDispatcher를 이용하면 서버에서 모든 작업이 처리되기 때문에 서버상에서의 객체의 전달이 가능하다. 하지만 RequestDispatcher를 이용할 경우 문제점이 있다. RequestDispatcher를 이용할 경우 응답이 이루어진 후의 URL이 처음 클라이언트가 요청한 URL로 지정되어 있기 때문에 문제가 되는 경우가 있다.
한가지 예로 사용자의 정보를 가져오거나 사용자의 정보를 볼 경우에는 문제가 되지 않는다. 하지만 사용자가 회원가입을 할 경우 똑같은 정보가 같은 페이지에 요청되기 때문에 같은 정보가 저장되는 경우가 있다.
개발자들이 게시판을 이용할 때 요청속도가 느려 Refresh를 계속해서 누를 경우 똑같은 글이 계속해서 저장되는 것을 경험한 적이 있을 것이다. RequestDispatcher를 이용할 경우에는 같은 문제가 발생하는 경우가 많다.

RequestDispatcher의 문제점을 해결하기 위해서 스트러츠에서는 해결점을 제공하고 있다. Action클래스의 saveToken()과 resetToken()을 이용하여 요청(Request)이 한번만 실행할 수 있도록 지원하고 있다. 간단하게 요약하면 saveToken()을 이용하여 요청이 실행될 때 하나의 Token을 생성한다. 만약 앞에서 생성한 똑같은 Token의 요청이 실행되면 스트러츠에서는 에러를 발생시켜 요청이 실행되지 않도록 한다.

<code>
요청이 한번 들어오면 요청에 해당하는 고유아이디를 만들어서 request의 session에 저장합니다. 만약 다음 요청이 이전에 전달한 고유 아이디와 같은지를 판단한 다음 만약 같다면 에러를 발생시켜야 합니다.
isTokenValid() 메써드가 이같은 역할을 합니다. 즉, 현재 요청하고 있는 token 이전 token과 같은지를 판단하는 겁니다.
만약 같다면 false, 틀리다면 true를 반환하게 됩니다.
if (!isTokenValid(request)) {
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.transaction.token"));
}
만약 유효한 요청이라면 그 다음으로 request에 저장되어 있는 token을 삭제합니다. 그 메써드가 resetToken() 입니다.
resetToken(request);
마지막으로 에러가 없다면 새로운 token을 생성하여 request객체어 다시 저장하게 되는 겁니다.
if (!errors.isEmpty()) {
saveErrors(request, errors);
saveToken(request);
return (mapping.getInputForward());
}
728x90

'JAVA' 카테고리의 다른 글

jsmooth - jar파일로 exe파일 생성  (0) 2012.07.29
JAVA에서 post로 url에 데이터 넘기기  (0) 2012.07.29
IBATIS 연산요소  (0) 2012.07.29
jstl 문자열 자르기  (0) 2012.07.29
SQLMaps를 이용한 객체-관계 맵핑  (0) 2012.07.29

+ Recent posts