使用自定义标头重新设置GET请求

时间:2016-07-09 20:16:16

标签: spring rest resttemplate custom-headers

我需要发送带有标头的GET请求:Content-Type: application/camiant-msr-v2.0+xml。我期待来自服务器的XML响应。我用Postman测试了请求和响应,一切都很好。但是当我尝试在RestTemplate的Spring中执行此操作时,我总是得到400个错误的请求。 spring的例外情况是:

Jul 09, 2016 12:53:38 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [/smp] threw exception [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException: 400 Bad Request] with root cause
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:475)

我的代码:

MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Content-Type", "application/camiant-msr-v2.0+xml");

HttpEntity<?> entity = new HttpEntity<Object>(headers);
log.debug("request headers: " + entity.getHeaders());
ResponseEntity<String> response = restTemplate.exchange(queryUrl, HttpMethod.GET, entity, String.class);

调试消息显示标题为{Content-Type=[application/camiant-msr-v2.0+xml]},这似乎是正确的。我想知道我的请求有什么问题,以及是否有办法在线路上查看调试请求。

3 个答案:

答案 0 :(得分:3)

以下对我有用:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

@Service
public class Http {

    @Autowired
    private RestTemplate restTemplate;

    public String doGet(final String url) throws Exception {
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
        headers.add(HttpHeaders.USER_AGENT, "Mozilla/5.0");
        headers.add(HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.8");
        HttpEntity<?> entity = new HttpEntity<Object>(headers);
        HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        return response.getBody();
    }

}

答案 1 :(得分:1)

400的可能解释是内容类型不适用于请求或网址不匹配。

根据我的个人经验,我强烈感觉你正在弄乱queryUrl所以要在这里微调一下,我建议你使用Spring的UriComponentsBuilder课程。

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
        .queryParam("data", data);

HttpEntity<?> entity = new HttpEntity<>(headers);

HttpEntity<String> response = restTemplate.exchange(
        builder.build().encode().toUri(), 
        HttpMethod.GET, 
        entity, 
        String.class);

如果它仍然不起作用,请告诉我。

答案 2 :(得分:1)

实际上要传递的标题应该命名为Accept而不是Content-Type,因为它是一个GET方法。但是服务器API文档以某种方式表示它期望Content-Type,而来自命令行/ Postman的API在Content-TypeAccept上都运行良好。我认为这是Java库阻止Content-Type标头传递给GET请求。