在Spring REST控制器中读取HTTP标头

我试图在基于Spring的REST API中读取HTTP头。 我跟着这个 。 但是我收到了这个错误:

没有为类java.lang.String找到消息正文阅读器,
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 getData(@RequestHeader(value="User-Agent") String userAgent, @DefaultValue ("") @QueryParam("ID") String id); } 

我试过@Context :在这种情况下,HTTPHeader为null

如何从HTTP标头中获取值?

您获得的错误似乎与RequestHeader无关。

而且你似乎把Spring REST服务与JAX-RS混淆了,你的方法签名应该是这样的:

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

不要担心HttpServletRequest的注入,因为Spring为你带来了魔力;)

我将举例说明如何读取控制器的REST标头。 如果我有需要读取的数据,我的控制器只接受application / json作为请求类型。 我怀疑你的问题是你有一个应用程序/八位字节流,Spring不知道如何处理。

通常我的控制器看起来像这样:

 @Controller public class FooController { @Autowired private DataService dataService; @RequestMapping(value="/foo/", method = RequestMethod.GET) @ResponseBody public ResponseEntity getData(@RequestHeader String dataId){ return ResponseEntity.newInstance(dataService.getData(dataId); } 

现在有很多代码在后台执行这些操作,所以我会为你分解它。

ResponseEntity是每个控制器返回的自定义对象。 它包含一个允许创建新实例的静态工厂。 我的数据服务是标准服务类。

魔术发生在幕后,因为你正在使用JSON,你需要告诉Spring使用Jackson映射HttpRequest对象,以便它知道你在处理什么。

您可以通过在配置的块中指定它来完成此操作

        

ObjectMapper只是com.fasterxml.jackson.databind.ObjectMapper的扩展,是Jackson用来将您的请求从JSON实际映射到对象的方法。

我怀疑你得到了你的exception,因为你没有指定一个可以将Octet-Stream读入对象的映射器,或者Spring可以处理的东西。 如果您正在尝试进行文件上传,那么完全不同。

所以我的请求发送到我的控制器看起来像这样只是有一个名为dataId的额外标头。

如果您想将其更改为请求参数并使用@RequestParam String dataId来读取请求中的ID,您的请求将类似于以下内容:

 contactId : {"fooId"} 

此请求参数可以像您一样复杂。 您可以将整个对象序列化为JSON,将其作为请求参数发送,然后Spring将其序列化(使用Jackson)返回到Java Object,供您使用。

控制器中的示例:

 @RequestMapping(value = "/penguin Details/", method = RequestMethod.GET) @ResponseBody public DataProcessingResponseDTO 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 ,就不应该有任何问题。