Làm cách nào để đặt tiêu đề Chấp nhận: Một tiêu đề trên ứng dụng Spring RestTemplate?


193

Tôi muốn đặt giá trị của Accept:yêu cầu tôi đang thực hiện bằng Spring's RestTemplate.

Đây là mã xử lý yêu cầu mùa xuân của tôi

@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;
}

và đây là máy khách Java REST của tôi:

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

Điều này làm việc cho tôi; Tôi nhận được một chuỗi JSON từ phía máy chủ.

Câu hỏi của tôi là: làm thế nào tôi có thể xác định Accept:tiêu đề (ví dụ như application/json, application/xml, ...) và phương thức yêu cầu (ví dụ GET, POST...) khi tôi sử dụng RestTemplate?

Câu trả lời:


353

Tôi đề nghị sử dụng một trong những exchangephương pháp chấp nhận một phương thức HttpEntitymà bạn cũng có thể đặt HttpHeaders. (Bạn cũng có thể chỉ định phương thức HTTP bạn muốn sử dụng.)

Ví dụ,

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

Tôi thích giải pháp này bởi vì nó được gõ mạnh, tức là. exchangemong đợi một HttpEntity.

Tuy nhiên, bạn cũng có thể chuyển nó HttpEntitylàm requestđối số postForObject.

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

Điều này được đề cập trong RestTemplate#postForObjectJavadoc .

Các requesttham số có thể là một HttpEntitytrật tự trong để thêm tiêu đề HTTP bổ sung cho các yêu cầu .


130

Bạn có thể đặt một bộ chặn "ClientHttpRequestInterceptor" trong RestTemplate của mình để tránh đặt tiêu đề mỗi khi bạn gửi yêu cầu.

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

Sau đó

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 có một httpHeaderInterceptor, vì vậy chúng ta không cần phải tạo triển khai ClientHttpRequestInterceptor của riêng mình.
huýt sáo_marmot

2
Vì một số lý do, httpHeaderInterceptor chỉ có trong spring-boot-devtools. Vì vậy, chúng tôi vẫn phải tự thực hiện ClientHttpRequestInterceptor. Tôi nghĩ rằng nó nên được chuyển vào mùa xuân web.
huýt sáo_marmot

2
Có tốt hơn không khi thêm các tiêu đề mặc định vào ClientHttpRequestFactory được đặt thành mẫu còn lại thay vì thêm các phần chặn? PS bạn nên thêm câu trả lời của bạn trong một câu hỏi riêng vì điều này liên quan đến các tiêu đề mặc định. Phải tìm một lúc để đến đây!
sbsatter

Nếu có hai dịch vụ sử dụng hai diff id / pass mà chúng ta phải gọi, thì thiết bị chặn này ở cấp độ resttemplate là quá cao phải không? bạn cần điều này ở cấp yêu cầu - nói chung RestTemplate là một @Bean trong cấu hình khởi động mùa xuân
Kalpesh Soni

21

Nếu, giống như tôi, bạn đấu tranh để tìm một ví dụ sử dụng các tiêu đề với xác thực cơ bản và API trao đổi mẫu còn lại, đây là điều cuối cùng tôi đã tìm ra ...

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

11

Gọi API RESTful bằng RestTemplate

Ví dụ 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);
        

Ví dụ 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()

Các getRequestJsonphương pháp tạo ra một đối tượng 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;
}

4

Đây là một câu trả lời đơn giản. Hy vọng nó sẽ giúp được ai đó.

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

10
Mã của bạn sẽ sử dụng Spring Devtools làm phụ thuộc sản xuất (bằng cách nhập org.springframework.boot.devtools.remote.client.HttpHeaderInterceptor) ...
snorbi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.