在 JAX-RS REST 服务中使用多部分 POST 数据
Consuming muiltipart POST data in JAX-RS REST Service
我有一个 jax-rs REST 服务,使用 JEE 7(部署在 glassfish 中),它有一个方法来处理资源上的 HTTP POST:
@POST
@Path(value="{dId}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response sendStatus(@Context HttpServletRequest request)
我尝试将多部分数据提取为:
Collection<Part> parts = request.getParts();
if(parts==null || parts.isEmpty()){
lg.warn("Empty/non-existent parts in request body!");
return sendBadRequestError(sp);
}
然后我尝试使用 RestClient(来自 wiztools.org)模拟客户端多部分 POST 请求,至少有 2 个不同内容类型的部分(边界定界符由 RESTClient 工具自动设置).
我在 wireshark 中验证它是从 RESTClient 发送的正确请求(没有格式错误的数据包等)。
但是,所有请求似乎都命中了请求正文消息中包含Empty/non-existent部分的块,表明在请求中找不到任何部分。
我在发布之前在 Whosebug 中搜索了很多次,所有 examples/solutions 都与上传 file/image 的用例有关,而我正在处理的不是这种情况。
我的休息服务只消耗一个多部分请求,它可以包含一个部分 JSON 数据,另一部分带有简单字符串或其他 JSON 数据。
是否缺少某些内容 - 请帮忙?是否有其他技术来解析命中 REST 服务的多部分数据?
请指教
谢谢。
J
感谢@peeskillet 的指点,我使用 Jersey 多部分 API 来获取多部分实体的句柄。
为了帮助其他遇到同样问题的人,我列出了完整的解决方案:
- 在容器中为您的应用启用 "MultiPart" 功能。这对于所需 readers/writers 的可用性是必要的。 Jersey 2 injection source for multipart formdata
中清楚地阐述了如何执行此操作
然后资源方法定义为
@POST
@Path(value="{dId}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response sendStatus(FormDataMultiPart multipart){
....
...
Map<String, List<FormDataBodyPart>> parts = multipart.getFields();
if(parts==null || parts.isEmpty()){
lg.warn("Empty/non-existent parts in request body!");
return sendBadRequestError(sp);
}
for(List<FormDataBodyPart> p: parts.values()){
FormDataBodyPart bp = p.get(0);
lg.info("\t body part name {}",bp.getName());
lg.info("\t body part value {}",bp.getValue());
....//do your real stuff here
}
}
宾果游戏成功了!
另请注意:使用 RESTClient GUI 工具时,请确保您没有明确设置 Content-Type 和 Boundary,因为该工具会自动设置。
希望这个帮助ps 某人。
ps:如何为 peeskillet 的回答投票?
我有一个 jax-rs REST 服务,使用 JEE 7(部署在 glassfish 中),它有一个方法来处理资源上的 HTTP POST:
@POST
@Path(value="{dId}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response sendStatus(@Context HttpServletRequest request)
我尝试将多部分数据提取为:
Collection<Part> parts = request.getParts();
if(parts==null || parts.isEmpty()){
lg.warn("Empty/non-existent parts in request body!");
return sendBadRequestError(sp);
}
然后我尝试使用 RestClient(来自 wiztools.org)模拟客户端多部分 POST 请求,至少有 2 个不同内容类型的部分(边界定界符由 RESTClient 工具自动设置).
我在 wireshark 中验证它是从 RESTClient 发送的正确请求(没有格式错误的数据包等)。
但是,所有请求似乎都命中了请求正文消息中包含Empty/non-existent部分的块,表明在请求中找不到任何部分。
我在发布之前在 Whosebug 中搜索了很多次,所有 examples/solutions 都与上传 file/image 的用例有关,而我正在处理的不是这种情况。
我的休息服务只消耗一个多部分请求,它可以包含一个部分 JSON 数据,另一部分带有简单字符串或其他 JSON 数据。
是否缺少某些内容 - 请帮忙?是否有其他技术来解析命中 REST 服务的多部分数据?
请指教
谢谢。 J
感谢@peeskillet 的指点,我使用 Jersey 多部分 API 来获取多部分实体的句柄。
为了帮助其他遇到同样问题的人,我列出了完整的解决方案:
- 在容器中为您的应用启用 "MultiPart" 功能。这对于所需 readers/writers 的可用性是必要的。 Jersey 2 injection source for multipart formdata 中清楚地阐述了如何执行此操作
然后资源方法定义为
@POST @Path(value="{dId}") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) public Response sendStatus(FormDataMultiPart multipart){ .... ... Map<String, List<FormDataBodyPart>> parts = multipart.getFields(); if(parts==null || parts.isEmpty()){ lg.warn("Empty/non-existent parts in request body!"); return sendBadRequestError(sp); } for(List<FormDataBodyPart> p: parts.values()){ FormDataBodyPart bp = p.get(0); lg.info("\t body part name {}",bp.getName()); lg.info("\t body part value {}",bp.getValue()); ....//do your real stuff here } }
宾果游戏成功了!
另请注意:使用 RESTClient GUI 工具时,请确保您没有明确设置 Content-Type 和 Boundary,因为该工具会自动设置。
希望这个帮助ps 某人。
ps:如何为 peeskillet 的回答投票?