如何在提供文件之前使用嵌入式 Jetty 转换文件?

How to transform files with embedded Jetty before serving them?

这是我用来从带有嵌入式 Jetty 的文件系统提供静态文件的代码。

    String directory = "dir";
    final ContextHandler contextHandler = new ContextHandler();
    final ResourceHandler resourceHandler = new ResourceHandler();
    contextHandler.setContextPath("/" + directory);
    resourceHandler.setBaseResource(Resource.newResource(new File(directory,
                directory);
    contextHandler.setHandler(resourceHandler);

如何修改它以在提供文件之前转换文件?

我想继续使用 ResourceHandler 和 ContextHandler 以避免重新实现那些 类 中有用的逻辑。

谢谢!

ResourceHandler 不支持在流中修改内容(动态)。

ResourceHandler 经过优化以尽可能高效地发送文件,通常使用内存映射文件缓冲区,直接从磁盘向网络提供文件,接下来 Java 中的文件没有缓冲区处理]记忆.

您有 2 个选择:

  1. 在单独的步骤或过程中(不是即时)修改磁盘上的文件
  2. 编写您自己的文件服务处理程序,可以动态修改文件。

您可以使用 Jetty git 存储库中的 FastFileServer example 作为选择 #2 的良好起点。

我找到了解决方案。 它是用这样的 class 包装您的代码传递给 ResourceHandler.setBaseResource() 的资源:

public class TransformingResource extends Resource {
    private Resource resource;

    protected TransformingResource(Resource resource) {
        this.resource = resource;   
    }

    @Override
    public boolean isContainedIn(Resource r) throws MalformedURLException {
        return resource.isContainedIn(r);
    }

    @Override
    public void close() {
        resource.close();
    }

    @Override
    public boolean exists() {
        return resource.exists();
    }

    @Override
    public boolean isDirectory() {
        return resource.isDirectory();
    }

    @Override
    public long lastModified() {
        return resource.lastModified();
    }

    @Override
    public long length() {
        transform();

        return transformed.length();
    }

    @Override
    public URL getURL() {
        return resource.getURL();
    }

    @Override
    public File getFile() throws IOException {
        return resource.getFile();
    }

    @Override
    public String getName() {
        return resource.getName();
    }

    private String transformed;

    private void transform() {
        if(transformed != null) {
            return;
        }

        transformed = transformInputStream(resource.getInputStream());
    }

    @Override
    public InputStream getInputStream() throws IOException {
        transform();

        return new ByteArrayInputStream(transformed.getBytes(Charset.forName("UTF-8")));
    }

    @Override
    public ReadableByteChannel getReadableByteChannel() throws IOException {
        return null;
    }

    @Override
    public boolean delete() throws SecurityException {
        return resource.delete();
    }

    @Override
    public boolean renameTo(Resource dest) throws SecurityException {
        return resource.renameTo(dest);
    }

    @Override
    public String[] list() {
        return resource.list();
    }

    @Override
    public Resource addPath(String path) throws IOException,
            MalformedURLException {
        Resource toReturn = resource.addPath(path);
        if(toReturn == null) {
            return null;
        }

        return new TransformingResource(toReturn);
    }
}