72

AndroidとRestTemplateを介して接続しようとしているRESTful APIがあります。exchange()API へのすべてのリクエストは、HttpEntity のヘッダーを設定してから RestTemplate のメソッドを使用することにより、HTTP 認証で認証されます。

すべての GET リクエストはこの方法でうまく機能しますが、認証された POST リクエストを達成する方法がわかりません。postForObjectPOSTをpostForEntity処理しますが、認証ヘッダーを設定する簡単な方法はありません。

したがって、GET の場合、これはうまく機能します。

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

exchange()しかし、カスタマイズされたヘッダーを送信しないため、POST は明らかに機能しませんexchange()

RestTemplate から認証済みの POST リクエストを作成する最も簡単な方法は何ですか?

4

4 に答える 4

136

わかりました。答えが見つかりました。exchange()が最善の方法です。奇妙なことに、HttpEntityクラスにはメソッドがありませんsetBody()(メソッドはありますgetBody()) が、コンストラクターを介してリクエスト本文を設定することは可能です。

// 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);
于 2012-05-01T20:45:09.123 に答える
26

少し異なるアプローチ:

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);
于 2014-11-12T08:22:48.053 に答える
12

私は最近、Java から REST 呼び出しを行っているときに認証を通過しようとしていたときに問題に対処していました。働く。

私にとってうまくいったのは、資格情報をエンコードしBase64、それらを Basic Authorization ヘッダーとして追加することでした。HttpEntity次に、それらをtoとして追加すると、restTemplate.postForEntity必要な応答が得られました。

これは私が書いた完全なクラスです(RestTemplateを拡張しています):

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);
    }
}
于 2015-06-26T14:34:37.577 に答える
8

非常に便利です。要求 xml 自体が POST の本体であり、パラメーターではないという、わずかに異なるシナリオがありました。そのためには、次のコードを使用できます-同様の問題を抱えている他の誰かが恩恵を受ける場合に備えて、回答として投稿します。

    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());
于 2012-07-24T13:07:29.997 に答える