Как отправить запрос HTTP OPTIONS с телом, используя шаблон Spring rest?

Я пытаюсь вызвать ресурс веб-службы RESTfull, этот ресурс предоставляется третьей стороной, ресурс предоставляется с помощью HTTP-глагола OPTIONS.

Чтобы интегрироваться с сервисом, я должен отправить запрос с определенным телом, которое идентифицируется провайдером, но когда я это сделал, я получил плохой запрос. После этого я отслеживаю свой код, после чего я понял, что тело запроса игнорируется оставшимся шаблоном на основе приведенного ниже кода:

if ("POST".equals(httpMethod) || "PUT".equals(httpMethod) ||
            "PATCH".equals(httpMethod) || "DELETE".equals(httpMethod)) {
        connection.setDoOutput(true);
    }
    else {
        connection.setDoOutput(false);
    }

мой вопрос, есть ли стандартный способ переопределить это поведение или мне следует использовать другой инструмент?


person AmjadD    schedule 23.06.2016    source источник


Ответы (1)


Код, который вы вставили, взят из

SimpleClientHttpRequestFactory.prepareConnection(HttpURLConnection connection, String httpMethod)

Я знаю, потому что отлаживал этот код несколько часов назад. Мне пришлось сделать HTTP GET с телом, используя restTemplate. Поэтому я расширил SimpleClientHttpRequestFactory, переопределил prepareConnection и создал новый RestTemplate, используя новую фабрику.

public class SimpleClientHttpRequestWithGetBodyFactory extends SimpleClientHttpRequestFactory {

@Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
    super.prepareConnection(connection, httpMethod);
    if ("GET".equals(httpMethod)) {
        connection.setDoOutput(true);
    }
}

}

Создайте новый RestTemplate на основе этой фабрики

new RestTemplate(new SimpleClientHttpRequestWithGetBodyFactory());

Тест, подтверждающий, что решение работает с использованием весенней загрузки (@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT))

public class TestRestTemplateTests extends AbstractIntegrationTests {

@Test
public void testMethod() {
    RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestWithBodyForGetFactory());

    HttpEntity<String> requestEntity = new HttpEntity<>("expected body");

    ResponseEntity<String> responseEntity = restTemplate.exchange("http://localhost:18181/test", HttpMethod.GET, requestEntity, String.class);
    assertThat(responseEntity.getBody()).isEqualTo(requestEntity.getBody());
}

@Controller("/test")
static class TestController {

    @RequestMapping
    public @ResponseBody  String testMethod(HttpServletRequest request) throws IOException {
        return request.getReader().readLine();
    }
}

}

person Florin Grozea    schedule 07.10.2016
comment
Я повторно протестировал тот же производный SimpleClientHttpRequestWithGetBodyFactory с connection.setDoOutput(true) для httpMethod = OPTIONS. Остальной шаблон выдает: org.springframework.web.client.ResourceAccessException: ошибка ввода-вывода при запросе OPTIONS для localhost:18181/ test: HTTP-метод OPTIONS не поддерживает вывод; вложенным исключением является java.net.ProtocolException: метод HTTP OPTIONS не поддерживает вывод. Вот почему в Options есть connection.setDoOutput(false); - person Florin Grozea; 08.10.2016