【问题标题】:How to set an "Accept:" header on Spring RestTemplate request?如何在 Spring RestTemplate 请求上设置“Accept:”标头?
【发布时间】:2013-10-14 20:17:34
【问题描述】:

我想在使用 Spring 的 RestTemplate 发出的请求中设置 Accept: 的值。

这是我的 Spring 请求处理代码

@RequestMapping(
    value= "/uom_matrix_save_or_edit", 
    method = RequestMethod.POST,
    produces="application/json"
)
public @ResponseBody ModelMap uomMatrixSaveOrEdit(
    ModelMap model,
    @RequestParam("parentId") String parentId
){
    model.addAttribute("attributeValues",parentId);
    return model;
}

这是我的 Java REST 客户端:

public void post(){
    MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
    params.add("parentId", "parentId");
    String result = rest.postForObject( url, params, String.class) ;
    System.out.println(result);
}

这对我有用;我从服务器端得到一个 JSON 字符串。

我的问题是:我如何指定 Accept: 标头(例如 application/json,application/xml, ... )和请求方法(例如 GET,POST, ... )当我使用休息模板?

【问题讨论】:

    标签: spring rest resttemplate


    【解决方案1】:

    我建议使用接受HttpEntityexchange 方法之一,您也可以为其设置HttpHeaders。 (您也可以指定要使用的 HTTP 方法。)

    例如,

    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
    
    HttpEntity<String> entity = new HttpEntity<>("body", headers);
    
    restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
    

    我更喜欢这个解决方案,因为它是强类型的,即。 exchange 需要 HttpEntity

    但是,您也可以将 HttpEntity 作为 request 参数传递给 postForObject

    HttpEntity<String> entity = new HttpEntity<>("body", headers);
    restTemplate.postForObject(url, entity, String.class); 
    

    RestTemplate#postForObject Javadoc 中提到了这一点。

    request 参数可以是HttpEntity,以便添加额外的 请求的 HTTP 标头

    【讨论】:

      【解决方案2】:

      您可以在 RestTemplate 中设置一个拦截器“ClientHttpRequestInterceptor”,以避免每次发送请求时都设置标头。

      public class HeaderRequestInterceptor implements ClientHttpRequestInterceptor {
      
              private final String headerName;
      
              private final String headerValue;
      
              public HeaderRequestInterceptor(String headerName, String headerValue) {
                  this.headerName = headerName;
                  this.headerValue = headerValue;
              }
      
              @Override
              public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
                  request.getHeaders().set(headerName, headerValue);
                  return execution.execute(request, body);
              }
          }
      

      然后

      List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
      interceptors.add(new HeaderRequestInterceptor("Accept", MediaType.APPLICATION_JSON_VALUE));
      
      RestTemplate restTemplate = new RestTemplate();
      restTemplate.setInterceptors(interceptors);
      

      【讨论】:

      • Spring Boot 1.3 有一个 HttpHeaderInterceptor,所以我们不需要创建自己的 ClientHttpRequestInterceptor 实现。
      • 由于某种原因,HttpHeaderInterceptor 仅在 spring-boot-devtools 中。所以我们还是要自己实现ClientHttpRequestInterceptor。我认为应该把它移到 spring-web 中。
      • 将默认标头添加到设置为其余模板的 ClientHttpRequestFactory 而不是添加拦截器是否更好?附:您应该在一个单独的问题中添加您的答案,因为这涉及默认标题。不得不寻找一段时间才能到达这里!
      • 如果有两个服务使用我们必须调用的两个 diff id /pass,那么这个 resttemplate 级别的拦截器级别太高了吧?您在请求级别需要这个 - 通常 RestTemplate 是 Spring Boot 配置中的 @Bean
      【解决方案3】:

      如果像我一样,您很难找到一个使用带有基本身份验证的标头和其余模板交换 API 的示例,这就是我最终解决的问题...

      private HttpHeaders createHttpHeaders(String user, String password)
      {
          String notEncoded = user + ":" + password;
          String encodedAuth = Base64.getEncoder().encodeToString(notEncoded.getBytes());
          HttpHeaders headers = new HttpHeaders();
          headers.setContentType(MediaType.APPLICATION_JSON);
          headers.add("Authorization", "Basic " + encodedAuth);
          return headers;
      }
      
      private void doYourThing() 
      {
          String theUrl = "http://blah.blah.com:8080/rest/api/blah";
          RestTemplate restTemplate = new RestTemplate();
          try {
              HttpHeaders headers = createHttpHeaders("fred","1234");
              HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
              ResponseEntity<String> response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, String.class);
              System.out.println("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
          }
          catch (Exception eek) {
              System.out.println("** Exception: "+ eek.getMessage());
          }
      }
      

      【讨论】:

        【解决方案4】:

        使用 RestTemplate 调用 RESTful API

        示例 1:

        RestTemplate restTemplate = new RestTemplate();
        // Add the Jackson message converter
        restTemplate.getMessageConverters()
                        .add(new MappingJackson2HttpMessageConverter());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Basic XXXXXXXXXXXXXXXX=");
        HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
        restTemplate.getInterceptors()
                        .add(new BasicAuthorizationInterceptor(USERID, PWORD));
        String requestJson = getRequetJson(Code, emailAddr, firstName, lastName);
        response = restTemplate.postForObject(URL, requestJson, MYObject.class);
                
        

        示例 2:

        RestTemplate restTemplate = new RestTemplate();
        String requestJson = getRequetJson(code, emil, name, lastName);
        HttpHeaders headers = new HttpHeaders();
        String userPass = USERID + ":" + PWORD;
        String authHeader =
            "Basic " + Base64.getEncoder().encodeToString(userPass.getBytes());
        headers.set(HttpHeaders.AUTHORIZATION, authHeader);
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        HttpEntity<String> request = new HttpEntity<String>(requestJson, headers);
        ResponseEntity<MyObject> responseEntity;
        responseEntity =
            this.restTemplate.exchange(URI, HttpMethod.POST, request, Object.class);
        responseEntity.getBody()
        

        getRequestJson 方法创建一个 JSON 对象:

        private String getRequetJson(String Code, String emailAddr, String name) {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode rootNode = mapper.createObjectNode();
            ((ObjectNode) rootNode).put("code", Code);
            ((ObjectNode) rootNode).put("email", emailAdd);
            ((ObjectNode) rootNode).put("firstName", name);
            String jsonString = null;
            try {
                jsonString = mapper.writerWithDefaultPrettyPrinter()
                                       .writeValueAsString(rootNode);
            }
            catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return jsonString;
        }
        

        【讨论】:

          【解决方案5】:

          不创建HttpHeaders 的短解决方案:

          RequestEntity<Void> request = RequestEntity.post(URI.create(url))
                          .accept(MediaType.APPLICATION_JSON)
                          .contentType(MediaType.APPLICATION_JSON)
                          // any other headers
                          .header("PRIVATE-TOKEN", "token")
                          .build();
          
          ResponseEntity<String> response = restTemplate.exchange(request, String.class);
          return response.getBody();
          

          【讨论】:

          • 最有用,简洁和整体干净的答案。谢谢
          • 我不明白为什么在您的本地环境中添加工作标头需要这样的 PIA,这就像我在网上看到的所有其他方法一样不起作用......跨度>
          【解决方案6】:

          这是一个简单的答案。希望它可以帮助某人。

          import org.springframework.boot.devtools.remote.client.HttpHeaderInterceptor;
          import org.springframework.http.MediaType;
          import org.springframework.http.client.ClientHttpRequestInterceptor;
          import org.springframework.web.client.RestTemplate;
          
          
          public String post(SomeRequest someRequest) {
              // create a list the headers 
              List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
              interceptors.add(new HttpHeaderInterceptor("Accept", MediaType.APPLICATION_JSON_VALUE));
              interceptors.add(new HttpHeaderInterceptor("ContentType", MediaType.APPLICATION_JSON_VALUE));
              interceptors.add(new HttpHeaderInterceptor("username", "user123"));
              interceptors.add(new HttpHeaderInterceptor("customHeader1", "c1"));
              interceptors.add(new HttpHeaderInterceptor("customHeader2", "c2"));
              // initialize RestTemplate
              RestTemplate restTemplate = new RestTemplate();
              // set header interceptors here
              restTemplate.setInterceptors(interceptors);
              // post the request. The response should be JSON string
              String response = restTemplate.postForObject(Url, someRequest, String.class);
              return response;
          }
          

          【讨论】:

          • 您的代码将使用 Spring Devtools 作为生产依赖项(通过导入 org.springframework.boot.devtools.remote.client.HttpHeaderInterceptor)...
          猜你喜欢
          • 2016-01-02
          • 1970-01-01
          • 2010-12-12
          • 1970-01-01
          • 1970-01-01
          • 2018-05-22
          • 1970-01-01
          • 1970-01-01
          • 2015-06-07
          相关资源
          最近更新 更多