Microsoft MVP성태의 닷넷 이야기
Java: 8. 닷넷 개발자가 구현해 본 자바 웹 서비스 (2) [링크 복사], [링크+제목 복사],
조회: 29193
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

닷넷 개발자가 구현해 본 자바 웹 서비스 (2)


지난번의 경우,

닷넷 개발자가 구현해 본 자바 웹 서비스 (1)
; https://www.sysnet.pe.kr/2/0/1130

개발 환경 구성하고 어떻게든 예제를 돌리느라 바빴는데요. 이제 여유를 가지고 잠시 살펴보면.

우선, 닷넷에 생성된 프록시 코드의 차이점을 파악해 보겠습니다.

(WCF를 제외하고) 닷넷의 웹 서비스인 asmx 서비스에 대해 프록시 코드를 만들면 보통 다음과 같은 식으로 메서드에 SoapDocumentMethod 특성이 부여됩니다.

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Echo", 
    RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/",
    Use=System.Web.Services.Description.SoapBindingUse.Literal, 
    ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

public string Echo(string text) {
    object[] results = this.Invoke("Echo", new object[] {text};
    return ((string)(results[0]));
}


반면, 자바 쪽 웹 메서드를 호출하는 프록시 코드에는 SoapRpcMethod 특성이 부여되었습니다.

[System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="http://DefaultNamespace", 
        ResponseNamespace="http://localhost:8080/axis/services/HelloService")]
[return: System.Xml.Serialization.SoapElementAttribute("EchoReturn")]

public string Echo(string text) {
    object[] results = this.Invoke("Echo", new object[] {text});
    return ((string)(results[0]));
}

닷넷의 asmx는 기본적으로 Document 스타일임을 알 수 있는데, 물론 RPC 스타일로 변경하는 것도 가능합니다. 방법도 아주 쉬운데요, 그냥 아래와 같이 asmx 파일 안의 웹 메서드 정의를 포함하고 있는 클래스에 SoapRpcService 특성만 지정해 주면 됩니다. (또는 메서드 단위로 SoapRpcMethod 특성을 지정할 수 있습니다.)

[SoapRpcService()] 
public class WebService1 : System.Web.Services.WebService
{
    [WebMethod]
    public string HelloWorld()
    {
        return "Hello World";
    }
}

참고로, Document/literal, Rpc/literal, Document/literal wrapped 방식이 있는데, 이에 대해서는 다음의 글이 도움이 될 것입니다. (WS-I Basic Profile에서 encoded 사용은 더 이상 허용하지 않기 때문에 그 방식은 잊어버리시는 것도 좋겠습니다.)

Which style of WSDL should I use?
; http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/

마이크로소프트의 경우, 정확히는 Document/literal wrapped 스타일의 SOAP 구현을 하고 있으며 지난번 구현했던 Axis 예제는 Rpc/Encoded 방식의 웹 서비스를 구현한 예제였던 것임을 알 수 있습니다.




자바 예제를 좀 더 확장해 볼까요? 기본 타입 값이 아닌 Complex 타입을 반환하도록 다음과 같이 수정해 보겠습니다.

===== HelloService.java =====
public class HelloService {

    public String Echo(String text)
    {
        return "Hello " + text;
    } 
    
    public Person EchoPerson(String name)
    {
        Person person = new Person();
        person.name = name;
        person.age = 5;
        
        return person;
    }
}

===== Person.java =====
public class Person {
    public String name;
    public int age;
}

노출되어야 할 메서드가 추가되었으므로 deploy.wsdd 파일 역시 변경 사항을 반영시켜줍니다.

<deployment name="test" xmlns="http://xml.apache.org/axis/wsdd/" 
    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

  <service name="HelloService" provider="java:RPC">
    <parameter name="className" value="HelloService"/>
    <parameter name="allowedMethods" value="*"/>
  </service>

</deployment>

Axis에 배포해주고, 프록시를 업데이트 한 후 닷넷 클라이언트 프로그램을 실행하면 이번엔 다음과 같이 오류가 발생합니다.

Unhandled Exception: System.InvalidOperationException: Response is not well-formed XML. ---> System.Xml.XmlException: Root element is missing.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlTextReader.Read()
   at System.Xml.XmlReader.MoveToContent()
   at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   --- End of inner exception stack trace ---
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   at ConsoleApplication1.localhost.HelloServiceService.EchoPerson(String name) in D:\...[생략]...\ConsoleApplication1\Web References\localhost\Reference.cs:line 114
   at ConsoleApplication1.Program.Main(String[] args) in D:\...[생략]...\ConsoleApplication1\Program.cs:line 14
Press any key to continue . . .

이 순간의 네트워크를 가로채 보면 단서가 있을까요?

======= 요청 =======
POST http://192.168.50.132:8080/axis/services/HelloService HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.235)
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Host: 192.168.0.132:8080
Content-Length: 610
Expect: 100-continue
Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost:8080/axis/services/HelloService" xmlns:types="http://localhost:8080/axis/services/HelloService/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:EchoPerson xmlns:q1="http://DefaultNamespace"><name xsi:type="xsd:string">test1</name></q1:EchoPerson></soap:Body></soap:Envelope>

======= 응답 =======
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Date: Thu, 22 Sep 2011 02:07:52 GMT
Content-Length: 0

불친절한 Axis군요. 가타부타 아무런 오류 메시지도 없이 200 OK를 보내주다니. ^^;

원인은 책을 찾아보고 나서야 알았습니다. 자바는 RPC 스타일의 경우 클래스 타입에 대해서 get/set 메서드에 대한 정의를 별도로 추가해야 한다는 것입니다. 따라서, Person 클래스는 다음과 같은 코드들이 부가적으로 작성됩니다.

public class Person {

    public String name;
    public int age;
    
    public String getName()
    {
        return name;
    }
    
    public void setName(String name)
    {
        this.name = name;
    }
    
    public int getAge()
    {
        return age;
    }
    
    public void setAge(int age)
    {
        this.age = age;
    }
}

이뿐만이 아니라, 이에 대한 매핑을 wsdd 파일에도 지정해 주어야 합니다.

<deployment name="test" xmlns="http://xml.apache.org/axis/wsdd/" 
    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

  <service name="HelloService" provider="java:RPC">
    <parameter name="className" value="HelloService"/>
    <parameter name="allowedMethods" value="*"/>
    <!--parameter name="wsdlServicePort" value="Echo"/-->
  </service>

  <beanMapping qname="ns:Person" xmlns:ns="http://test.com" languageSpecificType="java:Person">  
  </beanMapping>

</deployment>

오호~~~ 이거 불편함이 장난 아닌데요. ^^;

암튼, 이렇게 하고 다시 AdminService로 배포해 준 다음 닷넷 클라이언트 측의 프록시 코드를 업데이트 하고 실행해 주면 정상적으로 메서드 수행 결과값을 반환받을 수 있습니다.

여기까지 해서, 자바 Axis의 Rpc/encoded 방식으로 구현된 웹 서비스를 살펴보는 것이 끝났습니다.




원래는, 한 단계 더 나아가서 Axis로 Document 스타일의 SOAP 서비스를 실습해 보려고 했는데요. 닷넷 개발자로써는 도저히 현실적이지 않은 이유로 인해 포기했습니다.

왜냐하면, Axis의 Document 스타일은 Message라는 것에 너무 충실한 나머지 다음과 같은 식의 signature만 하용이 되기 때문입니다.

Service Styles - RPC, Document, Wrapped, and Message
 - Document / Wrapped services
; http://ws.apache.org/axis/java/user-guide.html#ServiceStylesRPCDocumentWrappedAndMessage

public Element [] method(Element [] bodies); 
public SOAPBodyElement [] method (SOAPBodyElement [] bodies); 
public Document method(Document body); 
public void method(SOAPEnvelope req, SOAPEnvelope resp); 

느낌이 오시죠? 말 그대로 XML 문서를 수작업으로 구성해서 메서드에 전달하고, 다시 반환값을 XML 파서로 select해 가면서 값을 받아와야 하는 구조입니다.

이렇게 구현된 Axis 웹 서비스를 닷넷에서 WSDL 코드 생성기를 거치면 다음과 같은 식으로 나옵니다.

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", 
    Use=System.Web.Services.Description.SoapBindingUse.Literal, 
    ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlElementAttribute("getTimeReturn", Namespace="http://localhost:8080/axis/services/TimeService")]

public object portfolio([System.Xml.Serialization.XmlElementAttribute("getTime", Namespace="http://DefaultNamespace")] object getTime1) {
    object[] results = this.Invoke("getTime", new object[] {
                getTime1});
    return ((object)(results[0]));
}

그렇습니다. object 인자에 object 반환값의 메서드로 asmx에서는 SoapParameterStyle.Bare 유형이 바로 Axis의 Document 스타일이었던 것입니다.




위의 실습을 해보고 나니, 개인적으로 설마 자바 개발자들이 Axis를 가지고 웹 서비스를 만들고 있을 거라는 생각은 들지 않더군요. 아마도 좀 더 나은 상용 웹 서비스 기반 도구가 있지 않을까 싶은데... 제가 거기까진 조사를 못했습니다.

어느 정도까지 자바의 상용 웹 서비스 도구들이 편할지는 알 수 없지만, 일단 이 정도만 봐서는 적어도 웹 서비스 환경만큼은 역시 마이크로소프트 제품만한 것이 없는 것 같습니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 7/10/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 181  182  183  184  185  186  [187]  188  189  190  191  192  193  194  195  ...
NoWriterDateCnt.TitleFile(s)
285정성태6/20/200622528오류 유형: 9. [TFS] Report 관련 서비스를 조회할 때 rsErrorImpersonatingUser 오류 메시지 발생 [1]
284정성태6/19/200620259VS.NET IDE: 40. FxCop - IDE 에서 제공해 주는 SuppressMessage 코드
283정성태1/19/200721122Team Foundation Server: 8. 소스 세이프에서 TFS SourceControl 로 마이그레이션 [2]
279정성태12/27/200626491개발 환경 구성: 3. VS.NET 원격 디버깅 [1]
280정성태6/12/200625999    답변글 개발 환경 구성: 3.1. VS.NET 2003 원격 디버깅 설정
281정성태8/11/200627473    답변글 개발 환경 구성: 3.2. VS.NET 2005 원격 디버깅 설정
315정성태8/11/200628137        답변글 개발 환경 구성: 3.3. VS.NET 2005 원격 디버깅 설정 - ASP.NET F5 디버깅
278정성태6/11/200624684오류 유형: 8. [Outlook] 0x8004011D 에러 - "Exchange over the Internet" 환경
276정성태6/7/200618218Team Foundation Server: 7. 외부 빌드 머신 구성
287정성태6/24/200615812    답변글 Team Foundation Server: 7.1. 외부 빌드 머신 구성 - 다른 블로그 자료
275정성태6/7/200623660디버깅 기술: 4. VC++ 8.0 원격 디버깅 구성 - Side-by-Side DLL 문제.
269정성태6/6/200620892Team Foundation Server: 6. HTTPS를 통한 Team Server 접근 [1]
270정성태6/5/200617831    답변글 Team Foundation Server: 6.1. HTTPS를 통한 Team Server 접근 [1]
273정성태6/6/200620557    답변글 Team Foundation Server: 6.2. 두번째 방법 - HTTPS 를 통한 Team Server 접근 [1]
267정성태6/4/200619879Team Foundation Server: 5. 인터넷으로 Team Server 접근 [2]
266정성태6/8/200616484오류 유형: 7. [설치] mpoai9.dll 관련 오류
265정성태6/1/200624205디버깅 기술: 3. 원격 컴퓨터 디버깅 - VPC 설정
314정성태8/11/200621242    답변글 디버깅 기술: 3.1. Managed 원격 디버깅과 WinDBG 원격 디버깅
264정성태6/1/200630314오류 유형: 6. [VC++ 컴파일] already defined in ntdll.lib(ntdll.dll)
263정성태6/1/200631304디버깅 기술: 2. 커널 구조체 살펴보기 [5]
262정성태6/1/200623587오류 유형: 5. [설치] WinFX Beta2 - 설치시 문제점 해결
261정성태6/1/200620077웹: 3. IIS 6.0 - AppPool을 활용하여 실 서버(운영 서버)에서 디버깅
258정성태6/1/200627990디버깅 기술: 1. 디버깅 방법 - CLR 프로파일러 [1]파일 다운로드1
274정성태6/7/200620898    답변글 디버깅 기술: 1.1. 디버깅 방법 - CLR 프로파일러 ( on Vista )
254정성태6/1/200617412개발 환경 구성: 2. VPC에 Vista 설치하는 방법 [2]
255정성태6/1/200617078    답변글 개발 환경 구성: 2.1. msconfig 설정과 Windows Activation
... 181  182  183  184  185  186  [187]  188  189  190  191  192  193  194  195  ...