ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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설정)과 그 종속적인 설정 파일이 존재한다.

     

    wsdl2java 간편한 웹서비스 클라이언트 생성

    웹서비스 제공자가 발행하는 WSDL만 있으면 손쉽게 웹서비스 클라이언트를 생성할 수 있다. Apache CXF 라이브러리를 다운로드하고 wsdl2java 명령어를 사용하여 손쉽게 자바 코드를 생성할 수 있다. �

    malchooni.name

     

    댓글 0

Designed by Tistory.