2015-11-27 3 views
2

Я пишу клиентское приложение для службы https://api.ai и использую org.springframework.web.client.RestTemplate для моих HTTP-запросов.RestTemplate DELETE throws HttpClientErrorException: 405 Метод не разрешен

Проблема заключается в том, что УДАЛЕНИЯ запросы всегда возвращают ошибку 405,

private static final String URL_INTENTS = "https://api.api.ai/v1/intents?v={apiVersion}"; 

HttpHeaders httpHeaders = new HttpHeaders(); 
        httpHeaders.setContentType(MediaType.APPLICATION_JSON); 
        httpHeaders.setAccept(Arrays.asList(new MediaType[]{MediaType.APPLICATION_JSON})); 
        httpHeaders.set("Authorization", "Bearer " + speaktoitConfig.getDeveloperAccessToken()); 
        httpHeaders.set("ocp-apim-subscription-key", speaktoitConfig.getSubscriptionKey()); 
        resp = restTemplate.exchange(
          URL_INTENTS, HttpMethod.DELETE, new HttpEntity<String>(intentId, httpHeaders), 
          AiVocabulariesResponse.class, speaktoitConfig.getApiVersion()).getBody(); 

но PUT и GET запросы работает отлично.

HttpHeaders httpHeaders = new HttpHeaders(); 
     httpHeaders.setContentType(MediaType.APPLICATION_JSON); 
     httpHeaders.setAccept(Arrays.asList(new MediaType[]{MediaType.APPLICATION_JSON})); 
     httpHeaders.set("Authorization", "Bearer " + speaktoitConfig.getDeveloperAccessToken()); 
     httpHeaders.set("ocp-apim-subscription-key", speaktoitConfig.getSubscriptionKey()); 
     resp = restTemplate.exchange(
       URL_INTENTS, HttpMethod.PUT, new HttpEntity<String>(JsonMapper.MAPPER.writeValueAsString(aiQueryIntentsList), httpHeaders), 
       AiVocabulariesResponse.class, speaktoitConfig.getApiVersion()); 

Я уверен, api.ai поддержать DELETE, потому что написано в их документах https://docs.api.ai/docs/intents

По вашему мнению, есть проблема с моим кодом, или я должен написать в апи. ai сервисная поддержка?

Вот полный код теста

import com.fasterxml.jackson.databind.JsonNode; 
    import com.fasterxml.jackson.databind.ObjectMapper; 
    import junit.framework.Assert; 
    import org.junit.Test; 
    import org.springframework.http.HttpEntity; 
    import org.springframework.http.HttpHeaders; 
    import org.springframework.http.HttpMethod; 
    import org.springframework.http.MediaType; 
    import org.springframework.web.client.RestTemplate; 

    import java.util.Arrays; 
    import java.util.Iterator; 
    import java.util.LinkedList; 
    import java.util.List; 


    public class TestDeleteRequest { 

     @Test 
     public void test1DeleteRequest() { 
      Assert.assertTrue(testDeleteRequest()); 
     } 

     public static final ObjectMapper MAPPER = new ObjectMapper(); 

     static boolean testDeleteRequest() { 

      final RestTemplate restTemplate = new RestTemplate(); 

      final String URL_INTENTS = "https://console.api.ai/v1/intents?v={apiVersion}"; 
      final String API_VERSION = "20150901"; 

      HttpHeaders httpHeaders = new HttpHeaders(); 
      httpHeaders.setContentType(MediaType.APPLICATION_JSON); 
      httpHeaders.setAccept(Arrays.asList(new MediaType[]{MediaType.APPLICATION_JSON})); 
      httpHeaders.set("Authorization", "Bearer " + "fc361168a9434289b7457408fa0acdd8"); 
      httpHeaders.set("ocp-apim-subscription-key", "76dba252-3e56-488d-9350-22f32b3b55f0"); 
    //download all elements headers 
      String respStr = null; 
      try { 
       respStr = restTemplate.exchange(
         URL_INTENTS, HttpMethod.GET, new HttpEntity<String>("", httpHeaders), 
         String.class, API_VERSION).getBody(); 
      } catch (Throwable e) { 
       return false; 
      } 
//parse elements ids 
      List<String> intentIds = new LinkedList<>(); 
      try { 
       int cnt = 1; 
       JsonNode rootNode = MAPPER.readTree(respStr); 
       Iterator<JsonNode> elements = rootNode.elements(); 
       while (elements.hasNext()) { 
        JsonNode aiIntentNode = elements.next(); 
        JsonNode aiIntentIdNode = aiIntentNode.path("id"); 
        String aiIntentId = aiIntentIdNode.asText(); 
        intentIds.add(aiIntentId); 
       } 
      } catch(Exception e) { 
       return false; 
      } 

      if (intentIds.isEmpty()) { 
       return false; 
      } 
//try to delete the first one 
      try { 
       restTemplate.exchange(
         URL_INTENTS, HttpMethod.DELETE, new HttpEntity<String>(intentIds.get(0), httpHeaders), 
         String.class, API_VERSION).getBody(); 
      } catch (Throwable e) { 
       return false; //TODO catch HttpClientErrorException 405 Method no Allowed 
      } 

      return true; 
     } 

    } 
+0

Вы можете удалить свой полный контроллер удаления, а также запрос, который вы отправили. – Patrick

+0

Если вы посмотрите на примеры, приведенные в этой ссылке, https://docs.api.ai/docs/intents, пример метода DELETE имеет URL-адрес как '/ intent /', что очень странно, как и весь другой метод и его примеры были определены как '/ intents /'. Даже заголовок метода DELETE определяется как '/ intents/{iid}', но в этом примере он указан только как '/ intent /'. Попробуйте заменить '/ intents /' на '/ intent /' в запросе 'DELETE'. –

ответ

0

Значение URL_INTENTS представляется неверным: на основе документации вы упомянутая выше, вы должны ударять URL /intents/{intent-id}. Однако, исходя из вашего значения https://api.api.ai/v1/intents?v={apiVersion}, вы не указываете идентификатор намерения удалить. Таким образом, когда сервер находит корневой ресурс /intents, он просто запрещает вам удалять этот корневой ресурс.