วิธีการตั้งค่าส่วนหัว“ ยอมรับ:” ในคำขอของ Spring RestTemplate


194

ฉันต้องการที่จะตั้งค่าของในการร้องขอผมทำใช้ของฤดูใบไม้ผลิAccept:RestTemplate

นี่คือรหัสการจัดการคำขอสปริงของฉัน

@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, ... ) เมื่อฉันใช้ RestTemplate?

คำตอบ:


355

ฉันขอแนะนำให้ใช้หนึ่งในexchangeวิธีการที่ยอมรับHttpEntityซึ่งคุณสามารถตั้งค่า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);

ฉันชอบโซลูชันนี้เพราะมันพิมพ์อย่างหนักเช่น คาดว่าจะมีexchangeHttpEntity

อย่างไรก็ตามคุณสามารถส่งต่อให้HttpEntityเป็นrequestอาร์กิวเมนต์postForObjectได้

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

นี้ถูกกล่าวถึงในJavadocRestTemplate#postForObject

requestพารามิเตอร์สามารถเป็นHttpEntityเพื่อเพิ่มส่วนหัว HTTP เพิ่มเติมเพื่อร้องขอ


132

คุณสามารถตั้งค่าตัวดัก "ClientHttpRequestInterceptor" ใน RestTemplate ของคุณเพื่อหลีกเลี่ยงการตั้งค่าส่วนหัวทุกครั้งที่คุณส่งคำขอ

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 ของเราเอง
whistling_marmot

2
ด้วยเหตุผลบางอย่าง HttpHeaderInterceptor มีเฉพาะใน spring-boot-devtools ดังนั้นเรายังต้องใช้ ClientHttpRequestInterceptor ด้วยตนเอง ฉันคิดว่าควรย้ายเข้าเว็บสปริง
whistling_marmot

2
มันจะดีกว่าที่จะเพิ่มส่วนหัวเริ่มต้นเพื่อ ClientHttpRequestFactory ตั้งค่าเป็นแม่แบบที่เหลือแทนการเพิ่ม interceptors? ป.ล. คุณควรเพิ่มคำตอบในคำถามแยกต่างหากเนื่องจากข้อตกลงนี้มีส่วนหัวเริ่มต้น ต้องรอซักพักที่นี่!
sbsatter

หากมีสองบริการที่ใช้สองรหัส / รหัสผ่านที่เราต้องเรียกใช้งาน interceptor ที่ระดับ resttemplate นั้นอยู่ในระดับสูงเกินไปใช่ไหม? คุณต้องการสิ่งนี้ในระดับคำขอ - โดยทั่วไป RestTemplate เป็น @Bean ในการกำหนดค่าบู๊ตสปริง
Kalpesh Soni

21

หากเช่นฉันคุณพยายามหาตัวอย่างที่ใช้ส่วนหัวที่มีการรับรองความถูกต้องเบื้องต้นและส่วนที่เหลือแลกเปลี่ยนเทมเพลต 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());
    }
}

11

การเรียก RESTful API โดยใช้ RestTemplate

ตัวอย่างที่ 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;
}

4

นี่คือคำตอบง่ายๆ หวังว่าจะช่วยใครซักคน

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
รหัสของคุณจะใช้ Spring Devtools เป็นการผลิตอ้างอิง (โดยการนำเข้า org.springframework.boot.devtools.remote.client.HttpHeaderInterceptor) ...
snorbi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.