Authentifizierte POST-Anforderungen mit Spring RestTemplate für Android stellen

Lesezeit: 4 Minuten

Benutzer-Avatar
Nick Daugherty

Ich habe eine RESTful-API, mit der ich über Android und RestTemplate eine Verbindung herstellen möchte. Alle Anforderungen an die API werden mit HTTP-Authentifizierung authentifiziert, indem die Header der HttpEntity festgelegt und dann die von RestTemplate verwendet werden exchange() Methode.

Alle GET-Anforderungen funktionieren auf diese Weise hervorragend, aber ich kann nicht herausfinden, wie authentifizierte POST-Anforderungen ausgeführt werden. postForObject und postForEntity verarbeiten POSTs, haben aber keine einfache Möglichkeit, die Authentifizierungsheader festzulegen.

Für GETs funktioniert das also hervorragend:

HttpAuthentication httpAuthentication = new HttpBasicAuthentication("username", "password");
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAuthorization(httpAuthentication);

HttpEntity<?> httpEntity = new HttpEntity<Object>(requestHeaders);

MyModel[] models = restTemplate.exchange("/api/url", HttpMethod.GET, httpEntity, MyModel[].class);

Aber POSTs funktionieren anscheinend nicht mit exchange() da es niemals die benutzerdefinierten Header sendet und ich nicht sehe, wie ich den Anforderungstext mit festlegen soll exchange().

Was ist der einfachste Weg, um authentifizierte POST-Anforderungen von RestTemplate zu stellen?

  • requestHeaders.setAuthorization(httpAuthentication).. seine undefinierte..keine Methode wie setAuthorization..

    – Sackgasse

    12. September 2017 um 9:00 Uhr

Benutzer-Avatar
Nick Daugherty

Okay Antwort gefunden. exchange() ist der beste Weg. Seltsamerweise die HttpEntity Klasse hat keine setBody() Methode (es hat getBody()), aber es ist immer noch möglich, den Anforderungstext über den Konstruktor festzulegen.

// Create the request body as a MultiValueMap
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();     

body.add("field", "value");

// Note the body object as first parameter!
HttpEntity<?> httpEntity = new HttpEntity<Object>(body, requestHeaders);

ResponseEntity<MyModel> response = restTemplate.exchange("/api/url", HttpMethod.POST, httpEntity, MyModel.class);

  • Es wird ein TypeMismatch-Fehler ausgegeben. Type mismatch: cannot convert from ResponseEntity to MyModel .. Ich denke, es sollte ResponseEntity model = restTemplate.exchange(“/api/url”, HttpMethod.POST, httpEntity, MyModel.class sein );

    – Sid

    7. April 2016 um 10:19 Uhr


  • MyModel myModel = restTemplate.exchange(completeServiceUrl, HttpMethod.GET, request, MyModel.class).getBody() wird helfen, das Problem zu lösen, das Sie erwähnt haben

    – 2280259

    31. August 2017 um 16:07 Uhr


  • DANKE. Das hat mich zwei Stunden gekostet, bis ich über deinen Beitrag gestolpert bin.

    – günhter

    8. Januar 2018 um 15:26 Uhr

  • Damit dies in neueren Spring Security-Umgebungen funktioniert, MÜSSEN Sie den CSRF-Schutz wie http.csrf().disable() deaktivieren.

    – M46

    23. Juli 2018 um 17:53 Uhr

Etwas anderer Ansatz:

MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("HeaderName", "value");
headers.add("Content-Type", "application/json");

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

HttpEntity<ObjectToPass> request = new HttpEntity<ObjectToPass>(objectToPass, headers);

restTemplate.postForObject(url, request, ClassWhateverYourControllerReturns.class);

  • Woher kommt ObjectToPass?

    – Ismail Iqbal

    18. Oktober 2016 um 9:53 Uhr

  • @Ismail Iqbal – es kann ein beliebiges Objekt mit Informationen sein, die Sie übergeben müssen (z. B. private Person john = Person (“John”, 24);). Es wird in JSON-Nutzdaten konvertiert und über den Anforderungstext an den Server gesendet

    – Andreas

    18. Oktober 2016 um 10:38 Uhr

Benutzer-Avatar
zacran

Ich habe mich kürzlich mit einem Problem befasst, als ich versuchte, die Authentifizierung zu umgehen, während ich einen REST-Aufruf von Java aus tätigte, und obwohl die Antworten in diesem Thread (und anderen Threads) geholfen haben, gab es immer noch ein bisschen Versuch und Irrtum, um es zu bekommen Arbeiten.

Was für mich funktioniert hat, war das Codieren von Anmeldeinformationen Base64 und sie als Kopfzeilen für die Basisautorisierung hinzufügen. Ich habe sie dann als hinzugefügt HttpEntity zu restTemplate.postForEntitywas mir die Antwort gab, die ich brauchte.

Hier ist die Klasse, die ich dafür vollständig geschrieben habe (RestTemplate erweitern):

public class AuthorizedRestTemplate extends RestTemplate{

    private String username;
    private String password;

    public AuthorizedRestTemplate(String username, String password){
        this.username = username;
        this.password = password;
    }

    public String getForObject(String url, Object... urlVariables){
        return authorizedRestCall(this, url, urlVariables);
    }

    private String authorizedRestCall(RestTemplate restTemplate, 
            String url, Object... urlVariables){
        HttpEntity<String> request = getRequest();
        ResponseEntity<String> entity = restTemplate.postForEntity(url, 
                request, String.class, urlVariables);
        return entity.getBody();
    }

    private HttpEntity<String> getRequest(){
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + getBase64Credentials());
        return new HttpEntity<String>(headers);
    }

    private String getBase64Credentials(){
        String plainCreds = username + ":" + password;
        byte[] plainCredsBytes = plainCreds.getBytes();
        byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
        return new String(base64CredsBytes);
    }
}

Sehr nützlich Ich hatte ein etwas anderes Szenario, in dem ich die XML-Anforderung selbst als Hauptteil des POST und nicht als Parameter bezeichnete. Dafür kann der folgende Code verwendet werden – Posting als Antwort, nur für den Fall, dass jemand anderes mit ähnlichen Problemen davon profitieren wird.

    final HttpHeaders headers = new HttpHeaders();
    headers.add("header1", "9998");
    headers.add("username", "xxxxx");
    headers.add("password", "xxxxx");
    headers.add("header2", "yyyyyy");
    headers.add("header3", "zzzzz");
    headers.setContentType(MediaType.APPLICATION_XML);
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML));
    final HttpEntity<MyXmlbeansRequestDocument> httpEntity = new HttpEntity<MyXmlbeansRequestDocument>(
            MyXmlbeansRequestDocument.Factory.parse(request), headers);
    final ResponseEntity<MyXmlbeansResponseDocument> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity,MyXmlbeansResponseDocument.class);
    log.info(responseEntity.getBody());

1187490cookie-checkAuthentifizierte POST-Anforderungen mit Spring RestTemplate für Android stellen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy