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

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

아직, 자바에 대한 큰 그림이 그려지지 않아서 정확히는 모르겠지만 자바에서는 자체적인 클래스 라이브러리에 웹 서비스 기능이 포함되어 있지 않아서, 공개된 외부 라이브러리를 사용해야 하는 것 같습니다. 자바 웹 서비스로 검색해 보면, 대표적으로 "Apache SOAP 3.0"이 나오는데 그 이름보다는 Axis(Apache eXtensible Interaction System)라고 알려주면 아시는 분들이 더 많을 것입니다. ^^ 저 역시 예전에 자바 개발자와 일한 적이 있었는데, 웹 서비스 노출을 Axis로 했다고 해서 ^^ 들어보기는 했었습니다.

Apache Web Services - Axis
; http://ws.apache.org/axis/

마지막 업데이트가 2006년 4월의 1.4 버전이니, 5년이 넘었군요.

Axis를 얹을 웹 서버가 필요한데, 저는 쉽게 Tomcat 기반으로 해보았습니다. (아직, 웹 로직 같은 것은 잘 모르는 단계입니다. ^^) 웹 검색을 해보면 다행히 이에 대한 자료가 쉽게 검색됩니다.

Axis 설치 및 톰캣과의 연동
; http://tequiero35.egloos.com/901100

(닷넷과 비교해서) 자바의 웹 서비스가 특이한 점이 있다면, XML 파서가 별도로 존재한다는 점입니다. 아마도 기본 파서가 있는 것 같은데, 외부에서 제공된 더 나은 XML Parser를 plug-in식으로 사용하는 것이 가능한 것 같습니다. 알아본 바로는, 보통 Xerces XML Parser를 쓰는 것이 권장된다고 하는데, 톰캣의 경우 기본 라이브러리에 포함되어 있다고 하지만 웹 서비스 접속을 하는 클라이언트 측 어플리케이션의 경우에는 xerces.jar 파일을 같이 배포해 주어야 한다고 합니다.





Tomcat에 Axis 설치

자, 그럼 이제 Axis를 Tomcat에 설치해 보겠습니다. 사실 윈도우 사용자들은 설치하면 setup.exe를 떠올릴 텐데 자바 쪽으로 오게 되면 전부 '파일 복사' 정도로 생각하시면 편합니다.

따라서, Axis 역시 다운로드한 파일의 압축을 풀고, [axis 폴더]\webapps\axis 폴더를 [tomcat 설치폴더]\webapps\axis 폴더로 복사해 주는 것으로 설치 과정이 끝납니다.

java_webservice_0.png

확인을 위해 tomcat을 실행하고 "http://localhost:8080/axis/" 경로를 방문해서 다음과 같이 나오면 정상적으로 설치가 된 것입니다.

java_webservice_1.png

위의 단계는 Axis 모듈이 잘 구동되고 있다는 사실만을 알려주는 것이고, 부가적으로 Axis가 주변 라이브러리와의 연동을 통해 정상적인 웹 서비스를 할 수 있는 환경이 마련되어 있는지를 확인하기 위해 위의 링크에서 "Validation"을 눌러서 방문해 보는 것이 좋습니다.

참고로, 위의 그림에 나온 "List"에 한번 관심을 가져볼까요? ^^ 이를 누르면 다음과 같이 2가지 웹 서비스가 나열됩니다.

java_webservice_2.png

이 중에서 "AdminService" 항목이 재미있는데요. 닷넷의 경우에는 asmx 파일을 Web Application 폴더에 복사하고 asmx.cs 파일이 빌드된 것을 /bin 폴더에 위치시키기만 하면 웹 서비스가 가능해지는데요. (닷넷의 용어와 비교해서 설명하면) Axis에서는 웹 서비스의 주소 역할을 하는 asmx가 없는 대신 별도의 등록 과정을 거쳐야만 asmx.cs에 해당하는 .class 파일이 외부로 노출이 됩니다. 바로 그 등록 과정을 위해 Axis에서는 AdminService라는 웹 서비스를 제공해 주는 구조입니다.

자바는 위와 같이 .class 파일을 배포하는 것 외에, 소스 코드인 .java 파일을 확장자만 .jws로 바꿔서 배포하는 것도 가능합니다. 그런데, 소스 코드의 보안 상 .jws보다는 .class 파일 배포가 (불편함에도 불구하고) 더 선호된다고 합니다.

자, 그럼 준비가 되었으니 이 정도 지식을 가지고, 한번 도전해 볼까요? ^^





1. .class 유형으로 배포되는 자바 웹 서비스 제작

이클립스에 임의의 프로젝트를 하나 만들고, HelloService.java 파일을 추가합니다.

public class HelloService {

    public String Echo(String text)
    {
        return "Hello " + text;
    }
}

빌드를 한 후, HelloService.java 파일이 있는 폴더에 deploy.wsdd라는 텍스트 파일을 만들고, Axis 압축을 해제한 폴더의 하위에서 '\samples\stock\deploy.wsdd'의 내용을 적당히 베껴 다음과 같이 내용을 채워넣습니다. (아직 제 수준에서 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="Echo"/>
    <parameter name="wsdlServicePort" value="Echo"/>
  </service>

</deployment>

그리고 나서, 다음과 같은 빌드 및 배포를 할 수 있는 배치(Batch) 파일을 만듭니다.

REM =========== 아래와 같이 CLASSPATH를 걸어줘야
set CLASSPATH=.;D:\Interop\axis-1_4\lib\axis.jar;D:\Interop\axis-1_4\lib\jaxrpc.jar;D:\Interop\axis-1_4\lib\log4j-1.2.8.jar;D:\Interop\axis-1_4\lib\commons-logging-1.0.4.jar;D:\Interop\axis-1_4\lib\commons-discovery-0.2.jar

REM =========== 이 단계에서 org.apache.axis.client.AdminClient를 찾아서 실행하는 것이 가능하고,
REM =========== AdminClient 클래스는 "-l" 옵션으로 지정된 웹 서비스를 호출해서 deploy.wsdd의 내용을 등록
java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd

REM =========== .class 파일을 tomcat에 배포된 Axis에서 찾을 수 있도록 복사
robocopy ..\bin ...[tomcat 설치 폴더]...\webapps\axis\WEB-INF\classes HelloService.class


이쯤에서 톰캣을 실행해 두고 위의 배치 파일을 실행하면 정상적으로 등록된 경우 다음과 같은 출력 결과를 볼 수 있습니다.

...[생략]...>set CLASSPATH=.;..[생략]...\axis-1_4\lib\axis.jar;...[생략]...\axis-1_4\lib\jaxrpc.jar;...[생략]...\axis-1_4\lib\log4j-1.2.8.jar;...[생략]...\axis-1_4\lib\commons-logging-1.0.4.jar;...[생략]...\axis-1_4\lib\commons-discovery-0.2.jar

...[생략]...\workspace\Test1\src>java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd
log4j:WARN No appenders could be found for logger (org.apache.axis.i18n.ProjectResourceBundle).
log4j:WARN Please initialize the log4j system properly.
Processing file deploy.wsdd
<Admin>Done processing</Admin>

...[생략]...\workspace\Test1\src>robocopy ..\bin ...[tomcat 설치 폴더]...\webapps\axis\WEB-INF\classes HelloService.class

이어서, "http://localhost:8080/axis/servlet/AxisServlet" URL을 방문하면 다음과 같이 정상적으로 배포된 것을 확인할 수 있습니다.

java_webservice_3.png

휴... 복잡하군요. 일단 자바 웹 서비스가 목표이니 클라이언트 쪽은 닷넷으로 간단히 마무리 하겠습니다. 우선, WSDL을 알아야 하는데 위의 화면에서 링크가 제공되고 있으니 이를 가지고 Visual Studio에서 가져오기만 하면 됩니다.

HelloService WSDL - http://localhost:8080/axis/services/HelloService?wsdl

역시, 음... 제게는 Eclipse보다는 Visual Studio가 편하군요. 아래와 같이 ^^ 금방, 자바 웹 서비스를 닷넷에서 호출한 결과를 볼 수 있습니다.

java_webservice_4.png


2. .jws 유형으로 배포되는 자바 웹 서비스 제작

위에서는 복잡하게 AdminService를 이용해서 웹 서비스를 등록해 주는 과정이 필요했지만, jws 파일로 배포하는 경우에는 이런 불편함이 없어집니다.

예를 들어, 다음과 같이 CalcService.java 코드를 만들고,

public class CalcService {
    public int Add(int a, int b)
    {
        return a + b;
    }
}

해당 파일을 빌드해서 오류가 없다는 것만 확인하고, 확장자를 .jws로 변경한 다음 ...[tomcat 설치 폴더]...\webapps\axis 폴더에 복사해 주면 됩니다.

오~~~ 훨씬 간결하군요. ^^

이제 웹 브라우저로 "http://localhost:8080/axis/CalcService.jws" 링크를 방문해서 확인해보면 WSDSL 링크가 출력되고,

java_webservice_5.png

이렇게 얻어진 "http://localhost:8080/axis/CalcService.jws?wsdl" 주소를 Visual Studio의 '웹 서비스 참조' 대화상자를 이용해서 프록시 코드를 생성하면 정상적으로 호출할 수 있게 됩니다.

참고로, jws로 배포한 경우, Axis는 CalcService.jws로 요청이 들어오는 시점에 컴파일을 해서 "...[tomcat 설치 폴더]...\webapps\axis\WEB-INF\jwsClasses" 폴더에 CalcService.class 파일로 보관하고 서비스를 합니다.

(여기까지 실습한 서버 측 자바 코드클라이언트 측 닷넷 코드를 첨부합니다.)



실행 시에 아래와 같은 식의 오류들이 발생한다면 Axis에 포함된 jar 파일들에 대한 CLASSPATH가 정상적으로 잡히지 않은 것이니 참고하시고.

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/axis/client/AdminClient
Caused by: java.lang.ClassNotFoundException: org.apache.axis.client.AdminClient
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: org.apache.axis.client.AdminClient.  Program will exit.

Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/rpc/ServiceException
Caused by: java.lang.ClassNotFoundException: javax.xml.rpc.ServiceException
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: org.apache.axis.client.AdminClient.  Program will exit.

Exception in thread "main" java.lang.NoClassDefFoundError: org.apache.commons.logging.LogFactory
        at org.apache.axis.components.logger.LogFactory.class$(LogFactory.java:45)
        at org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:45)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:41)
        at org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:33)
        at org.apache.axis.client.AdminClient.<clinit>(AdminClient.java:48)
Could not find the main class: org.apache.axis.client.AdminClient.  Program will exit.

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/discovery/tools/DiscoverSingleton
        at org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:45)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:41)
        at org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:33)
        at org.apache.axis.client.AdminClient.<clinit>(AdminClient.java:48)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.discovery.tools.DiscoverSingleton
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 5 more
Could not find the main class: org.apache.axis.client.AdminClient.  Program will exit.

그리고, "http://localhost:8080/axis/servlet/AxisServlet"으로 확인했는데 다음과 같은 오류가 발생한다면?

And now... Some Services
AXIS error
Sorry, something seems to have gone wrong... here are the details:

Fault - Could not find class for the service named: HelloService
Hint: you may need to copy your class files/tree into the right location (which depends on the servlet system you are using).; nested exception is: 
    java.lang.ClassNotFoundException: HelloService
AxisFault
 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException
 faultSubcode: 
 faultString: Could not find class for the service named: HelloService
Hint: you may need to copy your class files/tree into the right location (which depends on the servlet system you are using).; nested exception is: 
    java.lang.ClassNotFoundException: HelloService
 faultActor: 
 faultNode: 
 faultDetail: 
    {http://xml.apache.org/axis/}hostname:TESTPC

HelloService.class 파일을 찾을 수 없다는 것인데, ...[tomcat 설치 폴더]...\webapps\axis\WEB-INF\classes 폴더에 HelloService.class 파일을 정상적으로 배포했는지 검사하면 됩니다.




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

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/21/2021]

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

비밀번호

댓글 작성자
 




1  2  3  4  [5]  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13510정성태1/3/20242106닷넷: 2192. C# - 특정 실행 파일이 있는지 확인하는 방법 (Linux)
13509정성태1/3/20242146오류 유형: 887. .NET Core 2 이하의 프로젝트에서 System.Runtime.CompilerServices.Unsafe doesn't support netcoreapp2.0.
13508정성태1/3/20242168오류 유형: 886. ORA-28000: the account is locked
13507정성태1/2/20242830닷넷: 2191. C# - IPGlobalProperties를 이용해 netstat처럼 사용 중인 Socket 목록 구하는 방법파일 다운로드1
13506정성태12/29/20232396닷넷: 2190. C# - 닷넷 코어/5+에서 달라지는 System.Text.Encoding 지원
13505정성태12/27/20232951닷넷: 2189. C# - WebSocket 클라이언트를 닷넷으로 구현하는 예제 (System.Net.WebSockets)파일 다운로드1
13504정성태12/27/20232526닷넷: 2188. C# - ASP.NET Core SignalR로 구현하는 채팅 서비스 예제파일 다운로드1
13503정성태12/27/20232387Linux: 67. WSL 환경 + mlocate(locate) 도구의 /mnt 디렉터리 검색 문제
13502정성태12/26/20232489닷넷: 2187. C# - 다른 프로세스의 환경변수 읽는 예제파일 다운로드1
13501정성태12/25/20232299개발 환경 구성: 700. WSL + uwsgi - IPv6로 바인딩하는 방법
13500정성태12/24/20232365디버깅 기술: 194. Windbg - x64 가상 주소를 물리 주소로 변환
13498정성태12/23/20233054닷넷: 2186. 한국투자증권 KIS Developers OpenAPI의 C# 래퍼 버전 - eFriendOpenAPI NuGet 패키지
13497정성태12/22/20232456오류 유형: 885. Visual Studiio - error : Could not connect to the remote system. Please verify your connection settings, and that your machine is on the network and reachable.
13496정성태12/21/20232436Linux: 66. 리눅스 - 실행 중인 프로세스 내부의 환경변수 설정을 구하는 방법 (gdb)
13495정성태12/20/20232406Linux: 65. clang++로 공유 라이브러리의 -static 옵션 빌드가 가능할까요?
13494정성태12/20/20232538Linux: 64. Linux 응용 프로그램의 (C++) so 의존성 줄이기(ReleaseMinDependency) - 두 번째 이야기
13493정성태12/19/20232631닷넷: 2185. C# - object를 QueryString으로 직렬화하는 방법
13492정성태12/19/20232315개발 환경 구성: 699. WSL에 nopCommerce 예제 구성
13491정성태12/19/20232262Linux: 63. 리눅스 - 다중 그룹 또는 사용자를 리소스에 권한 부여
13490정성태12/19/20232389개발 환경 구성: 698. Golang - GLIBC 의존을 없애는 정적 빌드 방법
13489정성태12/19/20232172개발 환경 구성: 697. GoLand에서 ldflags 지정 방법
13488정성태12/18/20232101오류 유형: 884. HTTP 500.0 - 명령행에서 실행한 ASP.NET Core 응용 프로그램을 실행하는 방법
13487정성태12/16/20232406개발 환경 구성: 696. C# - 리눅스용 AOT 빌드를 docker에서 수행 [1]
13486정성태12/15/20232220개발 환경 구성: 695. Nuget config 파일에 값 설정/삭제 방법
13485정성태12/15/20232099오류 유형: 883. dotnet build/restore - error : Root element is missing
13484정성태12/14/20232175개발 환경 구성: 694. Windows 디렉터리 경로를 WSL의 /mnt 포맷으로 구하는 방법
1  2  3  4  [5]  6  7  8  9  10  11  12  13  14  15  ...