Bagaimana cara mendapatkan akses ke informasi header HTTP di pengendali Spring MVC REST?

154

Saya baru mengenal pemrograman web secara umum, terutama di Jawa, jadi saya baru tahu apa itu header dan body.

Saya sedang menulis layanan yang tenang menggunakan Spring MVC. Saya dapat membuat layanan sederhana dengan @RequestMappingdi controller saya. Saya perlu bantuan untuk memahami cara mendapatkan informasi header HTTP dari permintaan yang datang ke metode saya di pengontrol layanan REST saya. Saya ingin mengurai header dan mendapatkan beberapa atribut darinya.

Bisakah Anda menjelaskan bagaimana saya mendapatkan informasi itu?

Suara Kuda
sumber

Jawaban:

264

Ketika Anda membubuhi keterangan parameter dengan @RequestHeader, parameter mengambil informasi header. Jadi Anda bisa melakukan sesuatu seperti ini:

@RequestHeader("Accept")

untuk mendapatkan Accepttajuk.

Jadi dari dokumentasi :

@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding,
                              @RequestHeader("Keep-Alive") long keepAlive)  {

}

Nilai header Accept-Encodingdan Keep-Alivediberikan masing-masing dalam encodingdan keepAliveparameter.

Dan jangan khawatir. Kita semua noobs dengan sesuatu.

Vidya
sumber
Terima kasih. Dalam beberapa contoh kode di perusahaan tempat saya bekerja, saya melihat HttpServletRequest sebagai parameter dan ada metode getHeader di atasnya. Pendekatan mana yang lebih disukai?
Suara Kuda
1
Memilih abstraksi ke detail tingkat rendah dari API. Saya lebih suka memiliki Spring MVC abstrak jauh rincian ServletAPI. Saya dapat menggunakan anotasi untuk menarik apa yang saya butuhkan dari permintaan.
Vidya
6
Sebaiknya sebutkan, Anda akan mendapatkan 400 kesalahan permintaan buruk sebagai tanggapan jika permintaan tidak akan mengandung tajuk tersebut. Cara yang lebih fleksibel adalah akses langsung ke header permintaan seperti yang dijelaskan dalam: stackoverflow.com/a/28209710/1828296
lospejos
Saya kira itu tergantung pada apa yang ingin Anda lakukan, tetapi respons 400 adalah perilaku yang hampir selalu saya inginkan dalam kasus itu.
Vidya
@ lospejos yang bisa dihindari dengan menggunakan requiredflag seperti @RequestHeader(name = "Keep-Alive", required = false) long keepAliveitu akan membuat keepAlive menjadi null jika tidak disediakan. Ada juga defaultValuelapangan untuk penjelasan docs.spring.io/spring-framework/docs/5.0.7.RELEASE/javadoc-api/...
Niccolò
88

Anda dapat menggunakan @RequestHeaderanotasi dengan HttpHeadersparameter metode untuk mendapatkan akses ke semua header permintaan:

@RequestMapping(value = "/restURL")
public String serveRest(@RequestBody String body, @RequestHeader HttpHeaders headers) {
    // Use headers to get the information about all the request headers
    long contentLength = headers.getContentLength();
    // ...
    StreamSource source = new StreamSource(new StringReader(body));
    YourObject obj = (YourObject) jaxb2Mashaller.unmarshal(source);
    // ...
}
Debojit Saikia
sumber
Bagaimana dengan isi permintaan http? Bagaimana cara mengakses spesifik header? dapatkah Anda menjelaskan kepada saya jika HttpHeaders adalah peta yang saya perlukan kunci untuk mengakses?
Suara Kuda
HttpHeaders memiliki getter untuk mendapatkan spesifik header. Anda dapat menjelajahi tautan ini untuk mendapatkan perinciannya: docs.spring.io/spring/docs/3.1.x/javadoc-api/org/…
Debojit Saikia
edit jawaban saya untuk menunjukkan bagaimana Anda bisa mendapatkan akses ke badan permintaan.
Debojit Saikia
1
Mengapa streamsource diperlukan? Sepertinya terlalu rumit. Pasti ada cara yang lebih mudah daripada menggunakan stream dll.
Horse Voice
Di sini StringReaderdigunakan untuk membaca aliran karakter yang masuk. StreamSourceberfungsi sebagai pemegang untuk sumber transformasi dalam bentuk aliran markup XML.
Debojit Saikia
14

Solusi saya dalam parameter Header dengan contohnya adalah user = "test" adalah:

@RequestMapping(value = "/restURL")
  public String serveRest(@RequestBody String body, @RequestHeader HttpHeaders headers){

System.out.println(headers.get("user"));
}
Armando Cordova
sumber