Jetty在索引2 处发现非法字符 <:>
我在用最新版的Jetty(12.1.9)提供静态资源时遇到了困难。 当我使用 "file:///C:/some/path/to/html/" 时,就会得到
java.nio.file.InvalidPathException: Illegal char <:> at index 2: /C:/some/path/to/html/index.html
但当我使用 "file://C:/some/path/to/html/" 时,我会得到
Resource is not a readable directory
以及一个警告
[main] WARN org.eclipse.jetty.server.handler.ResourceHandler - Base Resource should be a directory: file://C:/some/path/to/html/
我已经再次确认该目录和index.html确实存在。
我的完整代码如下:
public static void main(String[] args) throws Exception {
int port = 80;
var server = new Server();
HttpConfiguration httpConf = new HttpConfiguration();
HttpConnectionFactory httpFac = new HttpConnectionFactory(httpConf);
ServerConnector connector = new ServerConnector(server, httpFac);
connector.setPort(port);
server.addConnector(connector);
ContextHandlerCollection contextCollection = new ContextHandlerCollection();
ResourceHandler handler = new ResourceHandler();
URI baseDir = URI.create("file://C:/some/path/to/html/");
Resource baseResource = ResourceFactory.of(handler).newResource(baseDir);
if (!Resources.isReadableDirectory(baseResource)) {
throw new RuntimeException("Resource is not a readable directory");
}
handler.setBaseResource(baseResource);
handler.setDirAllowed(true);
handler.setWelcomeFiles(List.of("index.html"));
contextCollection.addHandler(new ContextHandler(handler, "/file"));
server.setHandler(contextCollection);
server.start();
server.join();
}
解决方案
我对 Resource 类的源代码做了一番研究。Jetty的实现实在是漏洞百出,简直难以置信。我写了自己的实现,现在已经可以正常工作了。
public static class ResourcePath extends Resource {
final Path p;
public ResourcePath(Path p) {
this.p = p;
}
@Override
public Path getPath() {
return p;
}
@Override
public long length() {
return p.toFile().length();
}
@Override
public Instant lastModified() {
try {
return Files.getLastModifiedTime(p).toInstant();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public List<Resource> list() {
try {
return Files.list(p).map(ResourcePath::new).collect(Collectors.toList());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean isDirectory() {
return Files.isDirectory(p);
}
@Override
public boolean isReadable() {
return Files.isReadable(p);
}
@Override
public URI getURI() {
return p.toUri();
}
@Override
public String getName() {
return p.getFileName().toString();
}
@Override
public String getFileName() {
return p.getFileName().toString();
}
@Override
public Resource resolve(String s) {
if(s.startsWith("/")){
s = s.substring(1);
}
return new ResourcePath(p.resolve(s));
}
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。