DropWizard/Jersey API客户端

5

DropWizard在REST方面使用Jersey。我正在尝试弄清楚如何为我的DropWizard应用程序编写RESTful端点的客户端。

为了举例说明,假设我的DropWizard应用程序有一个CarResource,它公开了一些简单的RESTful端点以CRUD汽车:

@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客户端的官方参考资料彼此完全相反:
  • DropWizard 推荐项目结构 - 声称我应该将客户端代码放在 car.service.client 包下的 car-client 项目中;但是...
  • DropWizard 客户端手册 - 看起来好像 "DropWizard 客户端" 是用于将我的 DropWizard 应用程序与其他 RESTful Web 服务集成(从而充当中间人)。
所以我想问,编写 Java API 客户端的标准方式是什么?DropWizard 是否有一个客户端库可供我在这种情况下使用?我是否应该通过某些 Jersey 客户端 API 实现客户端?有人能够向我的 CarServiceClient 添加伪代码,以便我了解如何工作吗?
4个回答

2

以下是使用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));

0

是的,dropwizard-client提供的只能由服务本身使用,很可能用于与其他服务通信。它不直接为客户端应用程序提供任何内容。

它也不会在HttpClients方面做太多魔法。它只是根据yml文件配置客户端,将现有的Jackson对象映射器和验证器分配给Jersey客户端,并且我认为重用应用程序的线程池。您可以在https://github.com/dropwizard/dropwizard/blob/master/dropwizard-client/src/main/java/io/dropwizard/client/JerseyClientBuilder.java上检查所有这些内容。

我认为我会像您使用Jersey Client一样构建我的类。以下是我一直在使用的客户端服务的抽象类:

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();
    }
  }

0

如果有人在构建客户端时尝试使用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.4,然后应该就可以了。我相信jetty的子依赖项已经得到了更新,问题已经解决。

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

-10

您可以集成Spring框架来实现


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接