Я пишу клиентское приложение для службы 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;
}
}
Вы можете удалить свой полный контроллер удаления, а также запрос, который вы отправили. – Patrick
Если вы посмотрите на примеры, приведенные в этой ссылке, https://docs.api.ai/docs/intents, пример метода DELETE имеет URL-адрес как '/ intent /', что очень странно, как и весь другой метод и его примеры были определены как '/ intents /'. Даже заголовок метода DELETE определяется как '/ intents/{iid}', но в этом примере он указан только как '/ intent /'. Попробуйте заменить '/ intents /' на '/ intent /' в запросе 'DELETE'. –