@在Android注释中获取任意查询参数
似乎我无法将任意查询参数设置为@Get声明 我的端点看起来像@在Android注释中获取任意查询参数,android,rest,android-annotations,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 fi
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
看
尝试以下方法(未测试):
@Rest(rootUrl=”http://api.lmiforall.org.uk/api/v1/ashe")
公共接口MyService{
@Get(“/estimateHours?soc={soc}&Rough={Rough}&BreakdownW}&filters={filters}”)
ASHEFilterInfo GetEstimateHoursFiltered(整数soc、布尔粗集、字符串过滤器、字符串细分);
@Get(“/estimateHours?soc={soc}&Rough={Rough}&Breakdownw}”)
ASHEFilterInfo GetEstimateHours(整数soc、布尔粗集、字符串细分);
}
如果为每个方法定义参数,则需要在每个请求中提供它们。我认为这也有点过分,所以我所做的只是在我的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);
它没有那么干净,但可以是动态的当我需要创建带有许多动态参数的@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。这是一个有点老套的解决方案,但它是有效的。我遇到了同样的问题,并提出了另一个解决方案,虽然远不理想,但仍然有效。我试图解决的问题是如何处理“HATEOAS”链接 我最后做的是创建一个名为HATEOASClient的单独类来包含端点方法,这些端点方法不会逃逸作为参数传入的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);
}
public responseenty postFoo(Foo-Foo){
HttpHeaders HttpHeaders=新的HttpHeaders();
httpHeaders.set(RestHeader.AUTH_TOKEN_头,getClient().getHeader(RestHeader.AUTH_TOKEN_头));
httpHeaders.set(RestHeader.ACCEPT_LANGUAGE_头,getClient().getHeader(RestHeader.ACCEPT_LANGUAGE_头));
httpHeaders.setAuthorization(身份验证);
HttpEntity requestEntity=新的HttpEntity(null,httpHeaders);
HashMap urlVariables=新HashMap();
url变量.put(“link”,foo.getLinks().getFooCreate().getHref());
URI expanded=新的UriTemplate(getClient().getRootUrl()。
concat(API_版本+“{link}”).expand(urlVariables);
最终字符串url;
试一试{
url=urldecker.decode(扩展的.toString(),“UTF-8”);
}捕获(不支持的编码异常e){
抛出新的运行时异常(e);
}
返回getClient().getRestTemplate()。
交换(url、HttpMethod.POST、requestEntity、Foo.class、urlVariables);
}
如果需要所有参数,可以使用@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注释轻松地传递参数。但是任何人都可以使用更好的Android注释。问题在于,如果没有提供过滤器,那么会留下
&filters=&breakdown=test
,这可能是错误的。很容易:创建一个没有过滤器参数的新方法,但可能会有过滤器的任何排列aa不允许任何动态方式。直接使用Spring Android实现它(示例:)我不知道如何在REST界面中实现我很好奇你是如何做到这一点的,因为AA/RestTemplate会自动将此参数转义为“method/%3Frandom\u param…”我认为你是对的,你必须避免下划线,或者可能取消对查询字符串paramaters server sideGreat的编码,伙计!!!对我来说很好;用符号“=”和“&”解决我的问题。
@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);
}