지난 번 request 글에 이어지는 내용입니다. 이 글에서는 좀 더 상세하게 알아보기 위해서 fiddler 라는 툴을 사용해보겠습니다. request 와 response 내용은 브라우저에서 볼 수 없지만 이 도구를 이용해서 그 내용을 볼 수 있기 때문입니다. (닷넷프레임워크1.1이 설치되어야 동작합니다.)

fiddlertool 1.2 download
dotnetframework1.1 download

HTTP(HyperText Transfer Protocol HTML전송규약)의 형식에 따라서 서버와 브라우저간의 전송되는 내용을 보면서 작업을 하는 것은 웹 프로그래밍을 보다 더 정확하게 짤 수 있도록 도와줄 것입니다. 아, 툴은 Microsoft사에서 무료로 배포하고 있습니다.

설치를 마치고 나면 브라우저의 메뉴바에 생긴 Fiddler 아이콘을 볼 수 있습니다. 자동으로 프락시역할을 하면서 브라우저서 일어나는 모든 정보들을 들여다 볼 수 있도록 도와줍니다.

본론으로 돌아가서, 이번 글에서는 입력폼을 통해서 데이터를 처리하는 방법을 알아볼 것입니다. 브라우저를 통해서 데이터를 전달하는 방식에는 규약에 여러가지가 있지만 대표적으로 사용되는 방식이 "GET"과 "POST" 입니다.
get방식은 질의어를 보내서 데이터를 조회한다는 성격을 갖고 있고, post는 브라우저에서 서버쪽으로 데이터를 보내서 등록이나 갱신과 같이 서버에 변경을 가한다는 의미를 갖고 있습니다.
표면적으로 get방식의 데이터 전송은 브라우저 주소줄에 전송된 데이터가 표시됩니다. 북마크도 가능합니다. post방식은 요청(request)의 헤더부분에 보이지 않게 데이터가 전송됩니다. 브라우저에서는 post방식으로 전송된 데이터를 처리한 페이지에서 새로고침을 할 경우에 같은 데이터가 서버쪽으로 다시 전송된 것이라는 경고창을 띄워줍니다. 만료된 페이지라는 의미는 이와 같은 의미로 나오게 된 것입니다.

간단하게 로그인 하는 페이지를 만들어 보겠습니다.
id 와 password가 필요하겠죠. 일단 간단한 소스를 보시죠.
<소스 1> loginForm.jsp
<form name="loginForm" action="loginProcess.jsp" method="post">
  id: <input type="text" name="id">
  password: <input type="password" name="password">
  <input type="submit" name="submitButton" value="login">
</form>


form의 이름은 loginForm 으로 주었습니다. action은 폼 값을 전송해서 처리할 페이지주소를 정해줍니다. loginProcess.jsp 라는 파일이 필요하겠지요. 지난 번 글에서 본 대로 request를 이용하면 값을 가져올 수 있을 것입니다. method는 앞서 말한 데이터 전송 방식을 지정합니다. 생략하면 get방식으로 전달이 되는데, id와 password 가 주소줄에 노출되는 황당한 경우를 조심하시기 바랍니다. 이런 경우 post방식을 쓰는 것이 좋습니다. 물론 암호화 패킷을 보내는 SSL을 이용하는 방법이 최고의 방식이지만 지금부터 그걸 알아볼 필요는 없습니다.

입력 항목으로 input태그가 있습니다. type은 text로 지정을 했습니다. input태그의 이름은 id로 정했습니다. 다음 줄에 나오는 password 타입의 input은 말 그대로 암호스럽게 보여줍니다. 입력받는 문자에 대해서 * 이나 까만 동그라미 등으로 문자를 가려서 비밀번호가 노출도지 않도록 해줍니다. 그리고 브라우저 앞 뒤로 이동할 경우 password 타입의 input값은 비워지게 됩니다.

submitButton 이름을 가진 submit버튼은 말 그대로 제출용 버튼입니다. submit 버튼을 클릭하면 action에 지정된 페이지로 데이터를 전송하게 됩니다.

windows XP의 ie6 브라우저에서 본 모습입니다.

login form

login form


버튼을 클릭하면 받아서 데이터를 처리할 페이지를 만들어 보겠습니다.
<소스 2> loginProcess.jsp
<%
  String masterId       = "okadmin";
  String masterPassword = "okpass";
  String id       = request.getParameter("id");
  String password = request.getParameter("password");
  String message = ""; // 결과 메시지
  String script = "";  // 결과 후 실행할 javascript
  boolean isLogin = masterId.equals(id)
                     && masterPassword.equals(password);
  if (isLogin) {
       // 세션에 loginId의 키로 로그인한 id를 넣어둔다.
       session.setAttribute("loginId", id);
       message = "성공적으로 로그인되었습니다.";
       script = "document.location.replace('./loginForm.jsp')";
  } else {
       message = "로그인되지 않았습니다.";
       script = "history.back();";
  }
%><script type="text/javascript">
  // 결과 메시지를 javascript 경고창으로 표시
  alert('<%= message %>');
  <%= script %>
</script>

간략히 설명하면 서버에 있는 masterId와 masterPassword가 입력받은 id와 password와 같은지 확인 후 성공했다면 세션에 로그인 정보를 입력하고 성공 메시지를 보여주고, 실패한 경우 안내 메시지와 이전 페이지로 돌아가서 다시 로그인 하게 하는 프로그램입니다.

파라미터로 "id", "password" 키를 사용했습니다. <소스 1>의 input 태그에 있는 name 속성과 대소문자가 같은 키를 통해서 id 파라미터 값을 String변수 id 에 할당합니다. 마찬가지로 password 값도 할당합니다.

로그인 여부를 true 또는 false 값을 갖는 boolean 변수에 할당하고 이에 따라서 결과 메시지와 실행할 자바스크립트 명령을 각각 message와 script 에 넣었습니다. 페이지 제일 하단에 <script> 태그로 둘러 쌓인 영역은 브라우저에서 실행할 자바스크립트 코드들입니다.

중요한 것은 검은색 코드 부분은 서버에서 실행되는 것이고, 그 결과로 만들어진 파란색 부분은 클라이언트의 브라우저에서 해석되고 실행되는 것을 기억하셔야 됩니다. 웹 프로그래밍을 하면서 이 부분이 자칫 혼동을 일으키기 쉬운 개념입니다. 어느 곳에서 어떤 프로그램이 실행되는지 헷갈리면 javascript의 변수가 왜 jsp에서 못 읽는지 이해가 안 가는 상황에 봉착하게 됩니다. 요점은 jsp는 서버에서 실행되고, 그 결과 만들어진 html과 javascript는 클라이언트에서 실행된다는 것입니다.

alert()로 메시지를 브라우저에서 보여준 후에 실행되는 스크립트는 두 가지입니다.
성공했을 경우는 현재 post로 데이터를 받아서 처리하는 주소를 브라우저 history에서 대치(replace)하는 명령어입니다. document.location.replace("주소") 명령외에 document.location.href="주소"; 명령이 있는데, 차이점은 전자는 설명한대로 현재 자바스크립트가 실행하는 페이지의 브라우저 히스토리를 남기지 않고, 후자는 남겨놓는다는 것입니다.
실패했을 경우는 브라우저 뒤로(back) 버튼과 동일한 역할을 하는 history.back(); 명령을 실행합니다.

<소스1>은 다음과 같이 로그인 여부를 알 수 있도록 수정해보겠습니다.
<소스 1a> loginForm.jsp
<%
  // 세션에서 id를 가져옵니다.
  String loginId = (String)session.getAttribute("loginId");
  if (loginId != null) {
       out.println("loginId:"+loginId);
       return; // jsp 페이지의 실행을 종료합니다.
  }
%>
<form name="loginForm" action="loginProcess.jsp" method="post">
  id: <input type="text" name="id">
  password: <input type="password" name="password">
  <input type="submit" name="submitButton" value="login">
</form>


많이 길어졌네요. 주석을 친절하게 잘 달았기 때문에 설명하지 않아도 되겠죠. ^^;
한 가지 포인트, jsp 실행 중간에 멈추기를 원한다면 return;을 쓰면 됩니다. 원래 return은 메소드에서 결과값을 반환할 때 사용하는 것인데, 이전 글 JSP의 비밀에서 _JspService() 메소드를 기억하신다면 중간에 불쑥 나타난 return; 이 왜 종료하는지 이해가 갈 것입니다. 단 return;을 만나면 뒤에 있는 명령어들은 실행되지 않기 때문에 return; 뒤에 명령어가 있다면 컴파일 에러가 발생합니다. 조건문 안에 있거나 메소드의 맨 마지막에 위치해야 됩니다. 개발하면서 중간에 강제로 return을 쓰기 원하시면 if (true) return; 처럼 돌아가는 방법도 있습니다.

이제 맨 처음에 깔았던 fiddler를 실행하고 데이터 전달 모습을 확인해 보시기 바랍니다.
브라우저 툴바의 도구들을 보면 fiddler 아이콘이 보일 것입니다.
fiddler icon

fiddler icon


이어 나온 창에서 좌측에 보면 호출된 주소들이 보이고 우측에는 선택한 주소에 대한 자세한 정보들을 볼 수 있습니다.

입력 form에 로그인 정보를 입력하고 login 버튼을 클릭해봅니다.
alert 창이 떴을 때 한 줄이 추가된 것을 볼 수 있을 겁니다. 그 alert 창을 닫고 다음 페이지로 이동하면 또 한 줄 정보가 나옴을 알 수 있습니다.
loginProcess.jsp 라인을 선택하면 좌측에서 얻을 수 있는 정보들은 간략 정보입니다. 우측은 좌측 요청주소를 선택하면 그에 대한 응답시간, 내용, 헤더 정보들을 볼 수 있습니다.
header와 html의 비율을 보여주는 Chart 보기는 우측 하단의 파란 링크(Show Chart)를 클릭하면 보입니다.
fiddler data chart

fiddler data chart


우측 두번째 탭을 누르면 보낸 데이터에 대한 form 정보들을 볼 수 있습니다. get방식의 데이터는 = QUERYSTRING ==== 아래 나오고, post방식의 데이터는 = BODY ==== 아래 나옵니다.
fiddler data form

fiddler data form


독립 어플리케이션과 달리 서버와 클라이언트를 오가는 프로그램을 짤 때 이렇게 중간에서 전달되는 값들을 보면서 작업하는 것은 굉장히 유용합니다. 특히 flash나 ajax와 같이 페이지 변동없이 서버와 통신을 하면서 데이터를 주고 받을 때는 이러한 도구 없이 개발하는 것은 많은 시간을 낭비하게 됩니다.

지금까지 request 내장객체와 session 내장객체를 살짝 보았습니다. 다음 글에서는 java beans를 사용해서 데이터를 주고받는 방식을 알아보겠습니다.

+ Recent posts