当前位置: 首页 > 知识库问答 >
问题:

DropWizard/Jersey API客户端

薛烈
2023-03-14

DropWizard在REST的引擎盖下使用泽西。我正在尝试弄清楚如何为我的DropWizard应用程序将公开的RESTfulendpoint编写客户端。

为了这个例子,让我们假设我的DropWizard应用程序有一个< code>CarResource,它为CRUDding cars公开了几个简单的RESTfulendpoint:

@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客户端将类似于汽车服务客户端

// 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.
    }
}

但是我能找到的关于Drop Wizard客户端的仅有的两个官方引用是完全矛盾的:

  • DropWizard推荐的项目结构-它声称我应该把我的客户端代码放在car-client项目下car.service.client
  • 包;但是…
  • DropWizard客户端手册-这让它看起来像一个“DropWizard客户端”,用于将我的DropWizard应用程序与其他RESTful Web服务集成(从而充当中间人)。

所以我问,为DropWizard web服务编写Java API客户端的标准方法是什么?DropWizard是否有可用于此类用例的客户端库?我应该通过泽西客户端API实现客户端吗?有人可以向我的CarServiceClient添加伪代码,这样我就可以理解这是如何工作的?

共有3个答案

汝天宇
2023-03-14

如果任何人在构建客户端时尝试使用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>
刘嘉木
2023-03-14

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

无论如何,它对HttpClients并没有太大的魔力。它只是根据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();
    }
  }
曾阳飙
2023-03-14

下面是您可以使用 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));
 类似资料:
  • 我正在做一些关于拖放向导安全性和身份验证的研究。这是我 http://howtodoinjava.com/dropwizard/dropwizard-basic-auth-security-example/ 使用的链接。 我的问题是如何实际创建新用户,因为VALID_users是静态final,不能更改。我正在考虑创建一个数据库,它将由包含用户名和角色(例如admin)的用户对象组成。(我不需要密

  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se

  • URI 方法 URI() string 返回当前客户端使用的服务器地址。 SetURI 方法 SetURI(uri string) 设置当前客户端使用的服务器地址。如果你想要设置多个服务器地址,请使用 SetURIList 方法代替该方法。 URIList 方法 URIList() []string 返回当前客户端可使用的服务器地址列表。 SetURIList 方法 SetURIList(uriL

  • 客户端事件通过 SetEvent 方法进行设置。 客户端事件有两个,它们分别定义为: type onErrorEvent interface { OnError(name string, err error) }   type onFailswitchEvent interface { OnFailswitch(Client) } 因为 go 语言不需要显式实现接口的特点,所以这两

  • 创建客户端有两种方式,一种是直接使用特化的构造器函数,另一种是使用工厂构造器函数。 第一种方式返回的是具体的客户端结构体指针对象,第二种方式返回的是客户端接口对象。 使用特化的构造器函数创建客户端 特化的构造器函数有下面几个: func NewHTTPClient(uri ...string) (client *HTTPClient) func NewTCPClient(uri ...string

  • Dropwizard 是一个 Java 框架,用于开发易于运维,高性能的 RESTful 网络服务。 它由Yammer开发,用于增强基于JVM的后端服务,集合了来自Java生态系统中的稳定和成熟的程序库,组成了简单,轻量级的程序包,使得用户可以专注于把事情做好。 Dropwizard已是开箱即用的,它支持复杂的配置,应用环境, 日志和运维工具,使得你和你的团队可能在最短的时间内交付一个一流品质 HTTP+JSON 网络服务。