728x90
반응형

이번에는 다른 방법으로 구현하는 것을 해 보겠다.
먼저 예전에는 명령어를 직접 치는 것으로 했는데.. 이넘이 상당히 불편하단 말이지.
그래서 SoapUI를 이용하여 넣어 보겠다.
그냥 해 보았는데 잘 되더라.

먼저 CXF를 설치한다. http://cxf.apache.org 에 가면 다운로드 받을 수가 있다.
그리고 SoapUI를 설치하도록 한다. http://www.soapui.org 에 가면 다운로드 받을 수 있다.
물론 자바는 설치해야지. 웹으로 만든다면 웹서버 까지.

1. CXF를 압축 풀어 원하는 디렉토리에 저장한다.
    - 나는 C:\Dev\apache-cxf-2.7.1 에 압축을 풀었다.
2. 환경변수를 등록하여 CXF\bin에 Path를 주도록 한다.
    - CXF_HOME 을 C:\Dev\apache-cxf-2.7.1 (설치디렉토리) 값으로 입력한다.
    - PATH 에 %CXF_HOME%\bin 을 주어 패스를 추가 시킨다.
    - cmd 창을 띄우고 wsdl2java.bat 명령이 실행되는지 확인한다. 실행 안된다면 위의 과정을 다시 보시라. 오래걸리므로 ctrl+c로 끊어라.
3. SoapUI를 설치하고 실행한다.
4. 먼저 주어진 WebSevice에 대하여 설정한다.
    - 프로젝트 생성

    - 웹서비스 등록 (프로젝트 명은 원하는 데로 입력하고 아래 WSDL URL을 정확히 입력한 후 OK 버튼을 누른다.)
    - 이렇게 만들어진 웹서비스에서 리쿼스트 값 입력(이 내부는 주어진 웹서비스에 의해 결정된다.)이 필요하면 입력을 하도록 한다.
    - 초록색 오른쪽 방향 화살표(Request 창의 제일 왼쪽 아이콘)을 눌러 값이 정확히 넘어오는지 확인한다.
       왼쪽이 입력 오른쪽이 출력이다.
    - 제대로 만들어 진 것 같다면 이제 아파치 CXF를 이용하여 웹서비스 클라이언트 파일(스텁, 클래스... 인가 하는 목록들)들을 만들기 위하여 메뉴를 누른다.

    - Tools 버튼을 눌러 먼저 CFX를 설정하여 준다.
    - Out Directory는 소스파일이 위치할 곳을 지정하고 패키지는 해당 패키지를 넣도록 한다.
    - 별 문제가 없다면 아래처럼 완료가 될 것이다.
    - 만약 JAX-WS API 2.2 와 관련한 문제가 생긴다면 해당하는 주석을 참조하여 -frontend jaxws21 옵션을 주어 생성한다(세번째 탭 참조).

    - 진짜로 생성 되었는지 확인한다.
    - 해당 소스를 실행하기 위해서는 다음과 같은 라이브러리가 클래스패스로 지정되어야 한다(CXF 2.7.1 버전 기준).

    axis.jar, commons-discovery-0.2.jar, commons-logging.jar, commons-logging-1.1.1.jar, cxf-2.7.1.jar, httpasyncclient-4.0-beta3.jar, httpclient-4.2.1.jar, httpcore-4.2.2.jar, httpcore-nio-4.2.2.jar, jaxrpc.jar, neethi-3.0.2.jar, saaj.jar, wsdl4j.jar, wsdl4j-1.6.2.jar, xmlschema-core-2.0.3.jar

소스에서 보면 알겠지만 설정한 대로 그대로 파일이 자동 생성 되었다.
항상 문제로 여기는 부분인 URL 부분. localhost가 그대로 들어가는 현상에 대해서는 결국 코딩이 필요한 부분일 것이다.
해당 부분은 결국 configuration으로 빼서 하는 작업이 필요하다.

이상 일차로 마치도록 한다. 소스를 자세히 보면 main 함수로 이미 구현 되어 있는 부분을 참조하여 코딩하면 될 것이다.

이차가 되나.. ㅋㅋ.
일단 클라이언트를 jsp로 구현 중이다.
URL 하드코딩 부분을 일단 해결하였다.
그리고 QName 생성하는 이 부분의 값은 OrderProcess_OrderProcessImplPort_Client 등의 클라이언트 구현 부분의 값을 참조하여 만들면 쉽다.
getQName("http://order.demo/", "OrderProcessImplService");  <== 클라이언트 구현 부분의 값을 참조



<%@ page contentType="text/html; charset=EUC-KR" %>

 

<%@page import="java.net.URL"%>
<%@page import="test.client.order.*"%>
<%@page import="javax.xml.namespace.QName"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%><html>
<%!
 //공통함수로 빼버린다.
 private static Map<String, QName> QNAME_MAP = new HashMap<String, QName>();
 private static Object o = new Object();
 
 public static QName getQName(String nameSpace, String implServiceNm){
  synchronized(o){
   if(!QNAME_MAP.containsKey(implServiceNm)){
    QName q = new QName(nameSpace, implServiceNm);
    QNAME_MAP.put(implServiceNm, q);
   }
  }
     return (QName)QNAME_MAP.get(implServiceNm);
 }
 public static URL getWsdlURL(URL url){
     String protocol = "http://";
     String server = "localhost:8090"; //추후에 컨피그레이션으로뺀다.
     String URL = url.toString().substring(7);
     URL = URL.substring(URL.indexOf('/'));
  try{
         return (new URL(protocol + server + URL));
  }catch(Exception e){
         e.printStackTrace();
   return null;
  }
 }
%>
<body>
<h3>테스트 </h3>
<%
 Order order = new Order();
 order.setC1("cfdsf");
 try{
  QName serviceName = getQName("http://order.demo/", "OrderProcessImplService");
     URL wsdlURL = getWsdlURL(OrderProcessImplService.WSDL_LOCATION);
        out.println(wsdlURL.toString());

        OrderProcessImplService ss = new OrderProcessImplService(wsdlURL, serviceName);
        OrderProcess port = ss.getOrderProcessImplPort();

        String result = port.processOrder(order);
        out.println("processOrder.result=" + result);

 }catch(Exception e){
  e.printStackTrace();
 }
%>
</BODY>
</HTML>

====================================================================================================
마지막으로 허접하지만 이 닭이 Webservice를 동적으로 호출 할 수 있는 함수를 포함해서 만들어 봤다.

1. test.jsp 소스

<%@page contentType="text/html; charset=EUC-KR" %>
<%@page import="test.client.order.Order"%>
<%@page import="test.client.order.OrderProcess"%>
<%@page import="test.client.test.TestProcess"%>
<%@page import="test.webservice.util.WebserviceUtil"%><html>
<body>
<h3>테스트 </h3>
<%
 Order order1 = new Order();
 order1.setC1("cfdsf");

 Order order2 = new Order();
 order2.setC1("cfd  sdf dff");
 try {
  //TestProcess 웹서비스 생성
  TestProcess testPort = (TestProcess) WebserviceUtil.getService("http://order.demo/", "TestProcessImplService", "test.client.test");
  //getTest 웹메소드 호출
  String result = testPort.getTest("dsaffd");
  out.println("getTest.result=" + result + "<br><br>");

  //OrderProcess 웹서비스 생성
  OrderProcess port = (OrderProcess) WebserviceUtil.getService("http://order.demo/", "OrderProcessImplService", "test.client.order");

  order1 = port.getOrder(order1);
  out.println("getOrder.result=" + order1.getC1() + "<br>");
  out.println("getOrder.result=" + order1.getC2() + "<br><br>");

  order2 = port.processOrder(order2);
  out.println("processOrder.result=" + order2.getC1() + "<br>");
  out.println("processOrder.result=" + order2.getC2() + "<br><br>");
 } catch (Exception e) {
  e.printStackTrace();
  out.println(e.toString());
 }
%>
</BODY>
</HTML>

2. test.webservice.util.WebserviceUtil 클래스
package test.webservice.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class WebserviceUtil {
 private static Map<String, QName> QNAME_MAP = new HashMap<String, QName>();
 private static Object o = new Object();

 //QName 관리 메소드
 public static QName getQName(String nameSpace, String implServiceNm) {
  synchronized (o) {
   if (!QNAME_MAP.containsKey(implServiceNm)) {
    QName q = new QName(nameSpace, implServiceNm);
    QNAME_MAP.put(implServiceNm, q);
   }
  }
  return (QName) QNAME_MAP.get(implServiceNm);
 }

 //동적 URL을 위한 메소드
 public static URL getWsdlURL(URL url) {
  //추후에 컨피그레이션으로뺀다. 개발자, 개발서버, 운영서버가 서로 다를 수 있으므로.
  String serverURL = url.getProtocol() + "://localhost:8090" + url.getFile();
  try {
   return (new URL(serverURL));
  } catch (Exception e) {
   e.printStackTrace();
   return null;
  }
 }

 public static Object getService(String nameSpace, String implServiceNm, String pakageNm) throws Exception {
  QName qname = getQName(nameSpace, implServiceNm);
  try {
   Class classObj = Class.forName(pakageNm + "." + implServiceNm);
   Field field = classObj.getField("WSDL_LOCATION");
   URL wsdlURL = getWsdlURL((URL) field.get(classObj));

   Service ss = (Service) (classObj.getDeclaredConstructor(URL.class, QName.class).newInstance(wsdlURL, qname));
   Method method = ss.getClass().getMethod("get"+ (implServiceNm.substring(0, implServiceNm.lastIndexOf("Service"))) + "Port");
   return method.invoke(ss);

  } catch (Exception e) {
   e.printStackTrace();
   throw e;
  }
 }
}

 


마지막으로 추가 하다가 하다가 안되면 다음과 같이 명령어로도 가능하다.
wsdl2java -d jaxbri -uri http://xxxx.com?wsdl

 

728x90
반응형
블로그 이미지

nineDeveloper

안녕하세요 현직 개발자 입니다 ~ 빠르게 변화하는 세상에 뒤쳐지지 않도록 우리모두 열심히 공부합시다 ~! 개발공부는 넘나 재미있는 것~!

,