我在java项目中使用emmedded jetty。出于某种原因,我发送到resourceHandler的路径是c:\(小写),并且它被别名为c:\(大写)。正因为如此,我的静态内容没有被提供。
我读过一些文档,其中指出jetty比较绝对路径和规范路径来检测别名。在日志中,我看到:
[qtp15485575-19]INFO org.eclipse.jety.server.handler.ResourceHandler-文件:/c:/filepath别名为文件:/c:/filepath
有人对如何解决有什么想法吗?
更新:将错误记录到eclipse中:https://bugs.eclipse.org/bugs/show_bug.cgi?id=471526
以下是他们的回应:"这确实很烦人,但servlet规范糟糕的安全模型迫使我们这么做。
如果规范说除非明确允许,否则所有URI都被拒绝,那么我们就不需要检查别名了。但相反,它有一个模型,允许除了那些被明确拒绝的URI之外的所有URI。
因此,如果在/secretfile.txt上设置了安全约束,我们必须确保该文件的任何别名也受到约束。。。并且以独立于FS的方式进行。这意味着在各种操作系统上,我们可能需要阻止:
/sEcRetFile.TXT
/secretfile.txt
/SECRE~01.TXT
/secretfile.txt@@0
等等。等等。
所以可以肯定的是,我们已经实现了别名系统。
通常情况下,我们不会遇到c:和c:的问题,因为在配置上下文时应该规范化它们,所以应该使用正确的。但是文件系统确实会在不同版本之间改变它们的行为,所以这可能非常令人讨厌。
我认为这在jetty 9.3中处理得更好,在这里我们可以使用Path类来更好地检查部分路径。"
因此,如果可能的话,最好的选择可能是使用Jetty 9,如果问题仍然存在,则使用Joakin的修复方法。
给ResourceHandler
一个完整、绝对和真实的路径。
package jetty.resource;
import java.io.File;
import java.nio.file.Path;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.util.resource.PathResource;
public class ResourceHandlerFromFSExample
{
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
Path webRootPath = new File("src/test/webroot").toPath().toRealPath();
System.err.println("WebRoot is " + webRootPath);
ResourceHandler handler = new ResourceHandler();
handler.setBaseResource(new PathResource(webRootPath));
handler.setDirectoriesListed(true);
server.setHandler(handler);
server.start();
server.join();
}
}
顺便说一句,DefaultServlet
仍然是静态文件服务的一个更好的选择。