似乎我无法将任意查询参数设置为@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
答案 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¶m1=value2¶m3=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);
它不是那么干净但可以是动态的