使用Spring RestTemplate for Android进行经过身份验证的POST请求

Nic*_*rty 58 java rest spring android resttemplate

我有一个RESTful API,我试图通过Android和RestTemplate连接.所有对API的请求都通过HTTP身份验证进行身份验证,方法是设置HttpEntity的标头,然后使用RestTemplate的exchange()方法.

所有GET请求都以这种方式工作,但我无法弄清楚如何完成经过身份验证的POST请求.postForObjectpostForEntity处理POST,但没有简单的方法来设置身份验证标头.

因此对于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);
Run Code Online (Sandbox Code Playgroud)

但POST显然无法使用,exchange()因为它从不发送自定义标头,我也看不到如何设置请求体使用exchange().

从RestTemplate进行经过身份验证的POST请求的最简单方法是什么?

Nic*_*rty 109

好的找到了答案.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);
Run Code Online (Sandbox Code Playgroud)

  • 它抛出一个TypeMismatch错误类型不匹配:不能从ResponseEntity <为MyModel>到为MyModel转换..我想应当ResponseEntity <为MyModel>模型= restTemplate.exchange( "/ API/URL",HttpMethod.POST,httpEntity,MyModel.class ); (2认同)
  • 谢谢。这花了我两个小时,直到我偶然发现了您的职位。 (2认同)

And*_*rey 22

略有不同的方法:

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);
Run Code Online (Sandbox Code Playgroud)

  • ObjectToPass来自哪里 (3认同)
  • @Ismail Iqbal - 它可以是任何包含您需要传递的信息的对象(例如 private Person john = Person("John", 24);)。它将转换为 json 负载并通过请求正文发送到服务器 (3认同)

zac*_*ran 10

当我在尝试从Java进行REST调用时尝试通过身份验证时,我最近处理了一个问题,虽然这个线程(和其他线程)的答案有所帮助,但仍然有一些试验和错误涉及到它工作.

对我有用的是编码凭证Base64并将其添加为基本授权标头.然后我将它们添加为HttpEntityto 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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Sou*_*mya 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());
Run Code Online (Sandbox Code Playgroud)