Bagaimana cara mengatur tajuk “Terima:” pada permintaan Spring RestTemplate?

193

Saya ingin menetapkan nilai Accept:dalam permintaan yang saya buat menggunakan Spring'sRestTemplate .

Ini kode penanganan permintaan Musim Semi saya

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

dan inilah klien Java REST saya:

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

Ini bekerja untuk saya; Saya mendapatkan string JSON dari sisi server.

Pertanyaan saya adalah: bagaimana saya bisa menentukan Accept:header (mis application/json. application/xml, ...) dan metode permintaan (mis GET. POST, ...) ketika saya menggunakan RestTemplate?

edaklij
sumber

Jawaban:

353

Saya sarankan menggunakan salah satu exchangemetode yang menerima HttpEntityyang Anda juga dapat mengatur HttpHeaders. (Anda juga dapat menentukan metode HTTP yang ingin Anda gunakan.)

Sebagai contoh,

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

Saya lebih suka solusi ini karena sangat diketik, yaitu. exchangemengharapkan sebuah HttpEntity.

Namun, Anda juga dapat menyampaikannya HttpEntitysebagai requestargumen postForObject.

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

Ini disebutkan dalam RestTemplate#postForObjectJavadoc .

The requestparameter dapat menjadi HttpEntityurutan ke menambahkan header HTTP tambahan untuk permintaan .

Sotirios Delimanolis
sumber
130

Anda dapat mengatur interseptor "ClientHttpRequestInterceptor" di RestTemplate Anda untuk menghindari pengaturan header setiap kali Anda mengirim permintaan.

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

Kemudian

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

RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(interceptors);
Ammar
sumber
Spring Boot 1.3 memiliki HttpHeaderInterceptor, jadi kami tidak perlu membuat implementasi ClientHttpRequestInterceptor kami sendiri.
whistling_marmot
2
Untuk beberapa alasan, HttpHeaderInterceptor hanya ada di spring-boot-devtools. Jadi kita masih harus mengimplementasikan ClientHttpRequestInterceptor sendiri. Saya pikir itu harus dipindahkan ke web musim semi.
whistling_marmot
2
Apakah lebih baik menambahkan header default ke ClientHttpRequestFactory diatur ke template sisanya daripada menambahkan interseptor? PS Anda harus menambahkan jawaban Anda dalam pertanyaan terpisah karena ini berkaitan dengan header default. Harus mencari sebentar untuk sampai ke sini!
sbsatter
jika ada dua layanan yang menggunakan dua diff id / pass yang harus kita panggil, pencegat ini pada tingkat resttemplate terlalu tinggi bukan? Anda memerlukan ini di tingkat permintaan - umumnya RestTemplate adalah @Bean dalam konfigurasi booting musim semi
Kalpesh Soni
21

Jika, seperti saya, Anda kesulitan menemukan contoh yang menggunakan tajuk dengan otentikasi dasar dan API pertukaran templat sisa, inilah yang akhirnya saya lakukan ...

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

Memanggil RESTful API menggunakan RestTemplate

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

Contoh 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()

The getRequestJsonMetode menciptakan Object 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;
}
vaquar khan
sumber
4

Ini jawaban sederhana. Semoga ini bisa membantu seseorang.

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;
}
Tunde Michael
sumber
10
Kode Anda akan menggunakan Spring Devtools sebagai ketergantungan produksi (dengan mengimpor org.springframework.boot.devtools.remote.client.HttpHeaderInterceptor) ...
snorbi