Как получить доступ к информации заголовка HTTP в REST-контроллере Spring MVC?


154

Я новичок в веб-программировании в целом, особенно в Java, поэтому я только что узнал, что такое заголовок и тело.

Я пишу RESTful сервисы, используя Spring MVC. Я могу создавать простые сервисы с помощью @RequestMappingсвоих контроллеров. Мне нужна помощь в понимании того, как получить информацию заголовка HTTP из запроса, который приходит к моему методу в моем контроллере службы REST. Я хотел бы разобрать заголовок и получить некоторые атрибуты из него.

Не могли бы вы объяснить, как я могу получить эту информацию?

Ответы:


264

Когда вы аннотируете параметр с @RequestHeaderпомощью параметра, он извлекает информацию заголовка. Так что вы можете просто сделать что-то вроде этого:

@RequestHeader("Accept")

чтобы получить Acceptзаголовок.

Итак из документации :

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

}

В Accept-Encodingи Keep-Aliveзаголовке значение приведено в encodingи keepAliveпараметрах соответственно.

И не стоит беспокоиться. Мы все новички с чем-то.


Спасибо. В некоторых примерах кода в компании, в которой я работаю, я вижу HttpServletRequest в качестве параметра и в нем есть метод getHeader. Какой подход предпочтительнее?
Horse Voice

1
Предпочитаю абстракции низкоуровневым деталям API. Я бы предпочел, чтобы Spring MVC абстрагировалась от деталей ServletAPI. Я могу использовать аннотации, чтобы извлечь из запроса то, что мне нужно.
Видя

6
Следует отметить, что вы получите 400 ошибочных запросов в качестве ответа в случае, если запрос не будет содержать такой заголовок. Более гибкий способ - прямой доступ к заголовкам запросов, как описано в: stackoverflow.com/a/28209710/1828296
lospejos

Я думаю, это зависит от того, что вы хотите сделать, но ответ 400 - это поведение, которое я почти всегда хотел бы в этом случае.
Видья

@lospejos, которого можно избежать с помощью такого requiredфлага @RequestHeader(name = "Keep-Alive", required = false) long keepAlive, установит для keepAlive значение null, если не указано иное. Также есть defaultValueполе для аннотации docs.spring.io/spring-framework/docs/5.0.7.RELEASE/javadoc-api/…
Никколо,

88

Вы можете использовать @RequestHeaderаннотацию с HttpHeadersпараметром метода, чтобы получить доступ ко всем заголовкам запроса:

@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);
    // ...
}

Как насчет тела HTTP-запроса? Как мне получить доступ к особенностям заголовка? Не могли бы вы объяснить мне, является ли HttpHeaders картой, к которой мне нужен ключ для доступа?
Horse Voice

HttpHeaders имеет геттеры для получения спецификаций заголовков. Вы можете изучить эту ссылку, чтобы получить подробную информацию: docs.spring.io/spring/docs/3.1.x/javadoc-api/org/…
Debojit Saikia

отредактировал мой ответ, чтобы показать, как вы можете получить доступ к телу запроса.
Debojit Saikia

1
Зачем нужен потоковый источник? Это кажется слишком сложным. Должен быть более простой способ, чем использовать потоки и т. Д.
Horse Voice

Здесь StringReaderиспользуется для чтения входящего потока символов. StreamSourceработает как держатель источника преобразования в виде потока разметки XML.
Debojit Saikia

14

Мое решение в параметрах заголовка с примером является user = "test" :

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

System.out.println(headers.get("user"));
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.