Collapse AllExpand All

4.3. JSP 개발 - sample0.jsp

먼저 위에서 생성한 sample0.html을 JSP (sample0.jsp)로 고치고 검색 결과를 구하는 비즈니스 로직을 추가해본다.

sample0.jsp

1.	<%@ page import="com.konantech.ksf.client.CrzClient,
2.	                 com.konantech.ksf.client.SearchQuery,
3.	                 com.konantech.ksf.client.QueryBuilder,
4.	                 com.konantech.ksf.client.result.SearchResultSet,
5.	                 com.konantech.ksf.web.RequestUtils"
6.	%>
7.	<%@ page language="java" contentType="text/html; charset=UTF-8" 
       pageEncoding="UTF-8" %>
8.	<%  
   // 브라우저로부터 전달 받은 파라미터 query의 값을 구한다.
9.	  String query = RequestUtils.getParameter(request, "query");
  // 파라미터 query가 존재할 경우 아래의 검색 로직을 수행한다.
10.	  if (query != null) {
11.	    pageContext.setAttribute("query", query);
   // 호스트 127.0.0.1에서 포트 번호 9577로 서비스하는 검색 엔진에 
   // 연결할 클라이언트를 생성한다. 실제 적용 시에는 검색 엔진의 
   // IP 주소와 포트 번호로 교체해야 한다.
12.	    CrzClient crzclient = new CrzClient("127.0.0.1", 9577);
   // 시나리오 sample에 query를 검색어로 하는 검색 쿼리 객체를 생성한다.
13.	    SearchQuery sq = new SearchQuery("sample", query);
   // 검색 조건을 설정한다. (where text_idx=’query’ allwordthruindex)
14.	    sq.setWhereClause("text_idx='" + QueryBuilder.escapeQuery(query) + "' allwordthruindex");
   // 검색을 수행하고
15.	    SearchResultSet srs = crzclient.search(sq);
   // 검색 조건을 페이지 컨텍스트에 sq 라는 애트리뷰트로 저장한다.
16.	    pageContext.setAttribute("sq", sq);
  // 검색 결과를 페이지 컨텍스트에 srs라는 애트리뷰트로 저장한다.
17.	    pageContext.setAttribute("srs", srs);
18.	  }
19.	%>
20.	<!DOCTYPE html>
21.	<html>
22.	…
23.	</html>

9라인에서 브라우저로부터 전달받은 파라미터 query의 값을 구할때 RequestUtils의 getParameter 함수를 호출한다. 왜 request.getParameter 함수를 직접 사용하지 않을까? 아래 박스에서 그 이유를 살펴본다.

한글, 문자셋 그리고 인코딩

웹 프로그래밍을 하다 보면 한글 처리 문제 때문에 골치를 썩을 일이 많다. HTML 스펙에 따르면 웹 서버로 요청할 때 URL에 ASCII가 아닌 문자를 포함해서는 안된다. 따라서 GET 명령을 통해서 "한글"이란 값을 query 변수로 넘길 때는query=한글 이 아니라 query=%ED%95%9C%EA%B8%80 (UTF-8 문자 셋의 경우)와 같이 escape 시켜 전달하게 된다. POST로 요청을 보낼 때는 두 가지 선택이 있다. 하나는 application/x-www-form-urlencoded (디폴트 enctype) 이고, 다른 하나는 multipart/form-data 이다.

Tomcat은 브라우저로부터 요청을 받으면 HttpServletRequest 객체를 생성하고 이 객체에 요청 경로의 원래 값과 디코딩한 값을 포함한다. Tomcat의 경우 ISO-8859-1 (Latin1)이 디폴트 문자 셋이며, 따로 설정을 변경하지 않을 경우 ISO-8859-1로 요청 경로를 디코딩한다.

POST 요청 중 content type이 application/x-www-form-urlencoded일 경우에는 브라우저가 전달한 문자 셋으로 파라미터들을 디코딩한다. 그러나, 대부분의 브라우저는 문자 셋을 전송하지 않으며 이 경우에도 Tomcat은 디폴트 문자 셋인 ISO-8859-1로 파라미터들을 디코딩한다. POST 요청이고 content type이 multipart/form-data일 경우에는 디코딩을 수행하지 않고 애플리케이션에 그 역할을 위임한다.

위와 같은 이유로 한글과 같은 유니코드 파라미터를 포함하는 GET, POST (application/x-www-form-urlencoded) 요청에 대해 웹 애플리케이션 상에서 아래와 같이 HttpServletRequest 로부터 파라미터 값을 직접 구할 경우 유니코드가 아닌 ISO-8859-1 문자열이 반환된다.

String query = request.getParameter("query");

따라서 이 값을 유니코드로 변환하기 위해서는 아래와 같은 추가적인 코드가 필요하며 RequestUtils.getParameter 함수가 이 역할을 수행한다.

query = new String(query.getBytes("ISO-8859-1"), "UTF-8");

더 쉬운 방법은 웹 서버의 디폴트 문자 셋을 UTF-8로 변경하는 것이다. Tomcat의 경우 conf/server.xml에서 아래와 같이 URIEncoding을 UTF-8로 변경한다.

<Connector port="7612" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8"/>

이렇게 디폴트 문자 셋을 변경할 경우 아래와 같이 HttpServletRequest 객체에서 바로 UTF-8로 인코딩된 파라미터 값을 구할 수 있다.

String query = request.getParameter("query");

대부분의 WAS에서 디폴트 문자 셋은 ISO-8859-1이나 그렇지 않는 WAS도 존재한다. (Jetty의 경우는 디폴트 문자 셋이 UTF-8이다.)

11 라인에서 페이지 컨텍스트에 query 애트리뷰트를 저장하는 이유도 request 객체로부터 직접 파라미터값을 구할 경우 ISO-8859-1로 문자 셋이 지정되기 때문이다.