Чтение заголовков 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
.