首页 文章

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

提问于
浏览
47

我有一个RESTful API I 'm trying to connect with via Android and RestTemplate. All requests to the API are authenticated with HTTP Authentication, through setting the headers of the HttpEntity and then using RestTemplate' s 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);

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

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

4 回答

  • 7

    好的找到了答案 . 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);
    
  • 99

    略有不同的方法:

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

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

    对我有用的是在 Base64 中编码凭据并将它们添加为基本授权标头 . 然后我将它们作为 HttpEntity 添加到 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);
        }
    }
    
  • 19

    非常有用我有一个稍微不同的场景,我请求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());
    

相关问题