이번에는 다른 방법으로 구현하는 것을 해 보겠다.
먼저 예전에는 명령어를 직접 치는 것으로 했는데.. 이넘이 상당히 불편하단 말이지.
그래서 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
'JAVA' 카테고리의 다른 글
[Java Tips] 날짜 비교하는 법 (0) | 2014.03.27 |
---|---|
java 날짜수계산 질문 드립니다 (0) | 2014.03.27 |
JAVA(자바)로 이번주 초와 이번주 말을 찾고싶을때 (0) | 2014.03.27 |
CXF를 이용한 Webservice 서버 구축 (0) | 2014.03.11 |
[JAVA] 문서파일 생성하여 다운 (0) | 2014.03.05 |
<JAVA_API> JAVA Program 수행시간 체크 : Time Checking (0) | 2014.03.04 |
[JAVA] 현재 날짜(시간) 구하기 - 월/요일을 한글/영문으로 간단하게 구하기 (0) | 2014.03.04 |
JAVA로 영문 대,소문자+숫자 난수 발생시키기 (0) | 2014.02.28 |