Чтение заголовков HTTP в контроллере Spring REST

Я пытаюсь прочитать заголовки HTTP в Spring на основе REST API. Я следовал этой. Но я получаю эту ошибку:

для класса java не найдено средство чтения тела сообщения.ленг.Строке
ContentType: application / octet-stream

Я новичок в Java и Spring, поэтому не могу понять это.

вот как выглядит мой звонок:

@WebService(serviceName = "common")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public interface CommonApiService {

    @GET
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/data")
    public ResponseEntity<Data> getData(@RequestHeader(value="User-Agent") String userAgent, @DefaultValue ("") @QueryParam("ID") String id);
}

Я пробовал @Context: HTTPHeader составляет null в этом случай.

как получить значения из заголовков HTTP?

2 ответов


ошибка, которую вы получаете, похоже, не связана с requestheader, с.

и Вы, кажется, путаете службы весеннего отдыха с JAX-RS ваша подпись метода должна быть что-то вроде:

@RequestMapping(produces = "application/json", method = RequestMethod.GET, value = "data")
@ResponseBody
public ResponseEntity<Data> getData(@RequestHeader(value="User-Agent") String userAgent, @RequestParam(value = "ID", defaultValue = "") String id) {
    // your code goes here
}

и ваш класс REST должен иметь аннотации, такие как:

@Controller
@RequestMapping("/rest/")


Что касается фактического вопроса, другой способ получить заголовки HTTP-это вставить HttpServletRequest на ваш метод, а затем получить желаемый заголовок оттуда.

пример:

@RequestMapping(produces = "application/json", method = RequestMethod.GET, value = "data")
@ResponseBody
public ResponseEntity<Data> getData(HttpServletRequest request, @RequestParam(value = "ID", defaultValue = "") String id) {
    String userAgent = request.getHeader("user-agent");
}

не беспокойтесь о введении HttpServletRequest потому что весна делает эту магию для вас;)


я собираюсь дать вам пример того, как я читаю заголовки REST для своих контроллеров. Мои контроллеры принимают application/json только как тип запроса, если у меня есть данные, которые необходимо прочитать. Я подозреваю, что ваша проблема в том, что у вас есть приложение/октет-поток, который Spring не знает, как обращаться.

Обычно мои контроллеры выглядят так:

@Controller
public class FooController {
    @Autowired
    private DataService dataService;

    @RequestMapping(value="/foo/", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<Data> getData(@RequestHeader String dataId){
        return ResponseEntity.newInstance(dataService.getData(dataId);
    }

теперь есть много кода, делающего вещи в фоновом режиме здесь, поэтому я сломаю его для вы.

ResponseEntity-это пользовательский объект, который возвращает каждый контроллер. Он содержит статическую фабрику, позволяющую создавать новые экземпляры. Моя служба данных-это стандартный класс обслуживания.

магия происходит за кулисами, потому что вы работаете с JSON, вам нужно сказать Spring использовать Jackson для отображения объектов HttpRequest, чтобы он знал, с чем вы имеете дело.

для этого укажите это в ваш <mvc:annotation-driven> блок вашего config

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper" ref="objectMapper" />
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

ObjectMapper это просто расширение com.fasterxml.jackson.databind.ObjectMapper и это то, что Джексон использует, чтобы фактически отобразить ваш запрос от JSON в объект.

я подозреваю, что вы получаете свое исключение, потому что вы не указали сопоставитель, который может читать октет-поток в объект или что-то, что Spring может обрабатывать. Если вы пытаетесь сделать загрузку файла, это что-то совсем другое.

поэтому мой запрос, который отправляется на мой контроллер, выглядит как-то как это просто имеет дополнительный заголовок под названием dataId.

если вы хотите изменить это на параметр запроса и использовать @RequestParam String dataId читать идентификатор запроса, ваш запрос будет выглядеть примерно так:

contactId : {"fooId"} 

этот параметр запроса может быть настолько сложным, насколько вам нравится. Вы можете сериализовать весь объект в JSON, отправить его в качестве параметра запроса, и Spring сериализует его (используя Jackson) обратно в объект Java, готовый для использования.

Пример В Контроллер:

@RequestMapping(value = "/penguin Details/", method = RequestMethod.GET)
@ResponseBody
public DataProcessingResponseDTO<Pengin> getPenguinDetailsFromList(
        @RequestParam DataProcessingRequestDTO jsonPenguinRequestDTO)

Запрос Отправлен:

jsonPengiunRequestDTO: {
    "draw": 1,
    "columns": [
        {
            "data": {
                "_": "toAddress",
                "header": "toAddress"
            },
            "name": "toAddress",
            "searchable": true,
            "orderable": true,
            "search": {
                "value": "",
                "regex": false
            }
        },
        {
            "data": {
                "_": "fromAddress",
                "header": "fromAddress"
            },
            "name": "fromAddress",
            "searchable": true,
            "orderable": true,
            "search": {
                "value": "",
                "regex": false
            }
        },
        {
            "data": {
                "_": "customerCampaignId",
                "header": "customerCampaignId"
            },
            "name": "customerCampaignId",
            "searchable": true,
            "orderable": true,
            "search": {
                "value": "",
                "regex": false
            }
        },
        {
            "data": {
                "_": "penguinId",
                "header": "penguinId"
            },
            "name": "penguinId",
            "searchable": false,
            "orderable": true,
            "search": {
                "value": "",
                "regex": false
            }
        },
        {
            "data": {
                "_": "validpenguin",
                "header": "validpenguin"
            },
            "name": "validpenguin",
            "searchable": true,
            "orderable": true,
            "search": {
                "value": "",
                "regex": false
            }
        },
        {
            "data": {
                "_": "",
                "header": ""
            },
            "name": "",
            "searchable": false,
            "orderable": false,
            "search": {
                "value": "",
                "regex": false
            }
        }
    ],
    "order": [
        {
            "column": 0,
            "dir": "asc"
        }
    ],
    "start": 0,
    "length": 10,
    "search": {
        "value": "",
        "regex": false
    },
    "objectId": "30"
}

который автоматически сериализуется обратно в объект DataProcessingRequestDTO перед тем, как быть переданным контроллеру, готовому для меня использовать.

как вы можете видеть, это довольно мощный позволяет сериализовать данные из JSON в объект без необходимости писать одну строку кода. Вы можете сделать это для @RequestParam и @RequestBody что позволяет вам получить доступ к JSON внутри ваших параметров или запроса тело соответственно.

теперь, когда у вас есть конкретный пример, чтобы уйти, у вас не должно быть никаких проблем, как только вы измените тип запроса на application/json.