如何在提供文件之前使用嵌入式 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 个选择:
- 在单独的步骤或过程中(不是即时)修改磁盘上的文件
- 编写您自己的文件服务处理程序,可以动态修改文件。
您可以使用 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);
}
}
这是我用来从带有嵌入式 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 个选择:
- 在单独的步骤或过程中(不是即时)修改磁盘上的文件
- 编写您自己的文件服务处理程序,可以动态修改文件。
您可以使用 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);
}
}