@Get Android Annotations中的任意查询参数

时间:2014-01-28 00:47:40

标签: android rest android-annotations

似乎我无法将任意查询参数设置为@Get声明

我的端点看起来像

http://api.lmiforall.org.uk/api/v1/ashe/estimateHours?soc=2349&coarse=true

此查询有一些非常重要的参数,是否有可用于向@Rest界面指示此参数的声明?

我尝试将其声明为此,但它抱怨字段未被使用。

@Get("estimateHours")
ASHEFilterInfo GetEstimateHours( int soc, boolean coarse, String filters, String breakdown);

java: @org.androidannotations.annotations.rest.Get annotated method has only url variables in the method parameters

5 个答案:

答案 0 :(得分:1)

请看AA cookbook

试试这个(未经测试):


@Rest(rootUrl = "http://api.lmiforall.org.uk/api/v1/ashe")
public interface MyService {

    @Get("/estimateHours?soc={soc}&coarse={coarse}&breakdown={breakdonw}&filters={filters}")
    ASHEFilterInfo GetEstimateHoursFiltered( int soc, boolean coarse, String filters, String breakdown);

  @Get("/estimateHours?soc={soc}&coarse={coarse}&breakdown={breakdonw}")
    ASHEFilterInfo GetEstimateHours( int soc, boolean coarse, String breakdown);

}

答案 1 :(得分:1)

当我需要创建具有许多动态参数的@Get请求时,其中一些可能会被复制,我已经解决了这个问题:

@Rest(rootUrl = "http://example.com:9080/",
        converters = { GsonHttpMessageConverter.class },
        interceptors = { ApiInterceptor.class })
public interface ExampleApi {

   @Get("content/home/product-type/list?{filters}&domain={domain}") //filters is String like "param1=value1&param1=value2&param3=value3"
   ProductTypeListResponse getProductTypeList(int domain, String filters);

 }

public class ApiInterceptor implements ClientHttpRequestInterceptor {

    private static final String TAG = ApiInterceptor.class.getSimpleName();

    @Override
    public ClientHttpResponse intercept(final HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        final QueryMultiParamsHttpRequest modifiedRequest = new QueryMultiParamsHttpRequest(request);
        return execution.execute(modifiedRequest, body);
    }
}

public class QueryMultiParamsHttpRequest implements HttpRequest {

    private static final String TAG = QueryParametersBuilder.class.getSimpleName();
    private HttpRequest httpRequest;

    public QueryMultiParamsHttpRequest(final HttpRequest httpRequest) {
        this.httpRequest = httpRequest;
    }

    @Override
    public HttpMethod getMethod() {
        return httpRequest.getMethod();
    }

    @Override
    public URI getURI() {
        final URI originalURI = httpRequest.getURI();
        final String query = originalURI.getQuery() != null ? originalURI.getQuery().replace("%3D", "=").replace("%26", "&") : null;
        URI newURI = null;
        try {
            newURI = new URI(originalURI.getScheme(), originalURI.getUserInfo(), originalURI.getHost(), originalURI.getPort(), originalURI.getPath(),
                    query, originalURI.getFragment());
        } catch (URISyntaxException e) {
            Log.e(TAG, "Error while creating URI of QueryMultiParamsHttpRequest", e);
        }
        return newURI;
    }

    @Override
    public HttpHeaders getHeaders() {
        return httpRequest.getHeaders();
    }
}

所以,我为HttpRequest创建了一个包装器,它可以解码符号" ="和"&"。这个包装器取代了ApiInterceptor中的原始HttpRequest。这是一个有点hacky的解决方案,但它确实有效。

答案 2 :(得分:0)

我遇到了同样的问题并提出了另一种解决方案,虽然远非理想,但仍有效。我试图解决的特殊问题是处理" HATEOAS"链接。

我最终做的是创建一个名为HATEOASClient的单独类来包含端点方法,这些方法不会转义为以params方式传入的HATEOAS链接。为此,我基本上只是查看了一个自动生成的端点方法,并在我的实现中强制/调整了主体。

这些方法使用相同的RestTemplate实例AndroidAnnotations设置,因此您仍然可以访问您在RestTemplate上执行的所有常规设置。

例如:

    public ResponseEntity<Foo> postFoo(Foo foo) {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.set(RestHeader.AUTH_TOKEN_HEADER, getClient().getHeader(RestHeader.AUTH_TOKEN_HEADER));
            httpHeaders.set(RestHeader.ACCEPT_LANGUAGE_HEADER, getClient().getHeader(RestHeader.ACCEPT_LANGUAGE_HEADER));
            httpHeaders.setAuthorization(authentication);
            HttpEntity<Foo> requestEntity = new HttpEntity<>(null, httpHeaders);
            HashMap<String, Object> urlVariables = new HashMap<>();
            urlVariables.put("link", foo.getLinks().getFooCreate().getHref());
            URI expanded = new UriTemplate(getClient().getRootUrl().
                    concat(API_VERSION + "{link}")).expand(urlVariables);
            final String url;
            try {
                url = URLDecoder.decode(expanded.toString(), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            return getClient().getRestTemplate().
                    exchange(url, HttpMethod.POST, requestEntity, Foo.class, urlVariables);
    }

答案 3 :(得分:0)

如果需要所有参数,您可以使用@Path注释。

@Rest(rootUrl = "http://api.lmiforall.org.uk/api/v1/ashe")
public interface MyService {

    @Get("/estimateHours?soc={soc}&coarse={coarse}&breakdown={breakdown}&filters={filters}")
    ASHEFilterInfo GetEstimateHours(@Path int soc, @Path boolean coarse, @Path String breakdown, @Path String filters);

}

如果其中一个参数是可选的,那么您还没有一个解决方案可以使用Android Annotations轻松传递参数。但任何人都可以contribute更好地使用Android注释。

答案 4 :(得分:-1)

如果为每个方法定义参数,则需要在每个请求中提供它们。我认为这有点过于杀人所以我所做的只是在我的api客户端中制作一个通用的get / post请求然后只需手动输入值,如果你没有定义根URL我想你可以使用QueryStringBuilder类并以这种方式建立uri。

@Rest(rootUrl = "https://path/to/api/", converters = { FormHttpMessageConverter.class,
    GsonHttpMessageConverter.class, ByteArrayHttpMessageConverter.class })

    public interface ApiClient {

@Get("{uri}")
JsonElement apiGet(String uri);

@Post("{uri}")
JsonObject apiPost(String uri,MultiValueMap data);

RestTemplate getRestTemplate();

void setRootUrl(String rootUrl);

void setRestTemplate(RestTemplate restTemplate);

}

使用示例

JsonElement resp = apiClient.apiGet("method/?random_param=1&another_param=test);

它不是那么干净但可以是动态的