requestmapping requestheader headers ejemplo java spring rest spring-restcontroller spring-rest

java - requestheader - spring boot get request headers



Leyendo encabezados HTTP en un controlador REST Spring (2)

Estoy intentando leer los encabezados HTTP en la API REST basada en Spring. Seguí this . Pero estoy recibiendo este error:

No se ha encontrado ningún lector de cuerpo de mensaje para la clase java.lang.String,
ContentType: application / octet-stream

Soy nuevo en Java y Spring, así que no puedo resolver esto.

Así es como se ve mi llamada:

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

He intentado @Context : HTTPHeader es null en este caso.

¿Cómo obtener valores de los encabezados HTTP?


El error que recibe no parece estar relacionado con el RequestHeader .

Y parece que está confundiendo los servicios de REST de Spring con JAX-RS , la firma de su método debería ser algo como:

@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 }

Y tu clase REST debería tener anotaciones como:

@Controller @RequestMapping("/rest/")


Con respecto a la pregunta real, otra forma de obtener encabezados HTTP es insertar HttpServletRequest en su método y luego obtener el encabezado deseado desde allí.

Ejemplo:

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

No te preocupes por la inyección de HttpServletRequest porque Spring hace esa magia por ti;)


Les voy a dar un ejemplo de cómo leo los encabezados REST para mis controladores. Mis controladores solo aceptan application / json como tipo de solicitud si tengo datos que deben leerse. Sospecho que su problema es que tiene una aplicación / flujo de octetos que Spring no sabe cómo manejar.

Normalmente mis controladores se ven así:

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

Ahora hay un montón de código haciendo cosas en el fondo aquí, así que lo desglosaré por ti.

ResponseEntity es un objeto personalizado que devuelve cada controlador. Contiene una fábrica estática que permite la creación de nuevas instancias. Mi servicio de datos es una clase de servicio estándar.

La magia ocurre detrás de escena, porque está trabajando con JSON, debe decirle a Spring que use a Jackson para mapear objetos HttpRequest para que sepa de qué se trata.

Para hacer esto, especifique esto dentro de su bloque <mvc:annotation-driven> de su configuración

<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 es simplemente una extensión de com.fasterxml.jackson.databind.ObjectMapper y es lo que Jackson usa para asignar realmente su solicitud de JSON a un objeto.

Sospecho que está obteniendo su excepción porque no ha especificado un asignador que pueda leer un Octet-Stream en un objeto, o algo que Spring pueda manejar. Si está tratando de hacer una carga de archivo, eso es algo completamente distinto.

Por lo tanto, mi solicitud que se envía a mi controlador se ve algo como esto simplemente tiene un encabezado adicional llamado dataId .

Si quisiera cambiar eso a un parámetro de solicitud y usar @RequestParam String dataId para leer el ID de la solicitud, su solicitud sería similar a esto:

contactId : {"fooId"}

Este parámetro de solicitud puede ser tan complejo como quieras. Puede serializar un objeto completo en JSON, enviarlo como un parámetro de solicitud y Spring lo serializará (utilizando Jackson) nuevamente en un objeto Java listo para que lo use.

Ejemplo en el controlador:

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

Solicitud enviada:

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" }

que se vuelve a serializar automáticamente en un objeto DataProcessingRequestDTO antes de entregarlo al controlador listo para que lo use.

Como puede ver, esto es bastante poderoso, ya que le permite serializar sus datos de JSON a un objeto sin tener que escribir una sola línea de código. Puede hacer esto para @RequestParam y @RequestBody que le permite acceder a JSON dentro de sus parámetros o cuerpo de solicitud respectivamente.

Ahora que tiene un ejemplo concreto para salir, no debería tener ningún problema una vez que cambie su tipo de application/json a application/json .