在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
,就不应该有任何问题。