2014-10-29 177 views
6

DropWizard使用Jersey爲REST引擎蓋下。我想弄清楚如何爲我的DropWizard應用程序將公開的RESTful端點編寫客戶端。DropWizard/Jersey API客戶端

對於這個例子的目的,讓我們說我DropWizard應用程序有一個CarResource,這暴露了幾個簡單的RESTful端點CRUDding汽車:

@Path("/cars") 
public class CarResource extends Resource { 
    // CRUDs car instances to some database (DAO). 
    public CardDao carDao = new CarDao(); 

    @POST 
    public Car createCar(String make, String model, String rgbColor) { 
     Car car = new Car(make, model, rgbColor); 
     carDao.saveCar(car); 

     return car; 
    } 

    @GET 
    @Path("/make/{make}") 
    public List<Car> getCarsByMake(String make) { 
     List<Car> cars = carDao.getCarsByMake(make); 
     return cars; 
    } 
} 

所以我會想象一個結構化的API客戶端將會像CarServiceClient

// Packaged up in a JAR library. Can be used by any Java executable to hit the Car Service 
// endpoints. 
public class CarServiceClient { 
    public HttpClient httpClient; 

    public Car createCar(String make, String model, String rgbColor) { 
     // Use 'httpClient' to make an HTTP POST to the /cars endpoint. 
     // Needs to deserialize JSON returned from server into a `Car` instance. 
     // But also needs to handle if the server threw a `WebApplicationException` or 
     // returned a NULL. 
    } 

    public List<Car> getCarsByMake(String make) { 
     // Use 'httpClient' to make an HTTP GET to the /cars/make/{make} endpoint. 
     // Needs to deserialize JSON returned from server into a list of `Car` instances. 
     // But also needs to handle if the server threw a `WebApplicationException` or 
     // returned a NULL. 
    } 
} 

但只有兩個官方引用刪除嚮導客戶我能看到的是完全矛盾彼此:

  • DropWizard recommended project structure - 聲稱我應該把我的客戶端代碼在car-client項目下car.service.client包;但後來...
  • DropWizard Client manual - 這使得它看起來像一個「DropWizard客戶端」是用於集成我的DropWizard應用程序與其他 REST風格的Web服務(因此充當中間人)。

所以我問,爲您的DropWizard Web服務編寫Java API客戶端的標準方式是什麼? DropWizard有一個客戶端庫,我可以利用這種類型的用例嗎?我應該通過一些Jersey客戶端API來實現客戶端嗎?有人可以添加僞代碼到我的CarServiceClient,所以我可以理解這將如何工作?

回答

-10

你可以用Spring框架集成以實現

0

是的,有什麼dropwizard客戶端提供只由服務本身使用,最容易溝通等服務。它不直接爲客戶端應用程序提供任何內容。

無論如何它並沒有對HttpClient有太大的魔力。它只是根據yml文件配置客戶端,將現有的Jackson對象映射器和驗證器分配給Jersey客戶端,我認爲重用了應用程序的線程池。你可以檢查所有的https://github.com/dropwizard/dropwizard/blob/master/dropwizard-client/src/main/java/io/dropwizard/client/JerseyClientBuilder.java

我想我會去和結構我的班,就像你使用澤西客戶端。以下是一個抽象類,我已經使用了客戶端服務:

public abstract class HttpRemoteService { 

    private static final String AUTHORIZATION_HEADER = "Authorization"; 
    private static final String TOKEN_PREFIX = "Bearer "; 

    private Client client; 

    protected HttpRemoteService(Client client) { 
    this.client = client; 
    } 

    protected abstract String getServiceUrl(); 

    protected WebResource.Builder getSynchronousResource(String resourceUri) { 
    return client.resource(getServiceUrl() + resourceUri).type(MediaType.APPLICATION_JSON_TYPE); 
    } 

    protected WebResource.Builder getSynchronousResource(String resourceUri, String authToken) { 
    return getSynchronousResource(resourceUri).header(AUTHORIZATION_HEADER, TOKEN_PREFIX + authToken); 
    } 

    protected AsyncWebResource.Builder getAsynchronousResource(String resourceUri) { 
    return client.asyncResource(getServiceUrl() + resourceUri).type(MediaType.APPLICATION_JSON_TYPE); 
    } 

    protected AsyncWebResource.Builder getAsynchronousResource(String resourceUri, String authToken) { 
    return getAsynchronousResource(resourceUri).header(AUTHORIZATION_HEADER, TOKEN_PREFIX + authToken); 
    } 

    protected void isAlive() { 
    client.resource(getServiceUrl()).get(ClientResponse.class); 
    } 

} 

,這裏是如何使其具體:

private class TestRemoteService extends HttpRemoteService { 

    protected TestRemoteService(Client client) { 
     super(client); 
    } 

    @Override 
    protected String getServiceUrl() { 
     return "http://localhost:8080"; 
    } 

    public Future<TestDTO> get() { 
     return getAsynchronousResource("/get").get(TestDTO.class); 
    } 

    public void post(Object object) { 
     getSynchronousResource("/post").post(object); 
    } 

    public void unavailable() { 
     getSynchronousResource("/unavailable").get(Object.class); 
    } 

    public void authorize() { 
     getSynchronousResource("/authorize", "ma token").put(); 
    } 
    } 
1

是否有人試圖用DW建立時0.8.2客戶端,並且出現以下錯誤:

cannot access org.apache.http.config.Registry 
class file for org.apache.http.config.Registry not found 

at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:858) 
at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:129) 
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132) 
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208) 
... 19 more 

將您的pom.xml中的dropwizard-client從0.8.2更新到0.8。 你應該很好。我相信一個碼頭子依賴項被更新了,它修復了它。

<dependency> 
     <groupId>io.dropwizard</groupId> 
     <artifactId>dropwizard-client</artifactId> 
     <version>0.8.4</version> 
     <scope>compile</scope> 
    </dependency> 
1

以下是可以使用JAX-RS客戶端使用的模式。

獲取客戶端:

javax.ws.rs.client.Client init(JerseyClientConfiguration config, Environment environment) { 
    return new JerseyClientBuilder(environment).using(config).build("my-client"); 
} 

然後,您可以撥打電話的方式如下:

javax.ws.rs.core.Response post = client 
     .target("http://...") 
     .request(MediaType.APPLICATION_JSON) 
     .header("key", value) 
     .accept(MediaType.APPLICATION_JSON) 
     .post(Entity.json(myObj));