当前位置: 首页 > 知识库问答 >
问题:

嵌入式Jetty服务器,无法在根上下文下查看网页

澹台阳秋
2023-03-14

我使用的是jetty v9。2.10.v20150310,java版本为“1.8.0_45”,安装在具有3.18.9内核的linux设备上。

问题是,如果我将上下文路径设置为非根值;i、 e.,/embed我可以在我的嵌入式jetty服务器上访问我的网页。但是,如果我将上下文路径设置为root;i、 例如,“/”我无法访问该页面。有趣的是,当我通过curl与servlet交互时,这个问题并没有出现。

以下是代码:

final ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);

final String servletWebDir = "/";
servletHandler.setContextPath( servletWebDir );

final customServlet iass = new customServlet();

final ServletHolder servletHolder = new ServletHolder( iass );
servletHolder.setInitOrder(0);
servletHandler.addServlet( servletHolder, "/customServlet" );

final ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setDirectoriesListed(false);
resourceHandler.setResourceBase(".");

final HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{ servletHandler, resourceHandler } );

server.setHandler( handlers );

如果我将servletWebDir从“/”更改为“/embed”,一切都会正常工作。如果不是,我会得到404。

我可以通过以下curl命令与servlet成功交互:

卷曲http://host:8080/customServlet?command=exp

如果我尝试使用http://host:8080/customServlet在firefox或chrome浏览器中,servletWebDir设置为“/”时,我会得到一个404。请注意,该代码在jetty v8下运行良好。1.16.v20140903。

我做错了什么?我在Jetty v9中错过了什么。十、

更新了使用setBaseResource并删除ResourceHandler的代码:

final ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
final String servletWebDir = "/";
final String theBaseResourceDir = "/aa/bb/cc";
Resource theBaseResource = null;
try{
    theBaseResource = Resource.newResource( theBaseResourceDir );
}
catch( MalformedURLException e ){
    System.err.println( "setup failed on newResource with the exception " + e.toString() );
    System.exit(0);
}

servletHandler.setBaseResource( theBaseResource );
System.err.println("Class path->" + servletHandler.getClassPath() );

final customServlet iass = new customServlet();
final ServletHolder servletHolder = new ServletHolder( iass );
servletHolder.setInitOrder(0);
servletHandler.addServlet( servletHolder, "/customServlet" );
final HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{ servletHandler } );
server.setHandler( handlers );

不管servletWebDir的值是多少,这段新代码不再为web浏览器提供静态页面。通过curl与定制servlet交互仍然有效。如果上面的新代码是正确的,我是否遗漏了什么?类路径在错误日志中报告为null。下一步我能试试什么?

约阿金:

我试过你建议的代码。我非常感谢您花时间和精力准备代码示例。然而,代码在运行时失败。错误日志指出:

STDERR:2015-05-09 15:51:32.278:警告:/embed:main:不可用的java。lang.IllegalAccessException:类组织。日食码头。服务器汉德勒。ContextHandler$Context无法在sun访问修饰符为“private”的customServlet类的成员。反映反射Ensuremberaccess(Reflection.java:102)

例外情况并没有确定应该公开的确切成员。我更新的代码确实有效,而且我不需要将一大堆方法从private更改为public。

Joakim能否请您解释一下您的解决方案的好处?如果我没有弄错的话,您的解决方案需要将私有方法和数据成员更改为公共数据成员和方法,从而失去封装的一些好处。

更新了修复此问题的代码:

server = new Server();
final ServerConnector connector = getConnector( server );
connector.setReuseAddress(false);
connector.setSoLingerTime(0);

final int port = 8080;
connector.setHost( theHostName );
connector.setPort( port );

server.addConnector(connector);

final String theRootContextDir = "/";
final ContextHandler rootContext = new ContextHandler(theRootContextDir);
final String theBaseResourceDir = ".";
rootContext.setResourceBase( theBaseResourceDir );

final ResourceHandler rhx = new ResourceHandler();
rootContext.setHandler( rhx );

/**
  * I want to replace the default jetty error handler with my
  * custom error handler. However I have not figured out how
  * to do it under jetty v9.x, yet-(May.08.2015,W.S.)
  * final ErrorHandler uiErrHandler = new userInputErrorHandler( logger );
  * rootContext.setErrorHandler( uiErrHandler );
  ***/

final ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);

final String theServletContextPath = "/";
servletHandler.setContextPath( theServletContextPath );
servletHandler.setResourceBase( "." );

final customServlet iass = new customServlet();
final ServletHolder servletHolder = new ServletHolder( iass );
final MultipartConfigElement mce = new MultipartConfigElement( fileUploadTmpDir );
servletHolder.getRegistration().setMultipartConfig( mce );
servletHolder.setInitOrder(0);
final String theServletName = "/customServlet";
servletHandler.addServlet( servletHolder, theServletName );

final HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{ rootContext, servletHandler } );

server.setHandler( handlers );

共有1个答案

范侯林
2023-03-14

您使用的是ServletContextHandler,不能将其与ResourceHandler混合使用,因为ServletContextHandler的内置DefaultServlet将为文件提供服务(或给出错误响应),从而使ResourceHandler永远无法执行。

要修复:

删除ResourceHandler(它远远不如DefaultServlet)。

将servletHandler.setBaseResources(Resources)设置为Web应用程序根目录(静态文件所在的位置)。这可以是URL、URI或文件系统路径引用。

例如:

// As a file system reference
servletHandler.setBaseResource(Resource.newResource("/path/to/res"));

// or URL
servletHandler.setBaseResource(Resource.newResource("jar:file://tmp/b.jar!/webroot"));

资源路径应该指向一个目录,而不是特定的文件。

有关更多详细信息,请参阅前面的答案。

示例:

package jetty;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.nio.file.Path;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;

public class SimpleServletExample
{
    public static void main(String[] args)
    {
        try
        {
            Server server = new Server(8080);

            // Find the full path to the webroot.
            // Use the real path, with real file system case for all parts of the path
            // Otherwise we fall afoul of alias checking.
            // (esp on OSX and Windows. Unix and Linux do not have this issue)
            Path webrootPath = new File("src/test/resources/sample-files").toPath().toRealPath();

            URI webrootUri = webrootPath.toUri();

            System.err.println("webroot uri: " + webrootUri);

            Resource webroot = Resource.newResource(webrootUri);
            if (!webroot.exists())
            {
                System.err.println("Resource does not exist: " + webroot);
                System.exit(-1);
            }

            if (!webroot.isDirectory())
            {
                System.err.println("Resource is not a directory: " + webroot);
                System.exit(-1);
            }

            // Establish ServletContext for all servlets
            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
            context.setContextPath("/");
            context.setBaseResource(webroot);
            // What file(s) should be used when client requests a directory
            context.setWelcomeFiles(new String[] { "index.html" });
            server.setHandler(context);

            // Add a servlet (technique #1)
            ServletHolder holderHello = context.addServlet(HelloServlet.class,"/hello");
            holderHello.setInitOrder(0);

            // Add default servlet last (always last) (technique #2)
            // Must be named "default", must be on path mapping "/"
            ServletHolder holderDef = new ServletHolder("default",DefaultServlet.class);
            holderDef.setInitParameter("dirAllowed","true");
            context.addServlet(holderDef,"/");

            // Start server
            server.start();
        }
        catch (MalformedURLException e)
        {
            System.err.println("Unable to establish webroot");
            e.printStackTrace(System.err);
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }
    }
}
 类似资料:
  • 我试图在HA模式下使用带有spring数据的neo4j嵌入式服务器。我得到类加载错误。我把所有的罐子都放好了。我试图在HA模式下使用带有spring数据的neo4j嵌入式服务器。我得到类加载错误。我把所有的罐子都放好了。

  • 我把头撞到墙上了。我编写了一个小型嵌入式jetty服务器(jetty 9.4.18,jersey 1.19.4),但我无法让它尊重上下文路径和部署的REST服务。 我尝试了setContextPath,但这在ServletContextHandler上不起作用,所以我使用了WebAppContext。 任何帮助都将不胜感激,因为我觉得我在这里被困在一码线上。

  • 对于某些应用程序来说,窗口查看围绕特定主题的多个文档是很有用的。上下文视图能够帮助设置包含时序性事件的索引模式。 想要显示与锚文档相关的上下文,点击文档表条目左侧的 Expand 按钮 ,然后点击 View surrounding documents 链接。 上下文视图会显示锚文档前后的多个文档。锚文档会用蓝色突出显示。该视图是根据索引模式配置的时间字段而检索出的结果,并使用 Discover 浏

  • 问题内容: 我讨厌问这样一个模糊的问题,但是我很难找到一个简单的例子。这是我到目前为止的内容: 我可以找到的嵌入式Jetty示例始终显示如下内容,以启动运行的Server实例,但我不知道如何实例化WebSocketServlet。 如何创建可以处理WebSocket连接请求的嵌入式服务器? 问题答案: 更新:2013年12月2日 有关带有WebSocket的嵌入式码头的最新示例,请参见: http

  • 运行Spring Boot应用程序时,嵌入式tomcat服务器无法启动。我刚刚在pom.xml中添加了所需的依赖项,并创建了一个简单的java POJO类。应用程序属性已经按照oracle数据库所需的jdbc配置以及Hibernate方言信息进行了设置。 执行mvn spring-boot:run时的控制台日志

  • 问题内容: 我正在编写一些示例代码,其中启动了嵌入式Jetty服务器。服务器必须仅加载一个servlet,将所有请求发送到servlet并在localhost:80上侦听 到目前为止,我的代码: 我可以用更少的代码/行做同样的事情吗?(使用Jetty 6.1.0)。 问题答案: 删除了不必要的空格,并内联移动了ServletHolder创建。删除了5行。