2014-01-28 2 views
2

Это кажется, что я не могу установить произвольные параметры запроса к объявлению @Get@Get параметры произвольны запроса в Android аннотаций

Моя конечная точка выглядит

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 

ответ

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

Проблема с этим, если фильтры не предусмотрены, которые оставят '& filters = & breakdown = test', что может быть неправильным –

+0

Легко: создать новый метод без параметров фильтра – jmvivo

+1

Но могут быть любые перестановки фильтров –

-1

если вы определяете Params для каждого метода, то вы должны предоставить их в каждом запросе. Я подумал, что это слишком похоже на убийство, так что я сделал просто общий запрос на получение/отправку в моем клиенте api, а затем просто вручную введите значения, если вы не определяете корневой URL. Я полагаю, вы могли бы использовать класс QueryStringBuilder и построить ури таким образом.

@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); 

Это не так чисто, но может быть динамическим

+2

Мне любопытно, как вы получили это для работы, так как AA/RestTemplate автоматически вырвет этот параметр во что-то вроде «method /% 3Frandom_param ....» – Nick

+0

Я думаю, что вы правы, вам придется избегать подчеркивания или, возможно, unencode строка запроса param paramers server side – Brian

1

Когда мне нужно создать запрос @Get со многим динамическим parameteres, и некоторые из них могут быть дублированы, я решил эту проблему так:

@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, которая может декодировать символы "=" и "&". И эта оболочка заменяет оригинальный HttpRequest в ApiInterceptor. Это немного хакерское решение, но оно работает.

+0

Отлично, мужчина !!! Прекрасно работает для меня; решить мою проблему с символами «=» и «&». – kaleemsagard

0

Я столкнулся с этой проблемой и придумал другое решение, которое в то время как далекое от идеала, работает. Особой проблемой, которую я пытался решить, была обработка ссылок «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); 
    } 
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 аннотаций. Но кто-то может contribute улучшить Android Аннотации.

Смежные вопросы