如何使用Jersey计算多部分请求体的MD5哈希值

时间:2012-12-26 11:30:16

标签: java jersey md5 multipartform-data

我正在使用Jersey,我需要计算多部分帖子请求正文的MD5哈希值。我当前的资源方法签名如下所示:

@POST
@Consumes("multipart/form-data")
@Produces("application/json")
public String post(
        @FormDataParam("name") String name,
        @FormDataParam("description") String description,
        @FormDataParam("iconfile") FormDataBodyPart part,
        @Context HttpServletRequest hsr) {
    // ...
} 

我没有找到获取原始请求体的方法,我需要计算MD5哈希值。调用我的资源方法后,HttpServletRequesthsr.getInputStream())的输入流已被消耗,我无法再次读取它。

我尝试将方法签名更改为以下内容:

@POST
@Consumes("multipart/form-data")
@Produces("application/json")
public String test(byte[] bytes) {
    // ...
}

这样我得到请求体的原始字节,我可以成功计算MD5哈希,但我不知道如何从那里处理多部分请求(拆分部分,获取每个部分等)。我是否必须自己处理原始请求?或者我可以让泽西做肮脏的工作并为我提取FormDataParam并让我以某种方式计算MD5哈希?

谢谢,

1 个答案:

答案 0 :(得分:0)

这就是我最终做的事情:

我创建了一个容器请求过滤器,它使用实体输入流,计算MD5校验和并再次设置实体输入流,以便Jersey可以使用它来处理多部分请求并为我提取FormDataParam s

我还在我的过滤器和资源方法中注入了HttpServletRequest,以便在两者之间传递数据。

这是过滤器类:

public class MD5CheckFilter implements ContainerRequestFilter {

    @Context HttpServletRequest hsr;

    public ContainerRequest filter(ContainerRequest request) {

        byte[] bytes = request.getEntity(byte[].class); // this consumes the entity input stream
        String contentMD5 = calculateMD5(bytes);
        hsr.setAttribute("contentMD5", contentMD5);

        // set the entity input stream so it can be consumed again
        request.setEntityInputStream(new ByteArrayInputStream(bytes));

        return request;
    }

}

这是我web.xml部分servlet内的相关部分:

<init-param>
    <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
    <param-value>path.to.MD5CheckFilter</param-value>
</init-param>

这样我就不需要更改原始方法签名了:

@POST
@Consumes("multipart/form-data")
@Produces("application/json")
public String post(
        @FormDataParam("name") String name,
        @FormDataParam("description") String description,
        @FormDataParam("iconfile") FormDataBodyPart part,
        @Context HttpServletRequest hsr) {
    // ...
}