JSP 코드로 이미지 관리하기





동적 서블릿 이미지 메이킹을 마음대로!




Level: Introductory


Dan Becker
소프트웨어 개발자, IBM Software Group
2002년 11월


웹 사이트를 코딩하고 지원하거나 인터넷에 페이지를 갖고 있다면 독자들의 필요를 충족시키는 이미지를 제공하는 것이 얼마나 어려운 일인지 알 것이다. JavaServer Pages (JSP) 태그를 이용하여 이미지 관리를 시도해보자.


이 글은 IBM developerWorks 저널에 2002년 11월 이슈 부분에 기재되었음을 밝혀둔다
.


세상을 지배하라! 그렇지 않다면, 적어도 이미지라도 지배하라!
사이트 개발자 또는 페이지 작성자로서 다양한 선호를 만족시키는 것은 어려운 일이라는 것을 안다. 이를 수작업으로 수행하기 위해서는 사이트의 이미지 하나하나를 웹 사이트가 지원하는 이미지 사이즈로 변환해야한다. 그런다음 사이트의 각 페이지에 이미지 태그를 조정하여 각각의 태그가 이미지 사이즈를 적절하게 반영할 수 있도록 해야한다. 이미지를 변경하지 않고서는 HTML img 태그의 넓이와 높이를 간단히 변경시킬 수 없다. 이는 저대역 사용자들은 큰 이미지를 다운로드하여 클라이언트 측에서 리사이징을 해야한다는 것을 뜻한다. 이러한 종류의 이미지 관리는 성가실 뿐 아니라 에러를 양산해낸다. 그리고 대부분의 웹 사이트가 다양한 이미지 사이즈를 제공하지 않는 이유를 쉽게 알 수 있다.


문제는 기술의 문제가 아니다. 자바 프로그래밍으로 이미지를 다양한 사이즈나 포맷으로 변환하기는 쉽다. 서비스만의 문제 또한 아니다. 웹 서비스를 사용하여 각자의 필요에 맞춰 페이지를 커스터마이징하는 것이 일반적이기 때문이다. 문제는 전개와 관리가 쉽도록 기술과 서비스를 조합하는 일이다.


이 글은 JavaServer Pages (JSP) 태그를 사용하는 솔루션으로 이미지를 관리하는 방법을 다룬다. 예를들어 HTML에서 이미지 태그를 코딩하고 다양한 버전의 이미지 사이즈를 갖추는 대신 다음과 같이 하는것이다:






<img src=http://img.yahoo.co.kr/blank.gif width=”800″ height=”600″ >

사용자의 선호에 맞춰 이미지를 자동으로 사이징하는 태그를 갖추는 것이 합리적이다:






<util:imagesizer src=http://img.yahoo.co.kr/blank.gif

사용자가 다양한 사이즈 중에서 선택하고 선호도에 따라 사이트상의 모든 이미지가 바뀌도록 하는 것이 가능하다. 그림 1의 샘플 이미지를 보자. 또한 넓이와 높이 속성을 삽입하고 태그를 수동으로 편집하는 일 따위는 하지 않아도 된다.


그림 1. 이미지 선택이 있는 JSP 페이지


한번도 JSP 커스텀 태그를 본 적이 없다면 예제에서 신택스를 연구해보자. JSP 커스텀 태그를 HTML 태그와 비교해보자:



  • 태그 개발자가 만든 imagesizer가 있다.

  • 이 태그는 프리픽스 util이 있는데 태그 세트들을 자바 프로그래밍의 패키지 이름과 흡사한 라이브러리들로 그룹핑한다. 새로운 프리픽스를 만들거나 라이브러리에 있는 디폴트 이름을 사용할 수 있다.

  • 이 태그는 새로운 XML 방식의 끝내는(ending) 태그를 가지고 있다: “/>”.

HTML 태그처럼, JSP 태그도 많은 속성이 있다. 여기에서는 src가 제시되었다. 또한 바디가 있으며 바디 안에는 다른 태그들도 가질 수 있다. HTML img 태그를 모방하는 것이기 때문에 JSP 이미지 사이징 태그용 바디는 없다.


JSP 페이지가 커스텀 image-sizer 태그를 사용할 때, 태그의 자바 구현은 이미지 파일을 찾아 적절한 사이즈로 변환하고 이 이미지를 독자에게 제공한다. 태그는 퍼블리싱하기 전에 이미지 변환 부터 사이트 매니저를 저장한다. 또한 웹 페이지 작성 작업을 단순화한다. 단지 하나의 페이지가 많은 이미지 사이즈 선택을 핸들하는데 필요하기 때문이다. 무엇보다도, 중요한 것은 각자의 사이트 이미지에 이러한 유연성을 제공한다면 인기있는 사이트가 될 것이다.


웹 서버
이제는, 클라이언트(웹 브라우저를 이용하는 독자)가 JSP 페이지를 제공하는 사이트를 방문할 때 그 배후에 어떤일이 벌어지는지 알아보자. 세 개의 인터랙션이 이루어진다. (그림 2):


그림 2. 웹 클라이언트와 서버 간 인터랙션


첫 번째 경우, 브라우저가 HTML 파일이나 이미지 파일 같은 정적 문서를 요청한다고 가정해보자. 서버는 파일 공간에 리소스를 위치시키고 브라우저에 파일을 제공한다. 문서를 요청하고 요청에 응답하는 것은 HTTP에 정의되어 있는데 이것은 인터넷 상에서 클라이언트-서버 인터랙션의 기초가 된다. 웹 서버는 요청을 완벽하게 핸들하고 웹 애플리케이션 서버나 서블릿 콘테이너와 인터랙션 할 필요가 없다.


두 번째 경우 브라우저가 자바 서블릿을 포함하는 웹 리소스를 요청한다고 가정해보자. 자바 서블릿은 웹 서버가 자바 프로그래밍 언어를 사용하여 서버상에서 태스크를 수행하도록 한다. 서블릿들은 효율적이어서 CGI와 서버측     JavaScript     같은 오래된 기술보다 메모리와 프로세싱 파워를 덜 사용한다. 서블릿은 IBM WebSphere Application Server과 Apache Tomcat 같은 웹 서버에서 다른 기술들에 비해 이동성이 강하고, 다양한 플랫폼 상에서 같은 서블릿을 구동할 수 있는 서블릿 콘데이너를 지원한다. 마지막으로, 자바언어 고유의 안정성으로 인해 잘못된 서블릿이 웹 서버에 영향을 주는 경우도 드물다. 웹 서버는 적절한 서블릿을 찾아 필요할 경우 서블릿 소스 코드를 컴파일하고 서블릿 프로세싱 결과를 요청자에게 리턴한다. 자주 요청되는 서블릿은 서버 메모리에 캐싱된다. (그림 2).


세 번째 경우, 브라우저가 JSP 페이지를 포함하는 웹 페이지를 요청한다는 것을 가정해보자. JSP 페이지는 정보를 디스플레이 하는 작업을 쉽게 하고 동적 콘텐트를 정적 페이지와 분리하는 것을 돕는다. 웹 페이지 디자이너는 HTML 라이브러리에 있는 다른 태그인 것 처럼 하여 JSP 태그를 사용한다. JSP 프로그래머는 JSP 프로그래밍 스팩에 따라 태그를 구현한다.


이번에는 이미지-사이징 JSP 태그를 구현하고 JSP 코드를 작성하는 방법을 알아보자. 웹 콘테이너의 관점에서 볼 때 JSP 페이지는 자바 서블릿과 밀접하게 관련되어 있다. 텍스트 기반 JSP 페이지는 웹 콘테이너에 의해 자바 구현으로 변환된다. 웹 콘테이너는 자바 구현을 찾아 자바 서블릿 같은 구현을 처리하고 코드를 구동하여 프로세싱 결과를 클라이언트에 리턴한다. 많은 레이어와 리다이렉트가 있는 듯이 보이지만 디스패칭은 빠르고 사용자에게도 투명하다. 서블릿과 마찬가지로 자주 요청되는 JSP 페이지는 서버 메모리에 캐싱된다.


JSP 커스텀 태그 작성하기
웹 서비스가 JSP 페이지 요청을 어떻게 처리하는지 보았다. 이제는 JSP 커스텀 태그를 어떻게 구현하는지 보자. JSP 태그는 Java Standard Template Library(JSTL) 같은 표준 라이브러리와 일명 커스텀 태그라고 하는 스스로 작성한 라이브러리에도 해당된다는 것을 명심하라. 일반적으로 커스텀 태그는 특정 문제 도메인을 다룬다. 이 글에서는 이미지를 관리하는 방법을 다루겠다. 현재 Java 2 Extended Edition (J2EE) Versions 1.2와 1.3은 JSP Version 1.2를 사용한다. 현재 Sun은 JSP 스팩 2.0 버전을 발표했다. 이 새로운 스팩은 커스텀 태그를 구현하는 방식에 있어서 큰 변화가 없다.


표준과 커스텀 태그 라이브러리를 taglib 디렉티브를 통해 JSP 페이지로 반입할 수 있다:






<%@ taglib uri=’imagesizer.tld’ prefix=’util’ %>

이 디렉티브는 태그 라이브러리 디스크립터 파일의 위치를 명명한다. 여기서는 imagesizer.tld로 명명되었다. 그리고 사용된 프리픽스는 util로 명명되었다. 태그 예제에서 보았듯이 프리픽스와 이름으로 태그를 사용할 수 있다:






<util:imagesizer src=http://img.yahoo.co.kr/blank.gif

태그 라이브러리 디스크립터는 웹 콘데이너에게 사용가능한 태그가 무엇인지 그들이 어떻게 작용하는지를 설명한다. Listing 1은 그 예제이다. 이 파일은 XML 포맷으로 되어있고 읽기 쉽다. 하지만 IBM WebSphere Studio Application Developer 같은 애플리케이션 개발 플랫폼은 필드를 채우고 파일을 검사하는 것을 돕는다. 가장 중요한 정보는 태그 엘리먼트이다. 이것은 JSP 커스텀 태그의 이름과 태그를 구현하는 자바 클래스를 정의한다. 또한 태그가 받아들이는 모든 속성과 바디 콘텐트를 보여준다.

Listing 1. Tag Library Descriptor (TLD) 발췌




<taglib >
<tlibversion> 1.0 </tlibversion>
<jspversion> 1.1 </jspversion>
<tag>
<name>imagesizer</name>
<tagclass>tags.ImageSizerTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>src</name>
<required>required</required>
</attribute>
<attribute>
<name>alt</name>
</attribute>
<attribute>
<name>quality</name>
</attribute>
</tag>
</taglib>

이 예제에서 태그는 src 속성이 요구하는 세 개의 속성을 갖고 있다. alt 속성은 HTML img alt 속성을 모방한 것이다. 이 JSP 태그를 확장하여 다른 이미지 속성을 포함시켜도 된다.


JSP 커스텀 태그를 작성하는 다음 단계는 태그 용 자바 코드를 구현하는 것이다. 이 글에서 imagesizer 태그는 tags.ImageSizerTag 자바 클래스에서 구현된다. J2EE 커스텀 태그 지원 대부분은 javax.servlet.jsp.tagext 패키지에 위치해있다. imagesizer 클래스는 표준 TagSupport를 확장한다. 이것은 바디 없이 태그를 구현한다. 이것의 자손 클래스는 BodyTagSupport인데 이것은 바디가 있는 태그를 구현한다. 두 클래스 모두 Tag 인터페이스를 구현한다. doStartTagdoEndTag 메소드는 태그가 처음 읽혀지고 태그가 웹 컨테이너에 의해 완전히 읽혀진 후에 호출된다. ImageSizer 태그는 doEndTag 만 구현한다.


TagSupport 클래스에서 PageContext 클래스는 JSP 페이지와 관련된 중요한 정보에 액세스 하도록 한다. 예를들어, PageContextHttpRequestHttpResponse 객체에 액세스를 가능하게 한다. 이러한 객체들은 값을 읽고 응답을 작성하는데 필수적이다. 요청은, 사용자 선택을 트래킹하고 페이지에서 페이지로 값을 수행할 경우 HttpSession로 액세스를 허용한다. PageContextServletContext로 액세스를 허용하는데 이것은 서블릿 경로, 이름, 기타정보를 위치시키는데 도움이 된다. ImageSizer 코드(Listing 2)에서, PageContext 객체에 대한 레퍼런스와 정보가 있다. 그림 3은 이들 클래스들의 관계이다. 다른 표준 클래스 다이어그램 처럼 실선으로 된 박스는 클래스를 나타내고 점선 박스는 인터페이스를 나타낸다. 상속은 파생된 클래스나 인터페이스부터 부모까지 선으로 이어져있다.

Listing 2. ImageSizerTag doEndTag 구현




// Implement the tag once the complete tag has been read.
public int doEndTag() throws JspException {

// Move request data to session.
int outputSize = 0;
String siz    eVal     = request.getParameter( REQUESTSIZEKEY );
if ( siz    eVal     != null ) {
session.setAttribute( REQUESTSIZEKEY, siz    eVal     );
siz    eVal     = (String) session.getAttribute( REQUESTSIZEKEY );
if ( siz    eVal     != null ) {
outputSize = Integer.parseInt( siz    eVal     );
}
}

// Get specified image locally.
String contextPath = getContextPath( request );
Image image = Toolkit.getDefaultToolkit().getImage(contextPath + src );
ImageSizer.waitForImage( image );
int imageWidth = image.getWidth( null );
int imageHeight = image.getHeight( null );

if (( imageWidth > 0 ) && ( imageHeight > 0 )) {
if (( outputSize > 0 ) && ( outputSize != imageWidth )) {
// Convert image to new size.
Image outputImage = ImageSizer.setSize( image, outputSize, -1 );
ImageSizer.waitForImage( outputImage );
int outputWidth = outputImage.getWidth( null );
int outputHeight = outputImage.getHeight( null );

if ( outputWidth > 0 && outputHeight > 0 ) {
// Change image file name to xxxx.size.jpg
String originalSrc = src;
int lastDot = src.lastIndexOf( ‘.’ );
if ( lastDot > -1 ) {
src =http://img.yahoo.co.kr/blank.gif http://img.yahoo.co.kr/blank.gif 0, lastDot + 1 );
}
setSrc( src + outputSize + “.jpg” );

// Write new size image to JPEG file.
File file = new File( contextPath + src );
if ( !file.exists() ) {
out.println( “” );
FileOutputStream fos = new FileOutputStream( contextPath + src );
ImageSizer.encodeJPEG( fos, outputImage, quality );
fos.close( ) ;
}

imageWidth = outputWidth;
imageHeight = outputHeight;
}
} // if outputSize
} // if image found

// Produce output tag.
out.print( “<img src=http://img.yahoo.co.kr/blank.gif + src + “\”” );
// Add alt text, if any
if ((alt != null ) && ( alt.length() > 0 )) {
out.print( ” alt=\”” + alt + “\”” );
}

// Add proper width, height.
out.print( ” width=\”” + imageWidth + “\” height=\”” +
imageHeight + “\”” );
out.println( “>” );

return     EVAL    _PAGE;
} // doEndTag


그림 3. javax.servlet.jsp.tagext 클래스


ImageSizerTag 클래스의 doEndTag 메소드는 Listing 2에 나와있다. 이것은 JSP 커스텀 태그를 구현하는데 필요한 거의 모든 자바 코드라고 볼 수 있다. 큰 블록이지만 메소드를 완벽하게 보는데 도움이 된다. 우선 모든 HTTP 요청 매개변수는 HTTP 세션에 저장된다. 이것은 이미지 사이즈에 대한 사용자 선택 같은 속성을 가져다가 세션에 저장하여 페이지에 따라 사용자가 이를 따르도록 한다. 이 태그의 기능을 확장하기 위해서 이것을 확장하여 쿠키에 선택을 저장하여 사용자가 다음에 이 사이트를 방문할 때 선택을 사용하도록 할 수 있다.


다음 단계는 디폴트 이미지를 로딩하는 것이다. java.awt.Toolkit은 이미지를 요청하는데 이것은 ImageSizer.waitForImage와 함께 로드되고 적절한 사이징이 검토된다. 로딩을 위해 일시정지가 필요하다. 왜냐하면 자바 이미지는 비동기식으로 로딩되고 요청할 때마다 항상 사용할 수 있는 것이 아니기 때문이다. ImageSizer 보조 클래스는 이 예제에서 전체 이미지 프로세싱을 수행하고 다음 섹션에서는 더 자세하게 다루겠다. 넓이와 높이가 맞으면 이미지는 리사이징이 필요없다. HTML 이미지 태그는 이미지 이름과 현재 사이즈를 사용하여 작성된다. 이것은 HTML 이미지 태그를 모방하기위해 필요한 JSP 구현의 모든것이다.


ImageSizer 보조 클래스는 사용자가 새로운 이미지 사이즈를 요청하면 이미지를 리사이징한다. 이미지 파일은 파일 크기에 따라 새로운 이름이 된다. 이 파일은 JPEG 인코딩이고 파일 시스템에 작성된다. 결과적으로 새롭게 리사이징된 파일은 HTML 이미지 태그 아웃풋에 사용된다. 이 태그의 대안 구현은 파일을 GIF나 PNG 포맷으로 저장하거나 디스크 공간을 저장하기위해 메모리에서 이미지를 제공하는 것이다. Listing 2는 리사이징된 파일을 앞으로 사용할 경우에 대비하여 디스크에 캐싱한다. 따라서 처음의 리사이징은 약간의 서버 프로세싱 시간이 필요하지만 연속적인 이미지 사이즈 요청은 프로세싱이 전혀 필요하지 않다. 사용가능한 디스크 공간을 체크하여 제한된 파일 공간과 클라이언트에게 제공하는 정보의 긴급성 간에 균형을 맞추도록 할 수 있다.


이미지 사이징
지금까지 JSP 태그를 작성하는 단계를 검토했다. ImageSizerTag 클래스는 이미지를 자동으로 리사이징하여 사용자 선택에 맞춘다. 이번에는 ImageSizer 클래스를 사용하여 JPEG 파일로서 이미지를 리사이징하고 저장하는 구체적인 방법을 설명하겠다. 자바 코드로 이미지를 리사이징 할 때 java.awt.Image 클래스의 getScaledInstance 메소드를 사용할 때 쉬워진다. 이 메소드를 새로운 넓이와 높이로 하거나 형태 비율을 보존하기위해 -1에서 1까지의 매개변수 값을 제공한다. 그리고 나서 새롭게 리사이징된 이미지를 얻는다. 하지만 모든 자바 이미지는 즉시 사용할 수 있는 것은 아니다. 따라서 java.awt.MediaTracker 를 사용하여 이미지가 완전히 로딩될 때까지 기다려야한다. ImageSizerwaitForImage 메소드는 이 코드를 캡슐화한다.


이 예제에서 가장 어려운 디자인 포인트는 이미지 저장 방법을 결정하는 일이다. 자바 프로그래밍에는 이미지 인코딩과 저장에 많은 선택권이 있어 비교를 해야한다.



  • com.sun.image.codec. 이 패키지는 Java 2 SDK 1.2와 1.3 구현에 사용할 수 있지만 개인 패키지어서 Java 2 버전까지 기다려야한다. 이 패키지는 JPEG 인코딩에 제한이 있다.

  • Java Image I/O API. 이 패키지는 Java 2 SDK 1.4의 표준이다. 하지만 작성 당시 어떤 J2EE 버전도 SDK 1.4를 사용하지 않는다. 이 패키지는 뛰어난 이미지 조작 기능과 인코딩 옵션을 갖추고 있다.

  • Java Advanced Imaging API. 이 API는 표준 확장이지만 이것을 사용하려면 웹 마스터가 지원하지도 않는 패키지를 설치해야한다.

  • ACME GIF Encoder. 이 패키지는 유용하며 예제 코드와 결합할 수 있다. 하지만 비용과 유지 문제가 남아있다. 다른 옵션들과는 다르게 이 소프트웨어는 유료이며 GIF 표준을 완전히 지원하지 않는다.

Listing 3의 경우 com.sun.image.codec 패키지를 사용했는데 IBM WebSphere와 Apache Tomcat 같은 J2EE 1.2 와 1.3 웹 서버 콘테이너에서 사용할 수 있기 때문이다. 인코더는 단순하며 100% 순수한 자바 코드이지만 com.sun 패키지에 있다. 장기적인 시각으로 볼 때 Java Image I/O 패키지는 보완해야 할 사항이 많이있다. 이미지 변형 기능과 많은 파일 포맷을 저장하는 기능이 훌륭하다. Java Image I/O 패키지는 Java 2 version 1.4 이전까지는 표준이 아니다.


어떤 이미징 패키지를 사용할 것인가에 대해 결정이 끝났다면 JPEG 파일을 저장하는 코드는 간단하다. ImageSizerencodeJPEG 메소드는 다음 절차를 캡슐화한다:




  1. java.awt.image.BufferedImage 객체-자바 Image 자손-는 리사이징된 아웃풋 이미지에서 만들어진다. 주석은 로고, watermark, 타임스탬프, 이미지 저작권 정보를 추가할 때 코드에 주석이 달린다.

  2. Image에서 BufferedImage로 변환한 후에, 아웃풋 스트림에 JPEGImageEncoder 객체를 만들어라. 아웃풋 인코딩 평가는 0.0 (최악)부터 1.0 (최고) 까지 이다. 0.75는 디폴트이지만 0.95는 좀더 자세한 이미지와 함께 큰 파일 사이즈로 만들어진다.

  3. 이미지는 아웃풋 스트림으로 인코딩되고 스트림은 모든 정보가 이미지 파일에 나타나도록 플러쉬된다.

Listing 3. ImageSizer encodeJPEG 구현




// Encodes the given image at the given
// quality to the output stream.
public static void encodeJPEG
( OutputStream outputStream,
Image outputImage, float outputQuality )
throws java.io.IOException {

// Get a buffered image from the image.
BufferedImage bi = new BufferedImage
( outputWidth, outputHeight,
BufferedImage.TYPE_INT_RGB );
Graphics2D biContext =
bi.createGraphics( );
biContext.drawImage
( outputImage, 0, 0, null );
// Additional drawing code, such as
// watermarks or logos can be placed here.

// com.sun.image.codec.jpeg package
// is included in Sun and IBM sdk 1.3.
JPEGImageEncoder encoder =
JPEGCodec.createJPEGEncoder
( outputStream );
// The default quality is 0.75.
JPEGEncodeParam jep =
JPEGCodec.getDefaultJPEGEncodeParam
( bi );
jep.setQuality( outputQuality, true );
encoder.encode( bi, jep );
outputStream.flush();
} // encodeImage


여기까지는 이미지를 리사이징하고 저장하는데 필요한 모든 단계이다.


WebSphere또는 Tomcat에서 패키징 및 전개
이번에는 Application Server version 4.0이나 Apache Tomcat version 4.0에서 ImageSizer JSP 태그의 패키지 및 전개 방법을 설명하겠다. 그림 4는 Application Developer 이다. 왼쪽 칼럼의 상단에 있는 Navigator는 웹 애플리케이션의 디렉토리 구조를 나타내고 JSP 태그가 J2EE 스팩에 따라 어떻게 패키지되어야 하는지를 보여준다. J2EE 스팩에 필요하기 때문이 이 디렉토리 구조는 모든 웹 애플리케이션에 일반적이다. 일단 구조가 저장되면 Web Archive (WAR) 파일이 되고 WebSphere, Tomcat, 기타 웹 콘테이너에 쉽게 전송된다. Application Developer 같은 좋은 개발 환경은 다음의 스팩을 따르고 훌륭한 애플리케이션을 만들어낸다.


그림 4. WebSphere Studio Application Developer에서 ImageSizer 패키징
원본 크기의 사진을 보려면 클릭하세요


ImageSizer 프로젝트에는 소스 코드용 디렉토리가 있다. 최종 WAR 파일에 이 디렉토리를 추가할 것인지의 여부는 개발자가 선택하기 나름이다. webApplication 디렉토리에는 실제 프로그램 코드가 포함되어 있다. 예제 프로젝트에는 PickASize.jsp이라고 하는 테스트 JSP 페이지와 LazyDog.jpg 이라고 하는 테스트 이미지가 포함되어 있다. 일반적으로 이들은 ImageSizer 커스텀 태그의 라이브러리 버전에 포함되지 않는다. 이 태그의 구현은 WEB-INF 디렉토리에 있다. 자바 클래스는 WEB-INF/classes에 있고 Tag Library Descriptor 파일은 WEB-INF/tlds에 있다. 이들은 모든 웹 애플리케이션에 적용되는 표준 디렉토리 위치이다. 이 트리에 있는 다른 파일들은 서버 옵션 설정에 도움을 주지만 그렇지 않더라도 WAR 파일에 필수적인 것은 아니다. Application Developer나 Java SDK를 사용하여 이 애플리케이션 용 WAR 파일을 만들어보라.


To m c a t 에 웹 애플리케이션을 설치하려면 ROOT/webapps 디렉토리에 파일을 놓고 서버가 WAR 파일을 디렉토리 구조로 확장하도록 해야한다. Application Server의 경우, Administrators Console의 웹 애플리케이션 마법사(Web Application wizard)를 사용하여 애플리케이션을 설치할 수 있다. 전개한 후에, http://yourhostname:port/ImageSizer/PickASize.jsp를 방문하여 JSP 페이지를 구동해보라.


결론
지금까지 이미지 사이징을 자동으로 관리하는 JSP 커스텀 태그를 만들었다. 커스텀 태그는 이미지 리사이징 작업에 도움이 되고 웹 사이트를 방문하는 사용자들이 선택을 할 수 있도록 한다. 예제 태그를 확장하여 모든 종류의 이미지 조작을 할 수 있다. 저작권 텍스트, 타임스탬프, 로고, 워터 마크 등이 그것이다. Application Server나 Apache Tomcat에 이를 전개하고 이미지 기반 JSP 페이지를 작성하거나 예제를 사용하여 코드를 실험할 수 있다. 이 글이 JSP 태그에 대해 실질적인 팁을 주었기를 바라며 각자의 필요에 맞춰 기능을 확장해보기를 바란다.


참고자료






필자소개
Dan Becker는 IBM(Austin, Texas)의 소프트웨어 그룹에서 일하고 있다. 현재는 Interactive Financial Services 프로젝트에서 온라인 웹 뱅킹 시스템 작업을 수행하고 있다.

마크 앤드리스의 새로운 벤쳐, “닝(Ning)”

지난 6월에 뉴스닷컴에는 넷스케이프 창업자인 마크 앤드리슨이 비밀리에 (in stealth mode) 스타트업 하나를 추진하고 있다는 기사가 나온 적이 있다. 그때 프로젝트명은 “24 Hour Laundry”, 즉 24시간 빨래방(?) 이란 이름이었다.



약 4개월이 지난 10월, “24시간 빨래방” 프로젝트는 “Ning” 이라는 새로운 이름으로 발표되었다. Ning 은 “Now, it’s a New Game” 의 약자라고 한다. 개방성과 네트워킹을 강조한 웹 2.0이 어디서나 화두인 요즘, 웹 1.0을 개척한 장본인중 하나인 마크 앤드리슨은 이제 “새로운 게임 (new game)” 을 준비중인 모양이다.



Ning.com 서비스는?



Ning 은 한마디로 소셜 네트워킹 기능에 기반한 웹사이트를 만들 수 있도록 해 주는 웹 서비스다. 특정한 주제에 기반한 소셜 네트워킹 서비스를 구축하고자 하는 사용자는 Ning 서비스를 이용하여, “도메인명.ning.com” 으로 불리는 서비스 사이트를 만들 수 있다.



이 사이트의 오른쪽에는 닝 피벗 (Ning Pivot) 이라고 불리는 feature 가 있다. 닝 피벗에 포함된 특정 키워드를 선택하면 해당 키워드에 기반한 사이트 리스트와, 해당 키워드를 주제로 엔트리를 입력한 유저 리스트가 나타나게 된다. 이를 통해서, 특정 키워드에 기반한 사이트와 해당 키워드에 관심을 가진 사람들이 누구인지를 파악할 수 있게 된다.



한가지 예를 들어 보자. 어떤 지역에 있는 ‘맛집’들을 사용자들이 직접 지도 위에 표시하고, 각 맛집들에 대해 사용자들이 평가 및 후기를 남길 수 있는 사이트를 생각해 보자. Ning 서비스를 이용하여, “Restaurant Reviews with Maps” 라는 서비스 사이트를 구성할 수 있다. 도메인은 restaurantreviewswithmaps.ning.com 이 된다. 





그림. restaurantreviewswithmaps.ning.com



오른쪽의 Ning Pivot 칸에는 태그 리스트가 나타나 있다.



 



여기에서 Pizza 를 선택하면 피자라는 태그에 해당하는 Ning 사이트 목록 (App 이라고 부름)과, pizza 라는 키워드로 글을 남긴 유저들, 그리고 컨텐츠 타입이 표시된다.



사이트 리스트에서 “Worcester restaurants” 를 고르면, 워스터 (Worcester) 지역의 레스토랑을 리뷰하는, restaurantreviewswithmaps.ning.com 과 유사한 룩앤필의 Ning 사이트로 연결된다.





또한 키워드 검색화면에서 사이트 대신 사람 이름을 선택할 수도 있다. “pizza” 태그의 검색 결과 화면에서 (전 전 그림), “Top users for Pizza” 리스트 중 제일 먼저 나온 bgreenlee 라는 유저를 클릭하면, 그가 남긴 글 리스트가 보여지게 된다.





위에서 살펴본 워스터 지역의 레스토랑 검색 페이지가 원래 보았던 restaurantreviewswithmaps.ning.com 사이트와 룩앤필이 비슷한 이유는, 아마도 추측컨대 Ning 이 제공하는 “사이트 클론” 기능 때문이 아닐까 한다. 즉 A라는 소셜 네트워킹 사이트가 마음에 드는 유저는 A 사이트를 그대로 가져와서 약간의 수정을 통해 A’ 라는 자신의 소셜 네트워킹 사이트를 구축할 수 있다. 약간의 PHP 지식이 있으면 샘플 코드를 적용하여 자신의 사이트를 좀더 차별화할 수 있다.



그림. Ning 의 사이트 클론 기능



소셜 어플리케이션이 웹 2.0 을 대변하는 대표적인 장르로 큰 관심을 모으고 있는 가운데, 테크노라티나 딜리셔스 (del.icio.us) 등의 사이트가 태깅을 기반으로 한 사이트 검색 서비스를 제공하고 있다면, Ning.com 은 이처럼 태깅 기반의 사이트 및 유저 검색을 지원하는 동시에 소셜 어플리케이션을 쉽게 만들 수 있도록 해주는 서비스를 제공하고 있다.



Web 2.0 의 킬러 앱은?



Ning 에서 한가지 볼 수 있는 점은, 특정 태그에 기반한 사이트들을 “Apps” 라고 부른다는 점이다. 이는 웹이 단순히 HTML 을 이용한 고정적인 (static) 정보의 표현에서, 어플리케이션 구현의 플랫폼으로 진화해 나간다는 “Web as application platform” 트렌드를 반영하는 지도 모른다.



이러한 트렌드에는 구글 맵 등의 서비스를 통해 웹이 소프트웨어 구현의 플랫폼이 될 수 있다는 것을 증명한 구글이 한몫을 했다. 이러한 철학의 연장선으로, 잘 알려진대로 구글과 썬은 힘을 합해 새로운 오피스 스위트도 만들겠다는 발표를 했다. 썬은 “Network is Computer” 라는 기치 하에, 과거에도 스타오피스를 인수해서 thin client (웹브라우저) 기반의 오피스 스위트를 만드는 시도를 한 바 있으며, 이번에 구글이라는 강력한 지원군을 얻게 된 것이다. 직접적인 관계는 없을수도 있겠으나, 구글의 CEO 인 에릭 슈미트가 14년간을 근무한 곳이 바로 썬이라는 점도 퍼즐의 한 조각일 수 있겠다.



여하튼 Web 2.0 에 관심이 쏠리고 있다. Web 2.0 정신(?)에 충실한 서비스인 Ning.com 을 잠깐 써 보았지만, 사실 필자의 경우 그다지 큰 감동이 있지는 않았다. 오히려 이보다 단순한 Flickr 의 경우 해외쪽에서 사진 공유 프로그램으로 거의 자리를 잡아가고 있는 추세인 듯하다. (필자의 유럽 동료들도 현재 Flickr를 꽤 사용하고 있다.) 허나, 마크 앤드리슨은 똑똑한 사람일 테고, 그가 관심을 갖고 제품을 내고 있다는 것만 보더라도 Web 2.0 은 관심을 가질 만한 대상이라고 할 수 있지 않을까? 아무튼, Web 2.0 에서의 킬러 앱은 무엇일지 기대된다.








김창원 chang1.kim@samsung.com  
 
김창원님은 현재 삼성전자 무선사업부 VOC 그룹에서 근무중이며, 전세계 삼성 핸드폰 유저를 위한 포털사이트인 삼성펀클럽 (www.samsungmobile.com) 및 국내 애니콜 유저를 위한 포털인 애니콜랜드(www.anycall.com)를 위한 모바일 서비스 아이템을 담당하고 있다.

국내의 역량있는 무선 인터넷 서비스/컨텐츠/솔루션 벤처들이 해외 시장으로 진출하는 데 자그마한 도움이 되었으면 하며, 특히 삼성전자 무선사업의 글로벌 네트워크를 통해 해외로 진출하고자 하는 국내의 모바일 벤처들은 언제든지 문의 가능하다.



 

P2P, 소설 네트워크를 만나다



















스벤 컨설팅의 김명자 대리. 1주일 안에 게임 콘텐츠 해외 수출에 관한 프로젝트 제안서를 작성해야 한다. 평소 알고 있는 분야긴 하지만 외국의 상세한 유통 구조까지 스터디하기엔 시간이 너무 모자라다. 그렇다면? 김명자 대리의 머리 속에 게임의 해외 수출에 대해 알고 있을 만한 사람들의 이름이 왔다 갔다 한다. 전화기를 든 김대리. 통화를 하며 메모를 한다. 관련 자료는 메신저나 이메일로 보내주기로 했다. 이제 이 내용들을 제안서에 반영해보고 추가로 필요한 사항들은 나중에 보완하기로 한다.


 


최근 소프트웨어 산업에서 가장 다이내믹한 성장을 보여주는 분야는 협업 솔루션이다. 아웃 소싱을 통해 업무를 외부화하고 TFT를 활용해 프로젝트를 진행하는 등 새로운 업무 수행 방식들이 조직에 도입되자 구성원 간 협업의 문제가 점점 중요성을 띠게 되었고, 이를 지원하는 솔루션들이 부각되기 시작한 것이다.


 


IDC에 따르면 ‘협업’ 시장의 규모는 $4.4billion으로 올 해는 약 8% 가량 성장할 전망이다. 이 중에서도 특히 원활한 커뮤니케이션과 정보 공유를 지원하는 웹 컨퍼런싱, 기업 인스턴트 메시징, 프로젝트 사이트 등의 분야는 올 해 37%까지 성장해 $1.8billion의 규모를 형성할 것으로 예측되고 있다. 이러한 성장 가능성을 보여주기라도 하듯이 이미 글로벌 기업들도 이 분야에서의 세력 확장에 나서고 있다. 이 시장의 터줏대감인 IBM은 Lotus Notes로 현재 1억1800만 사용자를 확보하고 있고, MS는 $300million을 들여 Groove Networks와 PlaceWare를 사들이면서 IBM에 도전장을 내밀고 있다.


 


그렇다면 이 협업 솔루션 시장의 ‘Next Big Thing’은 무엇일까?
MS가 사들인 Groove Networks에서 그 힌트를 찾아볼 수 있다. Groove Networks는 안전한 인터넷 연결을 통해 다른 회사 직원들과 협업할 수 있게 해주는 P2P 기반의 소프트웨어이며, 별도의 그룹웨어를 깔거나 서버를 구축할 필요 없이 P2P 솔루션으로 파일을 공유하고, 원격 회의를 진행하거나 메시지를 주고 받을 수 있다는 점 때문에 성공적인 시장 진입이 예측되는 비즈니스 모델 중 하나였다 (물론 Groove의 경우 MS에 팔렸다는 것 자체가 성공일 수도 있겠다).


 


그런데 협업 솔루션으로서의 P2P는 이 외에도 그룹웨어와 달리 개인에 포커스를 맞출 수 있다는 점에 특징이 있다. 앞서 예를 든 김명자 대리처럼 대부분의 사람들이 업무에 개인적인 네트워크를 활용하고 있다. P2P는 바로 이러한 사람들에게 자신만의 자문팀을 꾸리는 기능을 제공할 수 있다. 여기에 인맥 관리 솔루션이 결합된다면 체계적으로 정리된 인적 네트워크를 자신이 수행하는 업무에 맞게 재단하여 일종의 자문팀을 구성하고 이들에게서 수집한 정보를 체계적으로 관리할 수 있게 될 것이다. 회사에서 구성해준 TFT와는 별도로 개인의 지원팀이 하나 더 생기는 것이다.



 



과연 한국에서는?


 


DataNet에 따르면 2003년 국내 협업 솔루션 시장의 규모는 약 1500억 원 (벤더 추산)으로, 2001년과 2002년 약 900억 원과 비교할 때 상당한 성장세를 보였다. 최근 아웃소싱의 증가, 기업 내부 업무환경의 분산 등으로 인해 협업 솔루션에 대한 관심이 점차 늘어나고 있어 이 분야의 성장세는 향후에도 지속될 것으로 보인다.


 


? 2004년 5월 KT가 코넷의 국내 트래픽 유형을 분석한 결과에 따르면 상대방 PC에 담긴 각종 파일을 주고 받는 P2P 프로그램 등으로 인해 발생하는 인터넷 트래픽이 전체의 90%를 육박하는 것으로 나타났으며, 이 중 P2P 프로그램을 이용한 트래픽이 33.44%, 개인간 메신저를 통한 파일 교환 트래픽이 55.32%인 것으로 집계됐다. 이러한 통계는 인터넷 사용형태가 정보검색 위주에서 개인간 콘텐츠 공유로 바뀌고 있음을 보여주고 있다.


 


? 최근 취업포털 잡링크가 직장인 1084명을 대상으로 ‘성공적인 직장 생활을 위한 인맥의 중요성’에 대해 조사한 결과, 66.7%가 `중요하다’고 답했지만 `현재 인맥관리를 제대로 하지 못하고 있다’는 응답자도 62.5%에 달해 인맥 관리 서비스에 대한 직장인들의 니즈를 보여주었다.


 


? 인맥 관리 서비스의 대표적인 성공 사례로는 2002년 선보인 쿠쿠박스가 있는데, 쿠쿠박스는 지인들의 연락처 정보를 자동으로 업데이트시켜주는 인맥관리 프로그램으로 2개월 만에 60만 명이 넘는 회원을 모았으며, 2003년 NHN이 이를 인수해 플랜훗이라는 이름으로 서비스를 제공하고 있다. 또 쿠쿠박스를 만들어낸 신동윤 사장이 최근 내놓은 토토링 서비스 역시 1월 19일 서비스 개시 후 열흘 만에 1400만 페이지 뷰를 기록해 화제가 되고 있는데, 토토링 서비스는 비즈니스맨과 일반인, 비즈니스맨과 비즈니스맨끼리 1촌을 맺고 나면 서로 상대의 1촌을 초대할 수 있도록 되어 있으며, 1촌으로 등록된 사람에게 궁금한 것을 물어보면 대답을 해주는 ‘지식통화’, ‘파워질문’ 등의 코너가 도입되어 있다.

액티언(Actyon), 젊음의 크로스오버 SUV가 탄생하다.

젊음의 크로스오버 SUV가 탄생하다, 액티언

최고의 성능과 세련된 감각, 젊음과 도전을 상징하는 크로스오버 자동차가 등장했다. 자유로운 감성과 세련된 스타일을 지닌 젊은 자동차 액티언은 어느 곳에서도 자연스럽게 어울리는 자동차다. 쌍용자동차의 신차 액티언을 만나보자.

우리가 SUV를 찾는 이유는 여러가지이다. 원래 SUV는 험준한 산악지대에서도 마음놓고 운전을 즐길 수 있는 용도로 태어났다. 안전하면서도 효율적인 이 차는 남성미를 물씬 풍기며 강력한 힘과 투박한 외모를 지니고 있었다. 그러나 레저의 개념이 폭 넓어지면서 자연에서 뿐만 아니라 도시에서도 어울리는 차를 원하게 되었다. SUV가 풍기는 강인한 멋과 안전에 대한 신뢰, 험한 길도 갈 수 있는 든든함 뿐만 아니라 승용차의 정숙함과 안락함, 그리고 세련됨 까지 요구한다. 더불어 도시의 사거리에서도 즐겁게 즐길 수 있는 편안함. 고급 연미복 재킷에 청바지를 입어도 어색하지 않은 감성이 필요하다. 하지만 역시 SUV를 좋아하는 사람들의 특징은 자유로운 감성과 여유이다. 푸른 바다를 배경으로 삼아 시원하게 뻗은 해안 도로를 달리다가 가파르고 높은 산길에서도 바람을 가르며 달릴 수 있는 묘미. 어느 곳에서도 자연스럽게 어울릴 수 있는 이유는 젊은 감성과 도전정신을 함유하고 있기 때문이 아닐까. 그런 의미에서 우리가 SUV는 역시 젊음에 가장 어울리는 차이다.

젊음이여 도전하라, 액티언

SUV의 명가로 자리잡은 쌍용자동차의 신차 액티언(Actyon)은 ‘젊음’에 도전한다. 즉, 젊음을 상징하는 키워드「Action」과「Young」의 결합한 단어인 액티언은 “ACTION”의 I를 “YOUNG”의 Y로 변형하여 젊은이들의 삶에 대한 열정과 도전정신, 그리고 그들의 역동성을 표현하였다. 열정과 활력이 넘치는 20~30대의 자존심, 최고의 SUV를 지향한다. 국내 SUV시장의 새로운 주력시장으로 성장하고 있는 소형 SUV 시장에 성공적으로 진입하기 위해서, 합리적이면서도 경쟁력 있는 가격과 뛰어난 상품성을 바탕으로 한 것이 특징이다. 국내 최초로 SUV와 스포츠 쿠페의 크로스오버로 탄생한 ACTYON은 다이내믹한 주행 성능과 스포티한 디자인의 소형 SUV 액티언(Actyon)이 역동성과 SUV 고유의 강인한 안전성에 차별화 된 편의사양과 스타일을 갖춰 국내 SUV 시장의 새로운 트렌드를 만들어내며 최근 급성장하고 있는 국내 소형 SUV 시장을 대표하는 엔트리 모델이 될 것으로 예상된다.

크로스오버의 스타일로 달린다.

ACTYON은 기존 쌍용자동차의 쓰리 서클 마크를 사용하지 않고 독립 브랜드 앰블램을 채택하여 주목을 끌었다. 이는 디자인의 모티브가 되었던 상어의 이미지와 ACTYON의 첫 글자인 A를 형상화한 것으로써 새로운 영역인 Entry급 SUV시장에 새롭게 진입하는 쌍용자동차의 의지와 약속이 담겨있다. 국내 SUV 시장의 에이스, 대표 브랜드, 쌍용자동차를 대표하는 첫번째 브랜드로, 디자인과 성능면에서 모두 A등급의 브랜드라는 것을 이미지화한 것이다. 특히 액티언의 가장 큰 강점은 감각적인 디자인이다. 기존 카이런이 SUV와 세단의 디자인 요소를 결합했다면, 액티언은 스타일적으로 스포츠 쿠페의 실루엣과 많이 닮아 있다. 활동적이면서도 역동적인 디자인은 메인 타깃인 젊은 층의 스타일리시한 감각에 맞추어져 있기 때문이다. 상어의 앞모습을 형상화한 후드라인과 독수리의 눈을 형상화한 헤드램프는 지금까지 SUV에서는 찾아 볼 수 없었던 미래지향성인 디자인이다. 특히, 역동성을 강조한 역 삼각 모양의 그릴과 어울려 액티언의 혁신적 이미지를 강조하고 있다. 사이드 가니쉬가 제외된 측면바디 경사각은 스포티한 도시형 SUV의 이미지를 나타낸다. 후면의 D필라의 경사각은 스포츠 쿠페에서만 느낄 수 있는 라인으로 더욱 역동적이다. 특히, 최근 트랜드화 되고 있는 다크 블루와 레드의 강렬한 이미지로 힘과 스피드를 나타내었다. 내부는 블랙 컬러를 베이스로 시트 및 데코레이션 아이템을 바디 컬러와 연계하여 블루와 레드로 콤비를 이루어 구성함으로 더욱 자유롭고 감각적인 스타일을 보여준다. 내부 인테리어는 직선적이고 동적인 디자인에 모든 조작 스위치가 원형으로 형상화되어져 운전자가 시각과 함께 손의 감각만으로 인지할 수 있도록 하였다. 기능적인 측면과 함께 디자인의 전체적 이미지에 통일감을 주어 재미있고 편안한 조작을 유도한다. 특히, 운전자의 편의에 맞추어진 공간들은 모든 주행에 대한 정보와 기능에 대한 실용적인 측면에 중점을 두었다.

동급 최강의 성능, 최고의 파워를 자랑하다.

액티언(Actyon)은 쌍용자동차가 국내 최고 수준의 커먼레일 디젤 엔진인 XDi270에 이어 독자 개발한 XDI200 XVT엔진을 사용하였다. 국내 동급 최강의 성능과 친 환경의 2.0리터 커먼레일 디젤엔진을 장착한 액티언(Actyon)은 경제적인 2WD 모델과 도심은 물론 오프로드도 충족시키는 4WD 모델의 5인승 SUV로써 스포츠 쿠페의 역동적이고 스포티한 디자인으로 구성돼 한눈에 젊은 감각과 우아한 세련미를 느낄 수있다. 액티언(Actyon)이 동급 최강의 성능과 편의성을 갖춘데다 젊은 세대들의 열정을 표현한 독특한 스타일로 남들과는 다른 개성을 추구하며 역동적인 에너지로 도전과 변화를 주도하는 20~30대 및 열정적 중년층을 사로잡아 SUV 풀 라인업을 구축, 시장 지배력 강화의 계기가 될 것이다. 액티언(Actyon)의 출시는 내수 침체로 주춤하던 SUV 시장에 활력을 불어넣는 동시에 기존 엔트리 SUV들의 취약점이었던 파워와 편의성 그리고 특색 없는 스타일을 대폭 보강한 독특하면서도 우아한 스타일로 SUV 대표 브랜드로 거듭날 것으로 보인다. 한편, 액티언(Actyon)은 완벽한 신차 품질을 위한 최종 마무리 작업을 거쳐 10월 중 고객들에게 첫 선을 보이며, 2006년에는 해외 시장에 진출할 계획이다.

– 사 양 –

◈ Actyon  제원 비교표 ◈                                
                                       
                     Actyon   스포티지    투싼       싼타페     카이런  (뉴코란도밴)
전장(mm)        4450        4350        4325        4500        4660        4340
전폭(mm)        1880        1820        1820        1845        1880        1855
전고(mm)        1739        1695        1695        1740        1746        1840
wheel/base     2740        2630        2630        2620        2740        2480
총중량(kg)       1950        1622        1627        1865        1995         2445
마력(hp)           145          115         115          126         176          95
차체TYPE       프레임   모노코크   모노코크   모노코크  프레임     프레임
연비(km/ℓ        12.1           12          12          10.2        10.6        
승차정원              5             5           5              7             7          2
최저지상고        195                                                   195          195