0

Ich versuche, eine RESTfull-Web-Service-Ressource aufzurufen, diese Ressource wird von einer Drittpartei zur Verfügung gestellt, die Ressource wird mit OPTIONS http Verb veröffentlicht.Wie senden HTTP OPTIONS-Anfrage mit Körper mit Spring Rest-Vorlage?

Um mit dem Dienst zu integrieren, sollte ich eine Anfrage mit einem bestimmten Körper senden, welche Identitäten von einem Anbieter, aber wenn ich das tat, bekam ich eine schlechte Anfrage. Ich erkannte Danach habe ich meinen Code verfolgen dann, dass der Körper des Antrags durch Ruhe Vorlage basiert auf den folgenden Code ignoriert wird:

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

meine Frage, ist es eine standardisierte Möglichkeit, dieses Verhalten zu überschreiben, oder sollte ich ein anderes verwenden Werkzeug?

Antwort

1

Der Code, den Sie eingefügt haben, ist von

SimpleClientHttpRequestFactory.prepareConnection(HttpURLConnection connection, String httpMethod) 

Ich weiß, weil ich vor, dass Code paar Stunden gedebuggt haben. Ich musste eine HTTP GET mit Körper mit RestTemplate tun. Also habe ich SimpleClientHttpRequestFactory erweitert, prepareConnection überschrieben und ein neues RestTemplate mit der neuen Factory erstellt.

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

}

Erstellen Sie ein neues RestTemplate auf dieser Fabrik basiert

new RestTemplate(new SimpleClientHttpRequestWithGetBodyFactory()); 

Ein Test, um die Lösung zu beweisen, arbeitet mit Federverschluß (@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(); 
    } 
} 

}

+0

Ich habe die gleiche abgeleitete SimpleClientHttpRequestWithGetBodyFactory mit connection.setDoOutput (true) für httpMethod = OPTIONS erneut getestet. Das Rest-Template wirft: org.springframework.web.client.ResourceAccessException: E/A-Fehler bei OPTIONS-Anfrage für "http: // localhost: 18181/test": HTTP-Methode OPTIONS unterstützt keine Ausgabe; Die verschachtelte Ausnahme ist java.net.ProtocolException: Die HTTP-Methode OPTIONS unterstützt keine Ausgabe. Aus diesem Grund haben Optionen connection.setDoOutput (false); –