-
jax-ws 웹서비스 서버 구축하기프로그래밍/Web Service 2020. 2. 22. 14:44반응형
웹서비스는 서비스에 대한 정의서(WSDL)를 발행하여 클라이언트가 그 서비스를 어떻게 이용하면 되는지 보다 쉽게 알 수 있다.
자바 웹서비스는 자바 스펙 요구서(Java Specification Request) 224번에 기재되어있다. JSR 224에 보면 자바 1.5 이상에서 사용할 수 있다고 한다. 어노테이션도 1.5 이상부터 지원.
It will run on JavaTM 2 Platform, Standard Edition (J2SE) 1.5. 자바 웹서비스를 제공하는 심플 모듈 예제는 다음과 같은 순서로 구현하겠다.
- 요청 value object 구현.
package test.server.webservice.vo; /** * 요청 메세지 value object. * @author ijyoon */ public class ReqInfo { // 이름. private String name; // 주소. private String address; // 나이. private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
웹서비스 이용자가 제공자에게 어떤 요청 값을 보낼지 정의한 클래스이다. 이름, 주소, 나이 세 가지 정보를 제공자에게 보내도록 하였다.
- 응답 value object 구현.
package test.server.webservice.vo; /** * 응답 메시지 value object. * @author ijyoon */ public class ResInfo { // 응답 메세지. private String resultMessage; public String getResultMessage() { return resultMessage; } public void setResultMessage(String resultMessage) { this.resultMessage = resultMessage; } }
웹서비스는 제공자는 이용자에게 resultMessage란 값만 응답값으로 보내기로 한다.
- 웹서비스 서버 구현.
package test.server.webservice; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.ws.Endpoint; import test.server.webservice.vo.ReqInfo; import test.server.webservice.vo.ResInfo; /** * 개인정보 서비스 * @author ijyoon */ @WebService public class PersonalInfoService { /** * 개인정보를 등록한다. * Attach file 포함. * @param req * @return res */ @WebMethod public @WebResult(name="resInfo")ResInfo register(@WebParam(name="reqInfo")ReqInfo req){ // 요청값 출력. System.out.println("request message."); System.out.println(req.getName()); System.out.println(req.getAge()); System.out.println(req.getAddress()); // 응답 메세지 생성. String resMessage = req.getName() +" : "+ req.getAge() +" : " + req.getAddress(); // 응답 객체 생성 ResInfo res = new ResInfo(); res.setResultMessage(resMessage); return res; } /** * simple webservice test. * @param args */ public static void main(String[] args){ System.out.println("start web service."); Endpoint.publish("http://192.168.0.210:8080/personalInfoService", new PersonalInfoService()); } }
눈여겨 봐야 할 곳이 어노테이션으로 정의된 부분이다.
16line에 @WebService라는 어노테이션이 정의되었다. @WebService 어노테이션 API를 참조하면 6가지 엘리먼트가 존재한다. 지정하지 않을 경우 클래스명을 따라간다. 다음은 @WebService에 대한 6가지 엘리먼트를 설명한 것이다.
@WebService
– name
웹서비스의 이름을 정의하는 엘리먼트이다. WSDL 발행 시 portType 엘리먼트에 정의되는 이름이다.– targetNamespace
타켓네임스페이스를 정의하는 엘리먼트이다. WSDL 발행 시 definitions 엘리먼트의 targetNamespace 속성과 연관이 있다.– serviceName
WSDL 발행시 service 엘리먼트에 정의되는 이름이다.– portName
WSDL 발행시 port 엘리먼트에 정의되는 이름이다.– wsdlLocation
기존에 발행된 WSDL 파일이나 URL을 참조한다.– endpointInterface
구현클래스와 인터페이스를 분리할 수 있으며 분리된 인터페이스에 풀 패키지를 값으로 설정한다.@WebMethod 어노테이션은 target value가 메소드이기 때문에 메서드에만 선언할 수 있다. 앞서 본 예제의 25 line에 해당한다.
@WebMethod
– operationName
WSDL 발행시 operation 엘리먼트에 정의되는 이름이다.– action
soap:operation엘리먼트의 soapAction 속성 값을 정의한다.– exclude
웹메소드에 포함하지 않는다. exclude=true 설정을 하면 WSDL발행 시 해당 메서드(오퍼레이션)는 제외된다.위의 내용을 참조하여 구현했던 클래스의 @WebService, @WebMethod(16,25 line)의 엘리먼트를 수정하여 WSDL을 확인해 보자.
/** * 개인정보 서비스 * @author ijyoon */ @WebService(name="PInfo_by_ijyoon", portName="PInfoPort", serviceName="PInfoService", targetNamespace="http://malchooni.name/PInfo") public class PersonalInfoService { /** * 개인정보를 등록한다. * Attach file 포함. * @param req * @return res */ @WebMethod(operationName="PInfoOpr",action="PInfoAction") public @WebResult(name="resInfo")ResInfo register(@WebParam(name="reqInfo")ReqInfo req){ // 요청값 출력. System.out.println("request message."); } }
– 수정 전 WSDL
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://webservice.server.test/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://webservice.server.test/" name="PersonalInfoServiceService"> <types> <xsd:schema> <xsd:import namespace="http://webservice.server.test/" schemaLocation="http://192.168.0.210:8080/personalInfoService?xsd=1" /> </xsd:schema> </types> <message name="register"> <part name="parameters" element="tns:register" /> </message> <message name="registerResponse"> <part name="parameters" element="tns:registerResponse" /> </message> <portType name="PersonalInfoService"> <operation name="register"> <input wsam:Action="http://webservice.server.test/PersonalInfoService/registerRequest" message="tns:register" /> <output wsam:Action="http://webservice.server.test/PersonalInfoService/registerResponse" message="tns:registerResponse" /> </operation> </portType> <binding name="PersonalInfoServicePortBinding" type="tns:PersonalInfoService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="register"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <service name="PersonalInfoServiceService"> <port name="PersonalInfoServicePort" binding="tns:PersonalInfoServicePortBinding"> <soap:address location="http://192.168.0.210:8080/personalInfoService" /> </port> </service> </definitions>
– 수정 후 WSDL
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://malchooni.name/PInfo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://malchooni.name/PInfo" name="PInfoService"> <types> <xsd:schema> <xsd:import namespace="http://malchooni.name/PInfo" schemaLocation="http://192.168.0.210:8080/personalInfoService?xsd=1" /> </xsd:schema> </types> <message name="PInfoOpr"> <part name="parameters" element="tns:PInfoOpr" /> </message> <message name="PInfoOprResponse"> <part name="parameters" element="tns:PInfoOprResponse" /> </message> <portType name="PInfo_by_ijyoon"> <operation name="PInfoOpr"> <input wsam:Action="PInfoAction" message="tns:PInfoOpr" /> <output wsam:Action="http://malchooni.name/PInfo/PInfo_by_ijyoon/PInfoOprResponse" message="tns:PInfoOprResponse" /> </operation> </portType> <binding name="PInfoPortBinding" type="tns:PInfo_by_ijyoon"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="PInfoOpr"> <soap:operation soapAction="PInfoAction" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <service name="PInfoService"> <port name="PInfoPort" binding="tns:PInfoPortBinding"> <soap:address location="http://192.168.0.210:8080/personalInfoService" /> </port> </service> </definitions>
@WebParam과 @WebResult는 요청,응답 xml 스키마 발행 시 엘리먼트의 이름과 연관이 깊다. 두 어노테이션은 따로 언급하지 않겠다.
마지막으로 만든 모듈을 서비스 해 보겠다. was 기반이 아닌 간단하게 서비스 발행하려면 javax.xml.ws.Endpoint 클래스의 publish 메서드를 사용하면 프로바이더를 생성하여 준다.
/** * simple binding test. * @param args */ public static void main(String[] args){ System.out.println("start web service."); Endpoint.publish("http://192.168.0.198:8080/personalInfoService", new PersonalInfoService()); }
파라미터로 URL과 해당 웹서비스의 객체를 넘겨주었다. 서비스 주소 끝에 ?wsdl 파라미터를 넘겨주면 서비스의 WSDL을 열람할 수 있다.
http://192.168.0.198:8080/personalInfoService?wsdl was기반에 올려야 할 경우 구현된 서블릿클래스가 있는 라이브러리를 참조한다. 대표적으로 apache cxf와 metro, apache axis 여러가지가 있다. 라이브러리 별로 web.xml(servlet class설정)과 그 종속적인 설정 파일이 존재한다.
반응형'프로그래밍 > Web Service' 카테고리의 다른 글
wsdl2java 간편한 웹서비스 클라이언트 생성 (0) 2020.09.09 apache cxf 클라이언트 생성하기 (0) 2020.02.22