在 Play Framework 2.4.x 中设置 headers 的优雅方式

Elegant way of setting headers in Play Framework 2.4.x

在Play Framework 2中设置Content-RangeX-Content-RangeContent-Lengthheaders有没有更优雅的方法4.x?

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 指定参数?

@Before@After 注释在 Play 1.x 中可用,它们在 Play 2.x 中不再存在,您仍然可以使用 @With您可以将自己的 class 作为控制器 and/or 操作的拦截器。

无论如何,我看不出在每个操作中使用 setHeader(...) 方法有什么问题,尤其是当它们依赖于所需资源的属性时——比如在分块响应中。

除了将 setHeader(...) 方法放在实用方法中并从每个操作中调用它以减少代码重复外,您的解决方案没有太多可改进的地方(令人遗憾)。

action composition 和 global intercepts 都只适用于 @Before 类型的情况,特别是如果你想从 action 传递变量,它们就没用了。