Java Jersey 客户端/JAX-RS 和可选(非默认)@QueryParam(客户端)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30147032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 09:13:56  来源:igfitidea点击:

Jersey Client / JAX-RS and optional (not default) @QueryParam (client side)

javarestjerseyjax-rs

提问by justderb

I have a RESTful API who's document says that a certain query parameter is optional, and does not supply a default argument. So, I can either supply the value or not send it in the GET request as a parameter.

我有一个 RESTful API,它的文档说某个查询参数是可选的,并且不提供默认参数。因此,我可以在 GET 请求中提供该值或不将其作为参数发送。

Example:

例子:

  • queryAis required
  • queryBis optional(can send GETwithout it)
  • queryA是必须的
  • queryB可选的(可以GET不带它发送)

This should work:

这应该有效:

http://www.example.com/service/endpoint?queryA=foo&queryB=bar

This should also work:

这也应该有效:

http://www.example.com/service/endpoint?queryA=foo

How do I make an client interface for Jersey-Proxythat can do this?? I do not have the server-side codeto interface with so I am using org.glassfish.jersey.client.proxy.WebResourceFactoryvia Jersey-Proxy to generate the client to interact with the server API.

我如何为Jersey-Proxy制作一个可以做到这一点的客户端界面?我没有org.glassfish.jersey.client.proxy.WebResourceFactory要与之交互的服务器端代码,因此我使用通过 Jersey-Proxy 来生成客户端以与服务器 API 交互。

Sample interface:

示例界面:

import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/service")
@Produces("application/json")
public interface ServiceInterface {

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first,
            @QueryParam("queryB") String second);

}

I know I can make another method:

我知道我可以制作另一种方法:

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first);

But what happens when you have multiple optional fields?? I don't want to make every possible mutation of them!

但是当您有多个可选字段时会发生什么?我不想对它们进行所有可能的突变!

采纳答案by justderb

The interface was right all along

界面一直都是对的

I can't believe it was this easy:

我不敢相信这是这么简单:

import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/service")
@Produces("application/json")
public interface ServiceInterface {

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first,
            @QueryParam("queryB") String second);

}

Notice anything different than the questions interface?? Nope. That's because that is the answer!

注意到与问题界面有什么不同吗??不。那是因为这就是答案!



Don't use @DefaultValue for optional parameters

不要将 @DefaultValue 用于可选参数

If you want to default a parameter to a specific value, you use the @DefaultValueannotation in the parameter:

如果要将参数默认为特定值,请使用@DefaultValue参数中的注释:

import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/service")
@Produces("application/json")
public interface ServiceInterface {

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first,
            @QueryParam("queryB") @DefaultValue("default") String second);

}


Pass nullto the @QueryParamyou don't want

传递null@QueryParam你不想要的

If you want to make the @QueryParamoptional, you do not apply the @DefaultValueannotation.To pass a value with the query parameter, just pass in the value normally. If you would like the query parameter to not show up at all, just pass null!

如果要使@QueryParam可选,则不应用@DefaultValue注释。要传递带有查询参数的值,只需正常传递值即可。如果您希望查询参数根本不显示,只需通过null

import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/service")
@Produces("application/json")
public interface ServiceInterface {

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first,
            // Pass null to this parameter to not put it in the GET request
            @QueryParam("queryB") String second);

}

So calling ServiceInterface.getEndpoint("firstQueryParam", "secondQueryParam");calls:

所以调用ServiceInterface.getEndpoint("firstQueryParam", "secondQueryParam");调用:

http://targethost.com/service/endpoint?queryA=firstQueryParam&queryB=secondQueryParam

and calling ServiceInterface.getEndpoint("firstQueryParam", null);calls:

并打电话ServiceInterface.getEndpoint("firstQueryParam", null);

http://targethost.com/service/endpoint?queryA=firstQueryParam

And walla! No second query parameter! :)

还有瓦拉!没有第二个查询参数!:)

Note on primitive values

关于原始值的注意事项

If your API takes primitive values (like int, float, boolean, etc), then use the object wrapper class (Autoboxing) for that primitive (like Integer, Float, Boolean, etc). Then, you can pass nullto the method:

如果您的API需要的原始值(如intfloatboolean,等),然后使用包装类(对象自动装箱)为原始的(如IntegerFloatBoolean,等)。然后,您可以传递null给该方法:

public Response getEndpoint(@QueryParam("queryA") Boolean first);

回答by Alex

You can inject a UriInfoinstance (or something else like HttpServletRequest) into your method, and get whatever data you want off of it.

您可以将一个UriInfo实例(或其他类似的东西HttpServletRequest)注入到您的方法中,并从中获取您想要的任何数据。

For example

例如

@Path("/endpoint")
@GET
public Response getEndpoint(@Context UriInfo info, @QueryParam("queryA") String queryA) {
  String queryB = info.getQueryParameters().getFirst("queryB");
  if (null != queryB) {
    // do something with it
  }
  ...
}