在Play Framework 2.4.x中设置Content-Range
,X-Content-Range
和Content-Length
标题是否有更优雅的方法?
public static Result stream(Long id) {
byte[] data = Song.get(id).getData();
RangeWrapper range = new RangeWrapper(request().getHeader("Range"), data.length);
Chunks<byte[]> chunks = ByteChunks.whenReady(out -> {
out.write(Arrays.copyOfRange(data, range.getFrom(), range.getTo()));
out.close();
});
// Is there a way of saying @After(range.getFrom(), range.getTo(), range.getContentLength(), data.length)?
response().setHeader("Content-Range", String.format("bytes %d-%d/%d", range.getFrom(), range.getTo(), data.length));
response().setHeader("X-Content-Length", Integer.toString(range.getContentLength()));
response().setHeader("Content-Length", Integer.toString(range.getContentLength()));
return status(206, chunks);
}
或者我是否坚持使用所提出的解决方案,因为您无法使用@With
,@Before
和@After
指定参数?
答案 0 :(得分:1)
@Before
和@After
注释,并且它们不再存在于Play 2.x中,您仍可以使用@With
将您自己的类作为控制器和/或操作的拦截器。
无论如何,我在每个动作中使用setHeader(...)
方法都没有错,特别是当它们依赖于所需资源的属性时 - 比如在分块响应中。
答案 1 :(得分:1)
除了将setHeader(...)
方法放在实用程序方法中并从每个操作中调用它以减少代码重复之外,还没有太多改进你的解决方案(遗憾的是)。
动作组合和全局拦截仅适用于@Before
类型的情况,特别是如果你想从动作传递变量它们是无用的。