비밀번호 Web Services는 Java에서 여러 방식으로 개발될 수 있습니다. 우리는 지난 튜토리얼에서 JAX-WS SOAP Web Services에 대해 배웠으며, 오늘은 Eclipse를 사용하여 SOAP 웹 서비스 및 해당 클라이언트 프로그램을 어떻게 만들 수 있는지에 대해 알아볼 것입니다. 여기서는 JAX-WS를 사용하지 않을 것이며, Apache Axis를 사용할 것입니다. 이는 Eclipse에 통합되어 응용 프로그램을 Java 웹 서비스로 변환하고 테스트 JSP 페이지와 클라이언트 스텁을 빠르고 쉽게 생성하는 방법을 제공합니다.
Java에서의 SOAP 웹 서비스
이 튜토리얼에서는 Eclipse Mars Release (4.5.0)를 사용하고 있지만, 이 단계들이 이전 버전의 Eclipse에서도 작동할 것으로 생각됩니다. 또한 Eclipse에 Apache Tomcat 또는 다른 서블릿 컨테이너를 서버로 추가했는지 확인하세요. 이제 Eclipse 웹 서비스 구현을 시작해 봅시다.
SOAP 웹 서비스 예제
이클립스에서 SOAP 웹 서비스 예제를 시작해 봅시다. 먼저, 애플리케이션의 비즈니스 로직을 포함할 동적 웹 프로젝트를 이클립스에서 만들겠습니다. 위의 Next 버튼을 클릭하면 다음 페이지에서 웹 프로젝트 이름과 대상 런타임을 입력할 수 있습니다. 제가 Apache Tomcat 8을 사용하고 있지만, 다른 표준 서블릿 컨테이너도 사용할 수 있습니다.
Next를 클릭하면 “Context Root”와 콘텐츠 디렉토리 위치를 입력하라는 메시지가 나옵니다. 기본값으로 둘 수 있습니다.
Finish를 클릭하면 이클립스가 프로젝트 템플릿을 생성합니다. 이제 비즈니스 로직을 시작해 봅시다. 예제에서는 객체를 추가/삭제/조회할 수 있는 웹 서비스를 배포하고자 합니다. 따라서 첫 번째 단계는 모델 빈을 생성하는 것입니다.
package com.journaldev.jaxws.beans;
import java.io.Serializable;
public class Person implements Serializable{
private static final long serialVersionUID = -5577579081118070434L;
private String name;
private int age;
private int id;
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;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString(){
return id+"::"+name+"::"+age;
}
}
위에 있는 것은 간단한 자바 빈입니다. 우리는 이를 네트워크를 통해 전송할 것이기 때문에 Serializable
인터페이스를 구현하고 있습니다. 우리는 또한 클라이언트 측에서 이 객체를 출력할 때 사용할 toString
메서드 구현을 제공했습니다. 다음 단계는 서비스 클래스를 생성하는 것입니다. 따라서 PersonService
인터페이스와 해당하는 간단한 구현 클래스 PersonServiceImpl
이 있을 것입니다.
package com.journaldev.jaxws.service;
import com.journaldev.jaxws.beans.Person;
public interface PersonService {
public boolean addPerson(Person p);
public boolean deletePerson(int id);
public Person getPerson(int id);
public Person[] getAllPersons();
}
아래는 구현된 서비스 클래스입니다. 우리는 Person 객체를 데이터 소스로 사용하기 위해 Map을 사용하고 있습니다. 실제 프로그래밍에서는 이들을 데이터베이스 테이블에 저장하고자 할 것입니다.
package com.journaldev.jaxws.service;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.journaldev.jaxws.beans.Person;
public class PersonServiceImpl implements PersonService {
private static Map<Integer,Person> persons = new HashMap<Integer,Person>();
@Override
public boolean addPerson(Person p) {
if(persons.get(p.getId()) != null) return false;
persons.put(p.getId(), p);
return true;
}
@Override
public boolean deletePerson(int id) {
if(persons.get(id) == null) return false;
persons.remove(id);
return true;
}
@Override
public Person getPerson(int id) {
return persons.get(id);
}
@Override
public Person[] getAllPersons() {
Set<Integer> ids = persons.keySet();
Person[] p = new Person[ids.size()];
int i=0;
for(Integer id : ids){
p[i] = persons.get(id);
i++;
}
return p;
}
}
이게 우리의 비즈니스 로직입니다. 이를 웹 서비스에서 사용할 것이기 때문에 여기에 웹 페이지를 만드는 것은 의미가 없습니다. 위의 코드에는 어떠한 종류의 웹 서비스 클래스에 대한 참조도 없습니다.
Eclipse를 사용한 자바로 하는 SOAP 웹 서비스
일단 비즈니스 로직이 준비되면, 다음 단계는 Eclipse를 사용하여 웹 서비스 애플리케이션을 만드는 것입니다. 새 프로젝트를 만들고 웹 서비스 마법사를 선택하십시오. 다음 버튼을 클릭하면 웹 서비스 및 해당 클라이언트 세부 정보를 제공해야 하는 페이지가 나타납니다. 이것은 웹 서비스를 만드는 데 가장 중요한 페이지입니다. “웹 서비스 유형”을 “Bottom up Java bean Web Service”로 선택하는지 확인하십시오. 왜냐하면 우리는 Bottom up 접근 방식으로 구현하고 있기 때문입니다. 웹 서비스를 만드는 두 가지 방법이 있습니다:
- Contract last 또는 Bottom up 접근 방식: 이 접근 방식에서는 먼저 구현을 만든 다음 WSDL 파일을 생성합니다. 우리의 구현은 이 범주에 해당합니다.
- Contract first 또는 Top Down 접근 방식: 이 접근 방식에서는 먼저 웹 서비스 계약 즉, WSDL 파일을 만든 다음 그것에 대한 구현을 만듭니다.
서비스 구현에서는 구현 클래스
PersonServiceImpl
의 완전히 분류된 경로를 제공하십시오. 서비스 및 클라이언트 유형을 왼쪽으로 이동하여 클라이언트 프로그램 및 웹 서비스를 테스트하는 UI를 생성할 수 있도록 하십시오. 웹 서비스 구현의 구성을 확인하십시오. 서버 실행 시간, 웹 서비스 실행 시간 및 서비스 프로젝트에 대한 올바른 세부 정보를 제공해야 합니다. 일반적으로 이러한 세부 정보는 자동으로 채워지며 여기서는 변경할 필요가 없습니다. 클라이언트 구성에 대해서는 원하는 클라이언트 프로젝트 이름을 제공할 수 있습니다. 기본값으로 남겨 두었습니다. SOAPExampleClient
. 웹 서비스 실행 시간에 대한 링크를 클릭하면 아래 이미지에 표시된대로 다른 옵션을 얻을 수 있습니다. 그러나 기본값으로 남겨 두었습니다. Next 버튼을 클릭하면 웹 서비스로 노출할 메서드를 선택할 수 있습니다. 문서 또는 리터럴로 웹 서비스 스타일을 선택할 수도 있습니다. WSDL 문서 이름을 변경할 수 있지만, 나중에 혼란을 피하기 위해 구현 클래스 이름과 함께 사용하는 것이 좋습니다.
Next 버튼을 클릭하면 서버 시작 페이지를 받게 되며, “서버 시작” 버튼을 클릭한 다음 다음 버튼이 활성화됩니다.
Next 버튼을 클릭하면 “웹 서비스 탐색기”를 시작할 수 있는 페이지가 나옵니다.
시작 버튼을 클릭하면 브라우저에서 새 창이 열리며, 여기서 클라이언트 애플리케이션 부분을 진행하기 전에 웹 서비스를 테스트할 수 있습니다. 프로젝트의 아래 이미지처럼 보입니다.
여기서 일부 신뢰성 테스트를 수행할 수 있지만, 우리 간단한 응용 프로그램에 대해서는 클라이언트 애플리케이션 생성을 진행하겠습니다. Eclipse 웹 서비스 팝업 창에서 Next 버튼을 클릭하면 클라이언트 애플리케이션의 소스 폴더 페이지를 받게 됩니다.
Next 버튼을 클릭하면 다양한 테스트 시설을 선택할 수 있는 옵션이 제공됩니다. 나는 클라이언트 애플리케이션에서 사용할 수 있는 JSP 페이지를 생성하기 위해 JAX-RPC JSPs를 사용하고 있습니다.
웹 서비스 엔드포인트 URL을 가져오고 다른 URL로 설정할 수 있는
getEndpoint()
및 setEndpoint(String)
메서드가 추가되었음을 주목하십시오. 마우스로 클릭하여 클라이언트 프로젝트를 생성하고 아래에 표시된대로 클라이언트 테스트 JSP 페이지를 실행합니다. URL을 복사하여 원하는 브라우저에서 열 수 있습니다. 노출된 서비스 중 일부를 테스트해 보겠습니다.
이클립스 SOAP 웹 서비스 테스트
-
getAllPersons
결과 섹션에는 사람 세부 정보가 인쇄되지 않는다는 것에 유의하십시오. 이것은 자동으로 생성된 코드이기 때문에 원하는 출력을 얻기 위해 조금 다시 정리해야 합니다. 클라이언트 프로젝트의 Result.jsp를 열면 결과 출력에 switch case를 사용하는 것을 볼 수 있습니다. getAllPersons() 메서드의 경우, 내 경우에는 케이스 42였습니다. 당신의 경우에는 완전히 다를 수 있음을 유의하십시오. 저는 단지 아래와 같이 케이스 42의 코드를 변경했습니다.
case 42: gotMethod = true; com.journaldev.jaxws.beans.Person[] getAllPersons42mtemp = samplePersonServiceImplProxyid.getAllPersons(); if(getAllPersons42mtemp == null){ %> <%=getAllPersons42mtemp %> <% }else{ String tempreturnp43 = null; if(getAllPersons42mtemp != null){ java.util.List<com.journaldev.jaxws.beans.Person> listreturnp43= java.util.Arrays.asList(getAllPersons42mtemp); //tempreturnp43 = listreturnp43.toString(); for(com.journaldev.jaxws.beans.Person p : listreturnp43){ int id = p.getId(); int age = p.getAge(); String name=p.getName(); %> <%=id%>::<%=name %>::<%=age %> <% } } } break;
이후에 아래와 같은 출력 결과를 얻게 됩니다. 이곳에서 Eclipse가 핫 디플로이먼트를 수행하고 있으므로 애플리케이션을 다시 배포할 필요가 없습니다.
우리의 웹 서비스와 클라이언트 애플리케이션이 정상적으로 작동하는 것으로 보입니다. Eclipse에서 생성된 클라이언트 측 스텁을 자세히 살펴보기 위해 시간을 할애해야 합니다.
SOAP 웹 서비스 WSDL 및 구성
마지막으로 웹 서비스 프로젝트에 아래와 같이 WSDL 파일이 생성되었음을 알 수 있습니다. PersonServiceImpl.wsdl 코드:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="https://service.jaxws.journaldev.com" xmlns:apachesoap="https://xml.apache.org/xml-soap" xmlns:impl="https://service.jaxws.journaldev.com" xmlns:intf="https://service.jaxws.journaldev.com" xmlns:tns1="https://beans.jaxws.journaldev.com" xmlns:wsdl="https://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="https://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="https://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="https://service.jaxws.journaldev.com" xmlns="https://www.w3.org/2001/XMLSchema">
<import namespace="https://beans.jaxws.journaldev.com"/>
<element name="addPerson">
<complexType>
<sequence>
<element name="p" type="tns1:Person"/>
</sequence>
</complexType>
</element>
<element name="addPersonResponse">
<complexType>
<sequence>
<element name="addPersonReturn" type="xsd:boolean"/>
</sequence>
</complexType>
</element>
<element name="deletePerson">
<complexType>
<sequence>
<element name="id" type="xsd:int"/>
</sequence>
</complexType>
</element>
<element name="deletePersonResponse">
<complexType>
<sequence>
<element name="deletePersonReturn" type="xsd:boolean"/>
</sequence>
</complexType>
</element>
<element name="getPerson">
<complexType>
<sequence>
<element name="id" type="xsd:int"/>
</sequence>
</complexType>
</element>
<element name="getPersonResponse">
<complexType>
<sequence>
<element name="getPersonReturn" type="tns1:Person"/>
</sequence>
</complexType>
</element>
<element name="getAllPersons">
<complexType/>
</element>
<element name="getAllPersonsResponse">
<complexType>
<sequence>
<element maxOccurs="unbounded" name="getAllPersonsReturn" type="tns1:Person"/>
</sequence>
</complexType>
</element>
</schema>
<schema elementFormDefault="qualified" targetNamespace="https://beans.jaxws.journaldev.com" xmlns="https://www.w3.org/2001/XMLSchema">
<complexType name="Person">
<sequence>
<element name="age" type="xsd:int"/>
<element name="id" type="xsd:int"/>
<element name="name" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="addPersonResponse">
<wsdl:part element="impl:addPersonResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getAllPersonsResponse">
<wsdl:part element="impl:getAllPersonsResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="deletePersonResponse">
<wsdl:part element="impl:deletePersonResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="addPersonRequest">
<wsdl:part element="impl:addPerson" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getPersonResponse">
<wsdl:part element="impl:getPersonResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getPersonRequest">
<wsdl:part element="impl:getPerson" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="deletePersonRequest">
<wsdl:part element="impl:deletePerson" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getAllPersonsRequest">
<wsdl:part element="impl:getAllPersons" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="PersonServiceImpl">
<wsdl:operation name="addPerson">
<wsdl:input message="impl:addPersonRequest" name="addPersonRequest">
</wsdl:input>
<wsdl:output message="impl:addPersonResponse" name="addPersonResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deletePerson">
<wsdl:input message="impl:deletePersonRequest" name="deletePersonRequest">
</wsdl:input>
<wsdl:output message="impl:deletePersonResponse" name="deletePersonResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPerson">
<wsdl:input message="impl:getPersonRequest" name="getPersonRequest">
</wsdl:input>
<wsdl:output message="impl:getPersonResponse" name="getPersonResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllPersons">
<wsdl:input message="impl:getAllPersonsRequest" name="getAllPersonsRequest">
</wsdl:input>
<wsdl:output message="impl:getAllPersonsResponse" name="getAllPersonsResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="PersonServiceImplSoapBinding" type="impl:PersonServiceImpl">
<wsdlsoap:binding style="document" transport="https://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="addPerson">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="addPersonRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="addPersonResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deletePerson">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="deletePersonRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="deletePersonResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPerson">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getPersonRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getPersonResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllPersons">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getAllPersonsRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getAllPersonsResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="PersonServiceImplService">
<wsdl:port binding="impl:PersonServiceImplSoapBinding" name="PersonServiceImpl">
<wsdlsoap:address location="https://localhost:8080/SOAPExample/services/PersonServiceImpl"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
디자인 모드에서 이클립스를 열면 아래 이미지와 같이 보입니다. 또한 웹 서비스 엔드포인트에 ?wsdl을 추가하여 브라우저를 통해 웹 서비스 WSDL 파일에 액세스할 수 있습니다.
또한 web.xml이 수정되어 웹 서비스의 프론트 컨트롤러로 Apache Axis를 사용하도록 변경되었음을 알 수 있습니다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SOAPExample</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<display-name>Apache-Axis Servlet</display-name>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet>
<display-name>Axis Admin Servlet</display-name>
<servlet-name>AdminServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/servlet/AdminServlet</url-pattern>
</servlet-mapping>
</web-app>
아래 이미지는 자동 생성된 모든 스텁과 웹 서비스를 테스트하기 위한 JSP 페이지를 포함한 웹 서비스 및 클라이언트 프로젝트를 보여줍니다.
이것으로 이클립스를 사용하여 자바에서 soap 웹 서비스의 예제를 마쳤습니다. 이제 모든 어려운 부분을 이클립스가 자동으로 처리하고 모든 초점을 웹 서비스의 비즈니스 로직 작성에 맞추면 됩니다.
Source:
https://www.digitalocean.com/community/tutorials/soap-webservices-in-java-example-eclipse