IBM®
메인 컨텐츠로 가기
    Korea [국가변경]    이용약관
 
 
   
        제품    서비스 & 솔루션    고객지원 & 다운로드    회원 서비스    
한국 developerWorks   >  Developer CoD  > developerworks

WTP에서 Axis2를 이용한 웹 서비스 구현하기 Part 2: 상품 검색 기능




CoD 신청자: 이상렬(pcguy7@gmail.com)
CoD 신청 내용: 요즘 이클립스 매력에 푹 빠진 개발자 입니다. WTP 플러그인과, Axis2 를 이용한 자바 기반의 웹서비스를 구현하고 관리하는 방법, WTP 플러그인을 이용한 웹서비스 클라이언트를 구현하고 관리하는 방법을 단순히 데모가 아닌 실프로젝트를 구축한다는 가정 하에 정리해 주었으면 합니다.


난이도 : 초급
2008년 1월 8일


웹 서비스 구현 시나리오 - 판매 프로세스

이번에 구현하는 시나리오는 판매 프로세스다.
[상품 검색] - [카테고리별 검색] - [물품 주문] - [미배송 상품 리스트 조회] - [배송 완료 전달]

고객은 Axis2Store에서 원하는 상품을 검색, 상품을 주문한다. 배송업체는 배송할 상품들을 조회한 후 물품을 집하한다.
배송업체는 배송을 마치면 Axis2Store에 배송이 끝났다는 내용을 전달한다.

위의 시나리오가 완료되는 데 있어 필요한 웹 서비스 기능들을 뽑아 보았다. 보는 관점에 따라 다른 기능이 도출될 수 있음을 유념하기 바란다.

  1. 상품 관련 기능
    1. 상품 검색 기능 제공
    2. 카테고리별 검색
  2. 배송 관련 기능
    1. 미배송 상품 목록 조회
    2. 위치별 분류
    3. 배송 완료 전달
이 기능들 중에서 상품 관련 기능을 WTP와 Axis2를 이용해 웹 서비스로 구현해 보겠다. 이 글은 판매 프로세스를 단순화하여 웹 서비스를 구현하는 데 목적을 두었기 때문에 모든 판매 프로세스를 설명할 수 없음을 양해 바란다.


웹 애플리케이션 생성

DB 생성

우선 웹 서비스에서 사용할 데이터베이스를 만들어 보자. MySQL콘솔을 실행하고 DB를 만들 수 있게 root 같은 관리자 계정으로 접근하여 아래와 같이 DB를 생성하고 권한을 부여한다. 여기서 설명하는 모든 작업은 MySQL GUI Tools 같은 GUI 도구를 이용해도 무방하다.

  

conosle> mysql -h localhost -u root -p
Enter password: XXXX

... 중략 ...

mysql> create database axis2store default charset utf8;
mysql> grant all privileges on axis2store.* to axis2store@localhost identified by 'axis2store' with grant option;

... axis2store로 접속한다.

mysql> use axis2store;
mysql> CREATE TABLE `products` (
  `id` varchar(50) default NULL,
  `name` varchar(100) default NULL,
  `category` varchar(50) default NULL,
  `cost` int(11) default NULL,
  `price` int(11) default NULL,
  `description` text
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

... 중략 ...
 

상품 관련 기능을 웹 서비스로 구축하기에 앞서 'products' 테이블을 만들었다. 나머지 customers, orders 테이블도 비슷하게 만들 수 있다.


예제 빈 객체 생성

앞서 웹 애플리케이션을 생성하고 애플리케이션 내에 빈(bean) 객체 하나를 만들고 그것을 처리하는 Manager 클래스를 만들었다. 비슷한 방법으로 시나리오에서 나온 객체들인 Product, Order를 생성한다. Manager 클래스는 DB 처리 부분을 설명한 후 다시 언급하겠다.

  

package axis2.store;

public class Product {
    private String id;
    private int price;
    private String description;
   
    public String getId() {
        return id;
    }
    ... 중략 ...
    public void setCost(int cost) {
        this.cost = cost;
    }
    ... 중략 ...
    public void setDescription(String description) {
        this.description = description;
    }
}
 

DB 연결

자바 애플리케이션과 MySQL 간의 인터페이스 연결을 위한 커넥터를 여기에서 다운로드할 수 있다. 압축을 푼 폴더 내의 mysql-connector-java-5.X.X-bin.jar만을 사용하기 때문에 적당한 곳에 두고 커넥터 jar 파일을 클래스 패스에 추가한다. OS 자체에서 클래스 패스를 지정하거나 배포될 톰캣에 사용할 jar를 추가할 수도 있다. 여기선 간단하게 Preferences - Java - Installed JRE에 add External JARs...으로 추가하였다. 데이터베이스와 애플리케이션간의 연결이 잘 되는지 간단한 조각코드를 통해 확인해 본다.

  

package axis2.store.util;

import java.sql.*;

public class DBConnTest {

    DBConnTest() {
        try {

            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/axis2store", "axis2store",
                    "axis2store");
           
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM customers;");
           
            while(rs.next()){
                System.out.print(rs.getString(1) + " : ");
                System.out.println(rs.getString(2));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new DBConnTest();
    }
}

데이터베이스를 연결하여 값을 가져오는 부분은 이미 관련 문서들이 많이 있기 때문에 상세한 설명은 생략하겠다. 콘솔에 입력된 사용자 ID와 이름이 나타나면 문제 없이 연결된 것이다.

데이터베이스를 이용한 개발시 잦은 DB 연결 호출의 성능 개선을 위해 데이터베이스 풀링(database pooling)이란 기법을 이용한다. 데이터베이스 풀링이란 DB 연결에 쓰이는 Connection 객체를 미리 생성해 담아 두어 필요할 때 사용하고 사용이 끝난 객체를 다시 반환하는 기법을 말한다. 사용자들이 자신들의 고유한 방법으로 구현한 API도 많이 있다. 이곳에 가면 자카르타에서 진행중인 DB 연결 풀링 프로젝트를 찾아 볼 수 있다.

예제 Manager 클래스 구현

Manager 클래스는 시나리오에서 설명한 기능(상품 검색 기능, 미배송 상품 리스트 조회 등)을 담고 있는 클래스다.

  

ProductManager.java
... 중략 ...
    public ArrayList<Product> listProducts(String keyword){
        ArrayList<Product> listProducts = new ArrayList<Product>();
        Connection conn = DBUtil.getConnection();
        Statement stmt;
        try {
            stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM products WHERE name like '%"
			+ keyword.toUpperCase().trim() + "%';");
            while(rs.next()){
                Product product = new Product();
               
                product.setId(rs.getString("id"));
                ... 중략 ...
                product.setPrice(rs.getInt("price"));
                product.setDescription(rs.getString("description"));
               
                listProducts.add(product);
            }
           
        } catch (SQLException e) {
            e.printStackTrace();
        }
       
        return listProducts;
    }
... 중략 ...

위의 listProducts기능은 키워드를 받아 검색한 후 해당 상품들을 ArrayList에 담아 반환하는 메서드다. 비슷한 방법으로 시나리오에 나온 기능들을 추가로 구현할 수 있다. 예를 들어, "SELECT * FROM customers c, orders o WHERE c.id = o.customerId;" 같은 쿼리문을 이용해 구매내역이 있는 OrderManager.listOrderCustomers의 메서드나 가장 많이 주문된 상품의 리스트를 반환하는 메서드 등을 추가로 구현할 수 있다.

본 예제에서 몇 가지 안 되는 기능을 위해 Manager 클래스를 만드는 것이 비효율적인 것처럼 보일 수 있으나 좀더 복잡한 시나리오를 구현하거나 Manager들간의 연계가 복잡해진다면 이러한 방법이 효율적이란 것을 느끼게 된다.

Manager 클래스 사용 예제

이렇게 만들어진 Manager 클래스를 다음과 같은 방법으로 사용할 수 있다.

  

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="java.util.ArrayList"%>
<%@page import="axis2.store.Product"%>
<%@page import="axis2.store.ProductManager"%>
... 중략 ...
<body>
<%
    ProductManager manager = new ProductManager();
    ArrayList<Product> list = manager.listAllProducts();
%>

<table border="1">
    <tr><th>ID</th><th>Name</th><th>Category</th><th>Value</th><th>Desc.</th></tr>
    <%
    for(int i = 0 ; i < list.size() ; i ++){
        Product product = list.get(i);
        %>
        <tr><td><%=product.getId() %></td><td><%=product.getName() %></td>
		<td><%=product.getCategory() %></td><td><%=product.getPrice() %></td>
		<td><%=product.getDescription() %></td></tr>
        <%
    }
    %>
</table>
</body>
</html>


ProductManager 객체에서 listAllProducts 메서드를 호출하여 모든 상품 리스트를 반환한 후 HTML 테이블로 렌더링하는 JSP 코드다.


웹 서비스 생성

이번에는 위에서 생성한 웹 애플리케이션에 웹 서비스를 생성하고 그것을 이용한 클라이언트를 만들어 보겠다. 다시 말해 웹 서비스를 제공하는 입장과 제공된 웹 서비스를 사용하는 입장을 모두 구현해 보는 것이다.


WTP에 AXIS2 설정

Axis2를 이용하여 웹 애플리케이션에 웹 서비스를 생성하면 지난 회에서 보았던 웹 기반 관리자 화면을 보여주기 위한 많은 파일이 /WebContent/axis2-web 폴더에 생성된다.

WTP 현재 버전에서는 기본적으로 Axis를 이용한 웹 서비스를 구축할 수 있는 마법사 화면을 볼 수 있다. 하지만 Axis2 엔진을 연결해주지 않았기 때문에 무심코 Axis2를 사용하려 하면 에러가 나온다. 먼저 Axis2를 이용하기 위해 Axis2 런타임 환경을 설정하자.

다음과 같이 Preferences -> Web Services -> Axis2 Preferences -> Axis2 Runtime Location에 다운로드해 압축 해제한 Axis2의 폴더를 지정한다.



웹 서비스를 구축하여 배포한 후에도 로직 또는 요구사항 변화로 기존에 구축된 웹 서비스를 여러 번 변경해야 할 때가 있다. 이 때 설정 정보를 매번 수정해야 하는 번거로움이 있는데 이는 Preferences -> Web Services -> Scenario Defaults, Server and Runtime를 적절하게 수정하면 좀더 쉽게 재구축할 수 있다.

웹 서비스 생성

위에서 생성한 웹 애플리케이션에 새로운 웹 서비스를 생성한다.

  1. File -> New -> Other... -> Web Services -> Web Service 선택 -> Next
  2. Web service type을 Bottom up Java bean Web Service로 선택
  3. Service implementation -> Browse... 클릭 후, ProductManager 선택
  4. Configuration의 Web service runtime 클릭 후, Apache Axis2 선택(서버는 톰캣 5.5를 사용하였다. 서버 설치는 지난 회를 참고한다)
Web service type에서 Bottom up Java bean Web Service를 선택하면 웹 서비스를 이용하여 배포할 기능을 담은 클래스를 이용하여 웹 서비스를 생성하고, Top down Java bean Web Service를 선택하면 배포된 웹 서비스가 제공하는, 혹은 기존 WSDL 파일을 이용해 웹 서비스를 생성한다.

클라이언트는 구축하지 않고, 서버에 웹 서비스를 생성하기 위해 Client 부분의 슬라이드는 가장 하단으로 내려 놓고 Next 버튼을 클릭한다.



지난 회에서는 직접 만들었던 service.xml을 자동 생성하는 부분이다. Next 버튼을 클릭한다. 서버를 실행하는 화면이 나오면 서버를 실행한다. 서버가 구동되면서 지난 회의 Simple Server를 구동할 때와 비슷하게 /WebContent/WEB-INF/modules와 services들이 로딩되는 것을 볼 수 있다.

다음으로 "Web Service Explorer"라는 페이지를 구동하는 화면이 나오는데 "Launch" 버튼을 클릭하면 브라우저가 실행되면서 Web Service Explorer가 나타난다. 이곳에서 웹 서비스가 잘 동작하는지 확인할 수 있다. 아래 그림(listAllProducts을 호출한 화면)을 보면 각각의 바인딩에 따라 제공하는 메서드(웹 서비스 메서드)를 보여주고 질의를 수행할 수 있는 UI를 제공한다.



정상적으로 웹 서비스가 생성되었다면 이 경로(http://localhost:8080/axis2/services/CustomerManager?wsdl)에서 WSDL 파일을 얻을 수 있을 것이다. 이제 지난 회에서 살펴보았듯이 WSDL 파일을 이용하여 클라이언트를 생성할 수 있다.


클라이언트 생성

이번엔 지난 회에서 살펴본 콘솔을 이용한 클라이언트 구축이 아닌 이클립스를 이용하여 클라이언트를 구축해 보자.

  1. File -> New -> Other... -> Web Services -> Web Service Client선택 -> Next
  2. Service definition -> Browser...를 선택하여 WSDL 경로 입력
  3. (http://localhost:8080/axis2/services/CustomerManager?ws이을 입력한 후 OK 버튼 클릭)
  4. Client type 부분의 슬라이드를 가장 상위까지 올린다.
  5. Configuration의 Web service runtime을 클릭 후, Apache Axis2 선택
  6. Client project: 부분을 클릭 후, 아래처럼 "axis2client"라고 직접 입력하고 OK를 클릭한다(직접 프로젝트 이름을 입력하면 새로운 프로젝트가 생성되고, 클라이언트 관련 코드들이 그곳에 생성된다).


클라이언트를 구축하기 위한 스텁 파일이 생성되었다. 이제 지난 회에서 설명한 방식으로 클라이언트를 구축하거나 웹이나 위젯 등과 같은 별도의 애플리케이션을 이용해 클라이언트 애플리케이션을 구축할 수 있게 되었다. 나머지 스텁을 이용한 클라이언트 프로그램은 독자들의 입맛에 맞춰 구축하기 바란다.



위로


   소셜 북마크

   mar.gar.in mar.gar.in
    digg Digg
    del.icio.us del.icio.us
    Slashdot Slashdot

결론

지금까지 판매 프로세스 중 상품 관련 기능들을 구현하고 그것을 웹 서비스에 등록, 그리고 클라이언트까지 생성해 보았다. 지난 회에서 언급했던 비슷한 내용을 WTP와 Axis2 플러그인을 이용해 수행하였다. 웹 서비스 탐색, 모니터링, 발행 등의 기능을 제공하는 이클립스 IDE를 이용하여 더 쉽게 구현할 수 있었다.



위로




참고 사이트

  1. Consuming Web service using Web Service Client
  2. Eclipse WTP Tutorials - Creating Bottom Up Web Service via Apache Axis2
  3. Using Web Service Explorer to test a Web service
  4. Get the most out of XML processing with AXIOM





필자 소개

김광섭김광섭 kwangsub.kim@gmail.com

서울대학교 치과의료정보기술전공 박사과정을 휴학하고 케이포엠(K4M)에서 전문연구요원으로 병역특례근무를 하고 있다. For the real semantic stuff를 운영한다.








developerWorks에 소개되었으면 하고 바라던 주제가 있으시거나, 관심 있는 기술에 대한 전문가의 지식과 견해가 궁금하시다면 Developer CoD 코너에 원하는 주제를 신청해주세요. 해당 분야 전문가를 필자로 섭외해, 여러분이 원하는 주제에 대한 맞춤형 컨텐츠를 제작해드립니다.
developer CoD 신청양식 다운로드   MS워드 아이콘   아래아한글 아이콘



[지난 Developer CoD 보기]


위로



사이트 여행

dW 커뮤니티
포럼 | 블로그 | Spaces
dW Student Community

로컬 컨텐츠

행사 및 세미나

기획 기사

개발자 입문

튜토리얼 및 교육

TOP 10 인기자료

SW 다운로드

RSS 피드

뉴스레터
  
자바스크립트가 작동이 중지되었습니다. 이 기능을 수행하시려면 브라우저에서 자바스크립스트를 작동시켜 주시거나 이곳을 클릭해주세요.
Special offers
IBM SOA Sandbox 시험판
dW Student Community
로보코드
코드 트레이닝


    IBM 소개 개인정보 보호정책 문의