Simple Frontend
Simple Frontend는 JAX-WS Frontend와 다르게 annotation 설정 필요 없이 Web Services를 구현할 수 있게 해주는 Frontend 모델이다.
클래스를 WSDL 모델에 매핑하는데 Reflection을 이용하며 현재 JAXB binding과 함께 사용 시 문제가 발생하므로 Aegis databinding을 사용하도록 함에 유의한다.
다음은 Simple Frontend를 Server와 Client 단에서 어떻게 사용해야 하는지에 대한 사용법이다.
Simple Frontend는 크게 Simple Frontend API 코드를 사용하여 서버와 클라이언트를 작성하는 방식과 Spring Configuration을 이용하는 방식으로 구분하여 사용될 수 있다.
-
Server Configuration
- Web Services 작성
- 서버 구동(2가지 방식 중 택1)
-
Client Configuration
- 클라이언트 작성(2가지 방식 중 택1)
Web Services 작성
Web Services로 노출시킬 서비스를 작성하는데, 일반 서비스 빈 개발 방식과 완벽히 동일하다. JAX-WS Frontend와 다르게 인터페이스 클래스에 어떠한 Annotation도 설정할
필요가 없다.
Samples
다음은 Web Service로 노출시킬 Movie Service에 대한 예제이다. 서비스는 일반 Spring Bean 개발과 동일하게 인터페이스 클래스, 구현 클래스, DAO(Data Access Object) 클래스, VO(Value Object)들로
구성되어 있다.
Interface Class
다음은 Movie Service의 인터페이스 클래스를 작성한 MovieService.java
의 일부이다.
public interface MovieService {
Log LOGGER = LogFactory.getLog(MovieService.class.getName());
public List<Movie> findMovieListAll() throws Exception;
public Map<String, Movie> findMovieMapAll() throws Exception;
public List<Movie> findMovieList(Country country, Category category)
throws Exception;
public Movie findMovie(String movieId) throws Exception;
public void createMovie(Movie movie) throws Exception;
public void updateMovie(Movie movie) throws Exception;
public void removeMovie(Movie movie) throws Exception;
...중략
Implementation Class
Interface Class를 구현한 구현 클래스로 Web Service 구현과 관련된 부분 없이 작성한다.
다음은 Movie Service의 인터페이스 클래스를 구현한 MovieServiceImpl.java
의 일부이다.
내부적인 MovieDAO
를 사용하여 Movie 정보를 관리하고 있다.
public class MovieServiceImpl implements MovieService {
private MovieDAO movieDAO = null;
public void setMovieDAO(MovieDAO movieDAO) {
this.movieDAO = movieDAO;
}
public List<Movie> findMovieListAll() throws Exception {
return this.movieDAO.findMovieListAll();
}
public Map<String, Movie> findMovieMapAll() throws Exception {
return this.movieDAO.findMovieMapAll();
}
public List<Movie> findMovieList(Country country, Category category)
throws Exception {
return this.movieDAO.findMovieList(country, category);
}
public Movie findMovie(String movieId) throws Exception {
return this.movieDAO.fineMovie(movieId);
}
public void createMovie(Movie movie) throws Exception {
this.movieDAO.createMovie(movie);
}
중략...
Server: Simple Frontend API 코드 사용
작성된 서비스를 Web Services로 노출시키는 서버를 구동하기 위해서 2가지 방식이 지원된다. 이중 Simple Frontend API 코드를 직접 작성하여 서버를 구동시켜보도록 한다.
Apache CXF에서 제공하는 Simple Frontend API 코드를 직접 호출하여 작성하는 것도 가능하지만, Anyframe에서 제공하는 API인
SimpleServer
를 사용하면
더욱 간편하고 편리하게 사용할 수 있다.(SimpleServer 내부적으로 Simple Frontend API 코드를 호출하고 있다.)
Samples
다음은 Anyframe에서 제공하는 SimpleServer 혹은 Apache CXF에서 제공하는 ServerFactoryBean를 직접 이용하여 Movie Service를 Web Service로 노출시키는 서버를 구동하는 예제이다.
Anyframe SimpleServer 사용한 서버 구동
다음은 서버 사이드의 서비스를 Web Services로 노출시키는 서버를 구동하는 코드를 작성한 SimpleFrontendServerFactoryTest.java
의 일부이다.
setUp() 메소드 내에서 SimpleServer
를 생성시킨 후, 서버의 정보로 인터페이스 클래스, 구현 클래스의 인스턴스, Web Services 주소를 설정해준다.
상위 테스트케이스 클래스인 RemotingTestCase
의 setUp() 메소드에서 Server
의 start() 메소드가 호출되면서 실제로 구동된다.
public class SimpleFrontendServerFactoryTest extends RemotingTestCase {
// ==============================================================
// ====== TestCase 수행에 필요한 사전 작업 정의 ====================
// ==============================================================
public void setUp() throws Exception {
this.setServer(new SimpleServer());
this.getServer().setServerInfo(new ServerInfo(
MovieService.class, new MovieServiceImpl(),"http://localhost:9002/Movie", true));
super.setUp();
}
...중략
Apache CXF ServerFactoryBean 사용한 서버 구동
다음은 서버 사이드의 서비스를 Web Services로 노출시키는 서버를 구동하는 코드 작성 예이다.
MovieServiceImpl movieImpl = new MovieServiceImpl();
ServerFactoryBean svrFactory = new ServerFactoryBean();
svrFactory.setServiceClass(MovieService.class);
svrFactory.setAddress("http://localhost:9002/Movie");
svrFactory.setServiceBean(movieImpl);
svrFactory.getServiceFactory().setDataBinding(new AegisDatabinding());
svrFactory.create();
Spring Configuration XML - simple:server tag 사용
작성된 서비스를 Web Services로 노출시키는 서버를 구동하기 위해서 2가지 방식이 지원된다. 이중 Spring Configuration XML - <simple:server/> tag를 사용하여 서버를 구동시켜보도록 한다.
<simple:server/> tag의 각각의 Attribute 속성값에 대한 설명은 다음 표와 같다. 아래 표에 나와있지 않은 속성들도 여러 가지가 존재한다. 단, 여기서는 필수적으로
작성해야 하는 Attribute 속성값에 대한 설명을 작성해놓은 것으로 나머지 속성 값들에 대한 설명은
Simple Frontend Spring Configuration
을 참고하도록 한다.
| Property Name
|
Description
|
Required
|
Default Value
|
| id |
spring bean id를 작성한다. |
Y |
N/A |
| serviceBean |
구현 클래스를 작성한다. 클래스명 대신에 spring bean id로 대체하고자 하면 bean id 앞에 #을 붙여서 작성하면 된다. |
Y |
N/A |
| serviceClass |
서비스의 인터페이스 클래스를 작성한다. |
Y |
N/A |
| address |
서비스가 동작할 주소를 상대 경로로 작성한다. |
Y |
N/A |
| [하위 element]
<simple:dataBinding> |
Simple Frontend는 디폴트 databinding인 JAXB를 사용하지 않고
AegisDatabinding을 사용해야 하므로 <bean tag의 class 속성 값에
"org.apache.cxf.aegis.databinding.AegisDatabinding"를 설정해야 한다. |
Y |
N/A |
Samples
다음은 Spring Configuration XML - <simple:server/> tag를 사용하여 Movie Service를 Web Service로 노출시키는 서버를 구동하는 예제이다.
Configuration
다음은 서버 사이드의 서비스를 Web Services로 노출시키는 <simple:server/> tag 속성을 정의한 context-movie-server.xml
의 일부이다.
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!-- MovieService -->
<bean id="anyframe.sample.movie.MovieService"
class="anyframe.sample.movie.impl.MovieServiceImpl">
<property name="movieDAO">
<ref bean="movieDAO" />
</property>
</bean>
<bean id="movieDAO" class="anyframe.sample.movie.impl.MovieDAODefaultImpl" />
<!-- Simple Frontend to expose MovieService with Aegis Databinding -->
<simple:server id="movieService" serviceBean="#anyframe.sample.movie.MovieService"
serviceClass="anyframe.sample.movie.MovieService" address="/Movie">
<simple:dataBinding>
<bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
</simple:dataBinding>
</simple:server>
Jetty 서버를 이용하여 웹 어플리케이션을 구동하여 서버 사이드의 서비스를 Web Services로 노출시키게 되는데, 이때 web.xml 파일에 Spring Configuration XML 파일을
org.springframework.web.context.ContextLoaderListener를 이용하여 등록시켜 줘야 한다.
다음은 CXFServlet과 ContextLoaderListener를 정의한 web.xml
의 일부이다.
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/context-movie-server.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Test case
다음은 서버 사이드의 서비스를 Web Services로 노출시키는 서버를 구동하는 코드를 작성한 SimpleFrontendSpringTest.java
의 일부이다.
setUp() 메소드 내에서 JettyServer
를 생성시킨 후, 서버의 정보로 Port 번호와 WEB-INF 폴더 경로 정보를 설정해준다.
상위 테스트케이스 클래스인 RemotingTestCase
의 setUp() 메소드에서 Server
의 start() 메소드가 호출되면서 실제로 구동된다.
public class SimpleFrontendSpringTest extends RemotingTestCase {
// ==============================================================
// ====== TestCase 수행에 필요한 사전 작업 정의 ====================
// ==============================================================
public void setUp() throws Exception {
this.setServer((new JettyServer());
ServerInfo serverInfo = new ServerInfo();
serverInfo.setPort(9002);
serverInfo
.setWarpath("src/test/resources/webservices/simple/server/webapp");
this.getServer().setServerInfo(serverInfo);
super.setUp();
}
...중략
Client: Simple Frontend API 코드 사용
Web Services에 접근하기 위한 클라이언트 작성 방식에는 2가지 방식이 지원된다. 이중 Simple Frontend API 코드를 직접 이용한 클라이언트를 작성하여
Web Services에 접근해보도록 한다.
Apache CXF에서 제공하는 Simple Frontend API 코드를 직접 호출하여 작성하는 것도 가능하지만, Anyframe에서 제공하는 API인
SimpleClient
를 사용하면
더욱 간편하고 편리하게 사용할 수 있다.(SimpleClient 내부적으로 Simple Frontend API 코드를 호출하고 있다.)
Samples
다음은 Anyframe에서 제공하는 SimpleClient 혹은 Apache CXF에서 제공하는 ClientProxyFactoryBean를 직접 이용하여 Web Services로 노출된 Movie Service에 접근하는 예제이다.
Anyframe SimpleClient 사용한 클라이언트
다음은 Anyframe에서 제공하는 SimpleClient 클래스를 사용하여 Web Services로 노출된 Movie Service에 접근하는 클라이언트 코드를 작성한 SimpleFrontendSpringTest.java
의 일부이다.
testXXX() 메소드 내에서 SimpleClient
를 생성시킨 후, 클라이언트의 정보로 인터페이스 클래스와 접근하고자 하는 Web Services 주소를 이용하여
Movie Service를 얻어낸다. Movie Service를 얻은 후에는 Movie Service에서 Web Service 메소드로 노출된 메소드를 호출하여 동작이 올바른지 테스트해본다.
public class SimpleFrontendSpringTest extends RemotingTestCase {
// ==============================================================
// ====== TestCase methods ======================================
// ==============================================================
/**
* [Flow #-3] Positive Case : Movie Id가 "001"인 Movie를 조회한다.
* @throws Exception
* throws exception which is from service
*/
public void testFindMovie() throws Exception {
Client client = new SimpleClient();)
MovieService movieService =
(MovieService) client.getClient(
new ClientInfo(MovieService.class,"http://localhost:9002/Movie", true));
// 1. find movie
Movie movie = movieService.findMovie("001");
// 2. check the movie information
assertEquals("The Sound Of Music", movie.getTitle());
assertEquals("Robert Wise", movie.getDirector());
}
...중략
Apache CXF ClientProxyFactoryBean 사용한 클라이언트
다음은 Apache CXF에서 제공하는 ClientProxyFactoryBean 클래스를 사용하여 Web Services로 노출된 Movie Service에 접근하는 코드 작성 예이다.
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setServiceClass(MovieService.class);
factory.setAddress("http://localhost:9002/Movie");
factory.getServiceFactory().setDataBinding(new AegisDatabinding());
MovieService movieService = (MovieService)factory.create();
Movie movie= movieService.findMovie("001");
Spring Configuration XML - simple:client tag 사용
Web Services에 접근하기 위한 클라이언트 작성 방식에는 2가지 방식이 지원된다. 이중 Spring Configuration XML - <simple:client/> tag를 사용하여 클라이언트를 작성하여
Web Services에 접근해보도록 한다.
<simple:client/> tag의 각각의 Attribute 속성값에 대한 설명은 다음 표와 같다. 아래 표에 나와있지 않은 속성들도 여러 가지가 존재한다. 단, 여기서는 필수적으로
작성해야 하는 Attribute 속성값에 대한 설명을 작성해놓은 것으로 나머지 속성 값들에 대한 설명은
Simple Frontend Spring Configuration
을 참고하도록 한다.
| Property Name
|
Description
|
Required
|
Default Value
|
| id |
spring bean id를 작성한다. |
Y |
N/A |
| serviceClass |
서비스의 인터페이스 클래스를 작성한다. |
Y |
N/A |
| address |
서비스 접근 URL Address를 절대 경로로 작성한다. |
Y |
N/A |
| [하위 element]
<simple:dataBinding> |
Simple Frontend는 디폴트 databinding인 JAXB를 사용하지 않고
AegisDatabinding을 사용해야 하므로 <bean tag의 class 속성 값에
"org.apache.cxf.aegis.databinding.AegisDatabinding"를 설정해야 한다. |
Y |
N/A |
Samples
다음은 Spring Configuration XML - <simple:client/> tag를 사용하여 Movie Service에 접근하는 예제이다.
Configuration
다음은 Web Services로 노출된 Movie Service에 접근하는 <simple:client/> tag 속성을 정의한 context-movie-client.xml
의 일부이다.
<!-- using Simple Client Bean -->
<simple:client id="movieServiceSimple" serviceClass="anyframe.sample.movie.MovieService"
address="http://localhost:9002/Movie">
<simple:dataBinding>
<bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
</simple:dataBinding>
</simple:client>
Test case
다음은 앞서 정의한 속성 설정 파일들을 기반으로 하여 Web Services로 노출된 Movie Service에 접근하는 TestCase인 SimpleFrontendSpringClientTest.java
의 일부이다.
getConfigLocations() 메소드 내에 클라이언트 Spring Configuration XML(context-movie-client.xml)을 정의함으로써
테스트 케이스 내에서 MovieService에 접근할 수 있도록 한다.
상위 테스트케이스 클래스인 RemotingSpringTestCase
은 Spring TestCase를 상속받아 구성된 것으로
Setter Injection을 통해 MovieService를 설정하여 해당 테스트 케이스 내에서 호출하여 테스트할 수 있게 한다.
public class SimpleFrontendSpringClientTest extends RemotingSpringTestCase {
// ==============================================================
// ====== TestCase 수행에 필요한 사전 작업 정의 ====================
// ==============================================================
private MovieService movieService = null;
public void setMovieService(MovieService movieService) {
this.movieService = movieService;
}
protected String[] getConfigLocations() {
중략...
return new String[] {"classpath*:/webservices/simple/client/context-movie-client.xml" };
}
// ==============================================================
// ====== TestCase methods ======================================
// ==============================================================
/**
* [Flow #-3] Positive Case : Movie Id가 "001"인 Movie를 조회한다.
* @throws Exception
* throws exception which is from service
*/
public void testFindMovie() throws Exception {
// 1. find movie
Movie movie = movieService.findMovie("001");
// 2. check the movie information
assertEquals("The Sound Of Music", movie.getTitle());
assertEquals("Robert Wise", movie.getDirector());
}
...중략
Resources
다운로드
샘플 테스트 코드를 포함하고 있는 anyframe-remotingtest-src.zip 파일을 다운받은 후, 테스트 환경 설정
을 참조하여
위에서 제시한 예제 코드를 실행해 볼 수 있다. 이때 해당 프로젝트 내의 src/test/java 소스폴더 하위의 anyframe.core.remoting.webservices.simple 패키지 하위의 테스트케이스 클래스를
JUnit Test Framework을 이용하여 수행시키도록 한다.
| Name
|
Download
|
| anyframe-remotingtest-src.zip |
Download
|
참고자료