制作认证POST请求同春RestTemplate为Android(Making authentica

2019-06-24 00:59发布

我有我试图通过Android和RestTemplate与连接一个RESTful API。 API的所有请求的身份验证与HTTP认证,通过设置HttpEntity的头,然后用RestTemplate的exchange()方法。

所有GET请求工作带来极大的这种方式,但我想不出如何完成身份验证的POST请求。 postForObjectpostForEntity车把支柱,但有没有简单的方法来设置身份验证头。

因此,对于入眼,这个伟大的工程:

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

但显然的POST不与合作exchange()因为它永远不会发送定制的头,我不明白如何使用设置请求体exchange()

是什么力量让从RestTemplate验证POST请求的最简单的方法?

Answer 1:

好找到了答案。 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);

MyModel model = restTemplate.exchange("/api/url", HttpMethod.POST, httpEntity, MyModel.class);


Answer 2:

略有不同的方法:

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


Answer 3:

我最近处理的时候,我试图同时使从Java中的REST调用来获取过去的认证的问题,而在这个线程的答案(和其他线程)的帮助下,仍有参与得到它有点试验和错误工作。

什么工作对我来说是在编码证书Base64和其添加为基本授权头。 然后我加入他们作为HttpEntityrestTemplate.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);
    }
}


Answer 4:

非常有用的我有一个稍微不同的情景,我请求XML本身就是该职位的身体,而不是设置了一个param。 对于下面的代码可以使用 - 以防万一别人有类似的问题,将有利于发帖作为一个答案。

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


文章来源: Making authenticated POST requests with Spring RestTemplate for Android