Aegis는 JAXB와 다르게 표준(Spec.)이 아니며, Apache CXF에서만 제공되는 기능으로 JAXB와 역할이 동일하다. 즉, XML Schema로부터 클래스 데이터를 바인딩하여 XML로부터 객체를 Unmarshalling 하거나,
반대로 객체를 XML로 저장하는 Marshalling을 수행할 수 있도록 해 준다.
Xfire 프로젝트의 일부로 시작되었으나 Celtix와 Xfire의 합체로 현재 Apache CXF에 포함되어 발전되고 있다.
| 구분 |
데이터 타입 |
| Basic types |
int, double, float, long, byte[], short, String, BigDecimal, BigInteger, Character, Double, Float 등
*주의)char는 지원되지 않음 |
| Collections |
Arrays, Maps |
| Dates |
java.util.Date, java.util.Calendar, java.sql.Timestamp, java.sql.Date, java.sql.Time |
| XML |
org.w3c.dom.Docmument, org.jdom.Element, XMLStreamReader, Source |
| Complex types |
위 데이터 타입의 조합으로 새로 작성한 User Defined Types |
Server Configuration
Movie Service를 Simple Frontend를 사용하여 Web Services로 노출시킬 때 인터페이스 메소드의 파라인터 인자와 리턴 값의 타입을 다양한 타입으로 선언하여
테스트해보도록 한다.
Samples
다음은 Movie Service의 인터페이스 클래스 예제이다.
Map 타입 사용을 위해서 부가적인 작업이 필요없다.
서버 구동을 위해서 Anyframe에서 제공하는 SimpleServer 클래스를 이용하고 있다.
Interface Class
다음은 Movie Service의 인터페이스 클래스를 작성한 MovieService.java
의 일부이다.
public interface MovieService {
public List<Movie> findMovieListAll() throws Exception;
public Map<String, Movie> findMovieMapAll() 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;
// ================= method for Type tests
public int testMovieIntVal(int val);
public long testMovieLongVal(long val);
public short testMovieShortVal(short val);
public float testMovieFloatVal(float val);
public double testMovieDoubleVal(double val);
public BigDecimal testMovieBigDecimalVal(BigDecimal val);
public boolean testMovieBooleanVal(boolean val);
public Character testMovieCharacterVal(Character val);
중략...
Test case
다음은 서버 사이드의 서비스를 Web Services로 노출시키는 서버를 구동하는 코드를 작성한 SimpleAegisTest.java
의 일부이다.
setUp() 메소드 내에서 SimpleServer
를 생성시킨 후, 서버의 정보로 인터페이스 클래스, 구현 클래스의 인스턴스, Web Services 주소를 설정해준다.
상위 테스트케이스 클래스인 RemotingTestCase
의 setUp() 메소드에서 Server
의 start() 메소드가 호출되면서 실제로 구동된다.
여기서 ServerInfo 클래스 생성 시 생성자 메소드의 네번째 파라미터(boolean useAegisBinding)값을 true로 설정하고 있음에 주의하도록 한다.
Aegis Databinding 기능을 사용하고자 한다면 true로 반드시 설정해야 한다.
public class SimpleAegisTest 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();
}
중략...
ServerInfo 클래스의 useAegisBinding 값을 true로 설정하게 되면,
내부적으로 ServerFactoryBean 클래스의 API를 호출하여 Aegis Databinding 사용을
가능하게 해준다.
다음은 SimpleServer.java
의 일부 코드 부분이다. 참고하도록 한다.
public class SimpleServer implements Server {
ServerFactoryBean svrFactory = null;
public SimpleServer() {
svrFactory = new ServerFactoryBean();
}
public void setServerInfo(ServerInfo serverInfo) {
svrFactory.setServiceClass(serverInfo.getInterfaceClass());
svrFactory.setAddress(serverInfo.getAddress());
svrFactory.setServiceBean(serverInfo.getImpleClass());
if (serverInfo.isUseAegisBinding())
svrFactory.getServiceFactory().setDataBinding(
new AegisDatabinding());
}
public void start() throws Exception {
svrFactory.create();
Server.LOGGER.info("Server ready...");
}
public void stop() throws Exception {
svrFactory.getBus().shutdown(true);
}
중략...
[Optional] Spring Configuration XML Server 설정 이용
이 SimpleAegisTest
에서는
Simple Frontend API 코드를 사용하고 있으나, Spring Configuration XML 설정을 통해 Aegis Databinding 사용을 정의할 수 있다.
<!-- 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>
중략...
Client Configuration
Web Services에 접근하기 위한 클라이언트 작성 방식 중 Anyframe에서 제공하는 API인
SimpleClient
를 사용하면
더욱 간편하고 편리하게 사용할 수 있다.(SimpleClient 내부적으로 Simple Frontend API 코드를 호출하고 있다.)
Samples
다음은 Anyframe에서 제공하는 SimpleClient를 이용하여 Web Services로 노출된 Movie Service에 접근하는 예제이다.
Test Case
다음은 Anyframe에서 제공하는 SimpleClient 클래스를 사용하여 Web Services로 노출된 Movie Service에 접근하는 클라이언트 코드를 작성한 SimpleAegisTest.java
의 일부이다.
testXXX() 메소드 내에서 SimpleClient
를 생성시킨 후, 클라이언트의 정보로 인터페이스 클래스와 접근하고자 하는 Web Services 주소를 이용하여
Movie Service를 얻어낸다. Movie Service를 얻은 후에는 Movie Service에서 Web Service 메소드로 노출된 메소드를 호출하여 동작이 올바른지 테스트해본다.
즉, 다양한 데이터 타입에 대해서 Databinding이 올바로 동작하여 파라미터 값과 리턴 값이 의도된 대로 동작하는지 테스트한다.
여기서 ClientInfo 클래스 생성 시 생성자 메소드의 세번째 파라미터(boolean useAegisBinding)값을 true로 설정하고 있음에 주의하도록 한다.
Aegis Databinding 기능을 사용하고자 한다면 true로 반드시 설정해야 한다.
public class SimpleAegisTest extends RemotingTestCase {
// ==============================================================
// ====== TestCase methods ======================================
// ==============================================================
/**
* [Flow #-1] Positive Case : List 형태로 전체 목록을 조회한다.
* @throws Exception
* throws exception which is from service
*/
public void testFindMovieListAll() throws Exception {
Client client = new SimpleClient();
MovieService movieService =
(MovieService) client.getClient(new ClientInfo(MovieService.class,
"http://localhost:9002/Movie", true));
// 1. find movie list all
List<Movie> movieList = movieService.findMovieListAll();
// 2. check the movie list count
assertEquals(2, movieList.size());
}
/**
* [Flow #-2] Positive Case : Map 형태로 전체 목록을 조회한다.
* @throws Exception
* throws exception which is from service
*/
public void testFindMovieMapAll() throws Exception {
Client client = new SimpleClient();
MovieService movieService =
(MovieService) client.getClient(new ClientInfo(MovieService.class,
"http://localhost:9002/Movie", true));
// 1. find movie map all
Map<String, Movie> movieMap = movieService.findMovieMapAll();
// 2. check the movie map count
assertEquals(2, movieMap.size());
}
/**
* [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());
}
중략...
/**
* [Flow #-7] Positive Case : Type Test - input, output parameter로 int value를
* 사용하여 호출한다.
*/
public void testMovieIntVal() {
Client client = new SimpleClient();
MovieService movieService =
(MovieService) client.getClient(new ClientInfo(MovieService.class,
"http://localhost:9002/Movie", true));
assertEquals(1, movieService.testMovieIntVal(1));
}
/**
* [Flow #-8] Positive Case : Type Test - input, output parameter로 long value를
* 사용하여 호출한다.
*/
public void testMovieLongVal() {
Client client = new SimpleClient();
MovieService movieService =
(MovieService) client.getClient(new ClientInfo(MovieService.class,
"http://localhost:9002/Movie", true));
assertEquals(1, movieService.testMovieLongVal(1));
}
중략...
ClientInfo 클래스의 useAegisBinding 값을 true로 설정하게 되면,
내부적으로 ClientProxyFactoryBean 클래스의 API를 호출하여 Aegis Databinding 사용을
가능하게 해준다.
다음은 SimpleClient.java
의 일부 코드 부분이다. 참고하도록 한다.
public class SimpleClient implements Client {
ClientProxyFactoryBean factory = null;
public SimpleClient() {
factory = new ClientProxyFactoryBean();
}
public Object getClient(ClientInfo clientInfo) {
factory.setServiceClass(clientInfo.getInterfaceClass());
factory.setAddress(clientInfo.getAddress());
if (clientInfo.isUseAegisBinding())
factory.getServiceFactory().setDataBinding(new AegisDatabinding());
return factory.create();
}
중략...
[Optional] Spring Configuration XML Client 설정 이용
이 SimpleAegisTest
에서는
Simple Frontend API 코드를 사용하고 있으나, Spring Configuration XML 설정을 통해 Aegis Databinding 사용을 정의할 수 있다.
<!-- Simple Frontend to access MovieService with Aegis Databinding -->
<simple:client id="movieService" serviceClass="anyframe.sample.movie.MovieService"
address="http://localhost:9002/Movie">
<simple:dataBinding>
<bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
</simple:dataBinding>
</simple:client>
중략...