블로그 이미지
Max.

calendar

    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Notice

2011.08.22 19:56 개발관련
1) 현재 환경이 JDK1.5 이므로, jersey 버전이 낮다(1.2 버젼이다. 1.3은 JDK1.6부터 지원한다). 해당 버전에서는 잘 알려진 버그가 있는데, json으로 array를 전송시, 한개 이상만, array로 보내고, 미만은 일반 객체로 넘겨 버린다. 클라이언트에서 관련 처리를 해주면 좋겠지만, 일관성 측면에서 서버측에서 지속적으로 array로 보낼 필요가 있을 때 이와 같은 방법을 사용해 볼수 있다.


2) 간단히 확장 클래스를 만든다. 아래는 인터넷에 뒤져보면 흔히 볼수 있는 코드와 비슷하다.

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
    private final JAXBContext context;
    private final Set<Class> types;
    private Class<?>[] cTypes ;
    public JAXBContextResolver(Class<?>[] __cTypes) throws Exception {
this.cTypes = __cTypes;
        this.types = new HashSet(Arrays.asList(cTypes));
        this.context = new JSONJAXBContext(JSONConfiguration.natural().build(), cTypes);
    }
    
    public JAXBContext getContext(Class<?> objectType) {
        return (types.contains(objectType)) ? context : null;
    }
}



3) DI 한다. 이때 변환될 모델을 필요한 만큼 등록한다.

    <bean class="com.xxx.jersey.resolver.JAXBContextResolver" scope="singleton">
    <constructor-arg>
    <list>
<value>xxx.domain.ChannelDsResponse</value>
<value>zzz.domain.CategoryDsResponse</value>
<value>yyy.domain.CountryDsResponse</value>
<value>www.DirtyWordsDsResponse</value>
</list>
    </constructor-arg>
    </bean>


 4) Test 코드
 

  @Test
    public void testResponseJson() throws IllegalArgumentException, IOException {
        ClientResponse clientResponse = webResource.path("/webservice/rest/Channel/KR/Channels/Category/01000000/1")
        .accept("application/json").get(ClientResponse.class);
        System.out.println("just 1: ===============================================");
    System.out.println(clientResponse.getHeaders());
    System.out.println(clientResponse.getEntity(String.class));
    System.out.println("just 1: ===============================================");
   
    clientResponse = webResource.path("/webservice/rest/Channel/KR/Channels/Category/01000000/2")
    .accept("application/json").get(ClientResponse.class);
    System.out.println("over 2: ===============================================");
    System.out.println(clientResponse.getHeaders());
    System.out.println(clientResponse.getEntity(String.class));
    System.out.println("over 2: ===============================================");
    }


5) 결과

just 1: =============================================== {Date=[Mon, 22 Aug 2011 10:46:50 GMT], Server=[Apache-Coyote/1.1], Content-Type=[ {"resultCode":0,"resultMessage":"","channels":[{"categories":[{"id":"01000000"}], just 1: =============================================== over 2: =============================================== {Date=[Mon, 22 Aug 2011 10:46:50 GMT], Server=[Apache-Coyote/1.1], Content-Type=[ {"resultCode":0,"resultMessage":"","channels":[{"categories":[{"id":"01000000"}], over 2: ===============================================


@Autowired로 DI 할수 있겠으나, 추가할 모델(Bean)들을 언제 늘어날지 모르므로 XML 설정파일로 하는게 편리할듯 싶다. 다른 버전에서는 잘 되는지 확인하지 않았다. 
저작자 표시
신고
posted by Max.
TAG array, jersey, JSON
2010.12.13 07:58 개발관련
저지로 호출시, 요청 파라메터를 보내는데, 일반적인 POST나 GET 처럼 "?" 다음에 붙여서 보내는 방법과, XML 을 요청 파라메터로 붙이는 방법 두가지이다. 그런데 인터넷에서 찾아보면, XML로 보내는 예제를 보기 어렵다. 

    @Test
    public void webPost1(){
              // 설정
             ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource("http://xxxx.com/xxxx/service");
                // 호출
IfRequest ifRquest = new IfRequest(); // jersey request Object
ClientResponse response = service.accept(MediaType.APPLICATION_XML).post(ClientResponse.class, ifRquest);
assertEquals(200,response.getStatus());

// 로그
System.out.println(response.getStatus());
System.out.println(response.getHeaders());
System.out.println(response.getEntity(String.class));
    }

진한 글씨가 보통은 생략되거나 Form객체로 param값을 전달하기도 한다. 아래는 IfRequest 객체의 매핑 내용이다.

@XmlType
@MappedSuperclass
@XmlRootElement(name="IfRequest")
public class IfRequest {
@XmlElement(name="messageId")
String messageId = "aaaa";
@XmlElement(name="caller")
String caller = "bbbb";
@XmlElement(name="hashKey")
String hashKey = "ccccc";
@XmlElement(name="serviceId")
String serviceId = "dddd";
@XmlElement(name="dataSet")
List<DataSet> dataSets = DataSetFactory.get();
}

이상이다.... 다음에는 SAML 이나, OAuth 같은 요즘 뜨는 예제를 올릴까... 아니면, SmartGWT 수동으로 파일 업로드 하는 무식한 예제를????
저작자 표시
신고

'개발관련' 카테고리의 다른 글

Spring Roo 1.1.2 BUILD-SNAPSHOT 기념샷  (0) 2011.01.12
토비의스프링3 읽고나서...  (12) 2010.12.13
Jersey + XML 호출 예제 테스트  (0) 2010.12.13
Spring + Jersey + Dozer 예제  (0) 2010.12.10
SmartGWT stack_overflow  (0) 2010.10.07
토비의 스프링3 : 독중감(2)  (10) 2010.09.08
posted by Max.
TAG jersey
2010.12.10 20:09 개발관련
생각나는 김에 올린다. 요즘 정신없이 개발하고 있어서 하루가 금방이다. 거의 방치수준의 블로그를 이런식으로라도 유지하려는...;;; 아무튼, 제목 그대로 저 두개를 이용하여 객체를 반환하는 예제이다. 이것이 필요한 이유는, 웹서비스를 처리하는 그룹과 그것을 이용하는 그룹이 분리되어 있다면, 서로 다른 목적의 객체에 담기는게 유리하다. 그때 각각의 객체에 값을 이동할 필요가 있는데, 이렇게 복사해(매핑해) 주는 것이 Dozer다. 아래는 그 예제를 순서적으로 기록한 것이다.

1) Response 객체 (jersey 에서 사용)
@XmlType
@MappedSuperclass
@XmlRootElement(name="RESULT")
public class AccountResponse {
@XmlElement(name="RESULT_CODE")
private String resultCode;
@XmlElement(name="COUNT")
private int count;
@XmlElement(name="LINK_URL")
private String linkUrl;
...

2) DTO 객체
public class AccountResult {
private Long count;
private String linkUrl;
...

3) Dozer 매핑 설정
...
  <mapping map-id="ws_account"> 
    <class-a>kr.company.ws.model.AccountResponse</class-a>
    <class-b>kr.company.service.model.AccountResult</class-b>   
    <field custom-converter="kr.company.service.model.converter.IntToLongConverter">
      <a>count</a>
      <b>count</b>
    </field>
    <field>
      <a>linkUrl</a>
      <b>linkUrl</b>
    </field>
  </mapping> 
[Converter] 
public class IntToLongConverter implements CustomConverter {
@Override
public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {
Integer id = (Integer) sourceFieldValue;
return Long.valueOf(id);
}
}

4) Spring 설정
...
<bean id="dozerMapper" class="org.dozer.DozerBeanMapper">
   <property name="mappingFiles">
       <list>
           <value>META-INF/spring/dozer-bean-mappings.xml</value>
       </list>
   </property>
</bean>

4) 서비스 호출
public class AccountServiceProviderImpl ...
@Override
public AccountResult findAccount(Long id) {
AccountResponse accountResponse = accountWebService.findAccount(id);
return dozerMapper.map(accountResponse, AccountResult.class,"ws_account");
}
...

5) 테스트
    @Test
    public void 테스트(){
         ...

     AccountResult accountResult = accountServiceProvider.findAccount(account.getId());
     assertNotNull(accountResult);
    }

따로 설명없이 순서적으로 보면, 이해될수 있을 정도로 쉽다. Dozer를 몇년전에 시도 했을때는 설정이 복잡해 보였는데, 다시 해보니, 복잡하지도 않고 쓸만하다. 오히려 jersey설정이 더 복잡해 보인다. 그래도 jersey역시 쉽다.

저작자 표시
신고
posted by Max.
prev 1 next

티스토리 툴바