1. 브라우저를 통하여 wsdl 에 접근하여 해당 파일을 별도로 저장하여 클래스 패스에 위치시킵니다.
2. wsdlDocumentUrl 프로퍼티를 classpath 에서 읽을 수 있도록 설정합니다.
(해당 wsdl 자체에 접근하려면 인증이 필요한데 wsdl 을 읽을 단계에서는 인증처리가 안되기 때문입니다.)
3. username, password 프로퍼티를 설정합니다.
4. 웹 메소드 호출을 수행합니다.
username 과 password 가 옳지 않으면 다음과 같은 오류가 발생합니다.
Caused by: com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 401: Unauthorized
회사에서 개발하는 솔루션이 spring framework 기반이라 웹서비스도 spring webservices 로 구축을 하였는데, JBoss 에 올리려고 하니 여러 오류가 생겨 재 작년부터 고민하고 여러가지 시도를 하였으나 실패를 하였습니다.
우연히 다른 것을 검색하다가 발견한 것에서 아이디어가 떠올라서 여러가지 실험을 해본 결과 JBoss 용 웹 서비스를 publish 하는 데 성공하였습니다.
기존의 Spring WebServices Class
별 다른 작업 없이 DI 를 이용하여 service 객체를 이용하여 웹 서비스를 제공하였습니다.
JBossWS 에서 Spring Bean 사용하는 WebService Class
JBossWS 에서는 @Resource 라는 어노테이션을 이용하여 ThreadLocal 한 WebServiceContext 객체를 설정할 수 있습니다.
메소드에 어노테이션 설정하여 WebServiceContext 객체가 웹 서비스 객체에 설정이 될 때 Spring Bean 을 WebApplicationContext 를 이용하여 가지고 오는 방법을 사용하였습니다.
이렇게 구성된 웹 서비스를 JBoss 에 publish 하는 방법은 단순합니다.
web.xml 에 servlet 과 servlet-mapping 에 웹 서비스 클래스를 등록하는 것이 전부입니다.
Spring WebService 로 publish 할 경우 별도의 포트로 binding 해야 하지만 JBossWS 는 JBoss 포트로 서비스가 가능합니다.
그래서 시스템의 모든 ethernet 컨트롤러를 조사하여 각각의 endpoint 로 배포하는 것을 맹글어 보았습니다.
모든 소스를 다 구현할 수는 없기에 org.springframework.remoting.jaxws.AbstractJaxWsServiceExporter 클래스를 토대로 작업을 하였습니다.
[#M_LocalMultiJaxWsServiceExporter.java 소스 보기|접기|
org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter 를 이용하여 웹서비스를 등록할경우 호스트를 하드코딩해야 해서 개발과 운영서버에 각각의 아이피를 적어줘야 하는 불편함이 있었습니다. 그래서 초큼 수정해보았습니다.
LocalJaxWsServiceExporter.java
스프링 설정
과연 국내에서 Spring 으로 웹서비스하는 사람은 나밖에 없는건가 -_ㅜ... 검색을 해도 안걸리네...
- @MTOM: binary attachment 전송을 위한 어노테이션
- @SOAPBinding(style = SOAPBinding.Style.RPC)... 이건 무슨 말인지 모르겠습니다.
아래와 같은 설명이 어딘가에 있더라구요... 해석이 딸리므로... 읽으시는 분께 맡기겠습니다.
그러나 해당 어노테이션이 정의되어 있지 않으면 클라이언트쪽에서 제너레이션 된 메소드의 파라미터가
byte[] 이 아닌 DataHandler 가 되므로 일단 어노테이션을 위와 같이 설정합니다.
No, this is specified by the SOAPBinding annotation on the service class. Notice this in the original post above:
@SOAPBinding(style = SOAPBinding.Style.RPC)
This is telling wsgen that this is an rpc/literal service. A document/literal (doc/lit) service is specified thusly:
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
Actually, things are a little more complicated. This is actually specifying a doc/lit/wrapped service, meaning that the SOAP message body can contain multiple parameters. By contrast, in a doc/lit/bare service, the SOAP message body can contain only one parameter. For all the gory details, see the Annotations section of the JAX-WS User's Guide.
ㅁ Client Side kr/co/vicki/client/conf/webservicesContext.xml
kr/co/vicki/client/Client.java
서버의 public void fileUpload(String filename, DataHandler handler) 메소드는
클라이언트에서 public void fileUpload(String filename, byte[] arg1) 로 제너레이션 됩니다.
파일을 byte[] 로 변환하여 파일명과 함께 넘겨주게 되면 서버쪽에서 inputStream 으로 접근이 가능하게 됩니다.
첨부파일을 7KB와 4MB, 20MB 로 테스트 해본결과 20MB 는 힙 메모리 부족이라는 익센션을 날려주었습니다.
JAX-WS User Guide를 보면 용량 제한하는 어노테이션도 보이던데 테스트는 해보지 못했습니다.
이걸 해보며서 알게된 사항은 org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter 이놈은 한 컨텍스트에
한개의 웹서비스를 Export 해주는 것 같습니다. 크흑..
You may find the release notes for each of the components linked above.
Other than a few new features listed in the release notes, there are many bug fixes in this release.
Many of these bugs /feature enhancement requirements were led from the discussions in Metro forum and filed by external users. This improves significantly the quality and usability of Metro.
이제는 클라이언트 쪽 소스를 만들어서 테스트를 해봐야겠죠?
build.xml 의 generate-WorkflowFormWebServicetarget 을 실행시키면 클라이언트 소스가 jar로 묶여서 나옵니다.
jar 를 풀어서 보면 아래와 같은 파일들이 있습니다. 저기 아래보이는 WorkflowFormWebService 가 serviceInterface 입니다.
위에 있는 wsdl 파일을 참조하여 아래 내용을 채워 넣습니다.
클라이언트 소스 테스트는 아래와 같이...
별도의 테스트 소스를 만들어서 올리고 싶지만 시간이 없는 관계로 이렇게 되었습니다.
나중에 시간이 되면 스크린캐스트로다가 샤샥...