jax-rs流式输出和读取服务器上的数据,为什么这样做有效



我发布了两次关于这个主题的问题(这里和这里,但从来没有得到一个令人满意的答案,我觉得我不能很好地表达这个问题。我已经弄清楚了,但我对它的理解很弱。正是偶然的机会让我找到了这个解决方案。我正在做的是在我的网络服务器生成的一个单独的进程上生成结果。当这些结果生成时,我想使用Jersey将字节流式传输到网络服务r,并最终将其传递回我的客户(稍后)。我最难弄清楚如何使我的数据流从我的流程返回到我的Web服务器。我猜想对我的实体使用StreamingOuput类型会起作用。网上没有这样的例子,有人能解释泽西岛发生了什么吗。当我能够在网络服务器上以InputStream的形式读取数据时,我惊呆了。

在服务器上的servlet容器中运行

@PUT
@Path("groups/{myUuid:" + Regex.UUID + "}")
public void updateSpectraData(@PathParam("myUuid") UUID myUuid, InputStream inputStream)
{
   float[] floatHolder = new float[512];
   byte[] bytes = ByteStreams.toByteArray(inputStream);
   ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
   byteBuffer.asFloatBuffer().get(floatHolder);
   System.out.println(Arrays.toString(floatHolder));
}

下面的代码在服务器派生的一个单独的进程中运行。

private void doPut(byte[] data, Object ctx)
{
   final Client client = ClientBuilder.newClient();
   ObjectMapper objectMapper = new ObjectMapper();
   MyTask myTask = objectMapper.readValue(data, MyTask.class);
   MyConifguration config = getConfig();
   WebTarget createTaskTarget = client.target(myTask.getURI());
   Builder request = createTaskTarget.request(MediaType.APPLICATION_OCTET_STREAM);
   request.put(Entity.entity(createData(config), MediaType.APPLICATION_OCTET_STREAM), InputStream.class);
}

这是创建数据的函数,返回类型是重要的:

private StreamingOutput createData(MyConfiguration config)
{
   return new StreamingOutput()
   {
    ...code...
   }
}

Jersey将根据请求的内容类型,尝试为您提供任何作为输入参数的内容。您也可以使用byte[]而不是InputStream。如果内容类型是application/octet流,并且您的输入参数是可序列化对象,那么Jersey将假设传入数据使用Java序列化,application/xml也是如此(它将使用JAXB)。如果您想使其更加明确,可以将@Consumes@Produces放在servlet方法上。