2013年1月10日 星期四

使用Apache CXF快速製作Java RESTful Client (JSR311)

使用Apache CXF製作Java RESTful client是很容易的,首先我們看一下org.apache.cxf.jaxrs.client.JAXRSClientFactory,其中有很多名為create的static method,而在官方的說明文件中有特別提到Proxy-based API的使用方式,簡單的說,它可以利用一組符合JSR311規範的interface,反過來generate proxy client instance,讓我們可以不需要自己撰寫任何HTTP client或者是其它RESTful API就做出client端的物件,是不是很方便呢?

以下是一組簡單的test case:
  1. JSR311 interface
  2. 代碼:
    package com.gss.gmo.cao.restclient;

    import java.util.Date;

    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;

    @Path("test")
    public interface TestResource {
        @GET
        @Path("getDate")
        @Produces(MediaType.APPLICATION_JSON)
        Date getDate();
    }
  3. Implementation class
  4. 代碼:
    package com.gss.gmo.cao.restclient.provider;

    import java.util.Date;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import org.joda.time.format.ISODateTimeFormat;
    import com.gss.gmo.cao.restclient.TestResource;

    @Path("test")
    public class TestResourceImpl implements TestResource {
        @Override
        @GET
        @Path("getDate")
        public Date getDate() {
            return ISODateTimeFormat.dateTime().parseDateTime("2012-12-14T09:21:00.123+08:00").toDate();
        }
    }
  5. Test case
  6. 代碼:
    package com.gss.gmo.cao.restclient.provider;

    import static junit.framework.Assert.assertEquals;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
    import org.joda.time.format.ISODateTimeFormat;
    import org.junit.Before;
    import org.junit.Test;
    import com.gss.gmo.cao.restclient.TestResource;
    import com.sun.jersey.test.framework.AppDescriptor;
    import com.sun.jersey.test.framework.JerseyTest;
    import com.sun.jersey.test.framework.WebAppDescriptor;

    public class ResponseExceptionMapperTest extends JerseyTest {

        private TestResource testResource;

        @Override
        protected AppDescriptor configure() {
            return new WebAppDescriptor.Builder().initParam("com.sun.jersey.config.property.packages", "com.gss.gmo.cao.restclient.provider").build();
        }

        @Override
        @Before
        public void setUp() throws Exception {
            super.setUp();
            List<Object> providers = new ArrayList<Object>();
            providers.add(new GsonMessageBodyProvider());
            testResource = JAXRSClientFactory.create("http://localhost:9998", TestResource.class, providers);
        }

        @Test
        public void testGetDate() {
            Date date = testResource.getDate();
            assertEquals(ISODateTimeFormat.dateTime().parseDateTime("2012-12-14T09:21:00.123+08:00").toDate(), date);
        }
    }
當我們要接上一個外部RESTful Web Services時,只要依照對方提供的API,依樣畫葫蘆改用JSR311做出interface之後,也就等於完成client端的程式了。