2015-05-06 45 views
3

我在带有3.18.9内核的Linux机器上使用java版本“1.8.0_45”的jetty v9.2.10.v20150310。嵌入式Jetty服务器,无法在根环境下查看网页

问题是,如果我将上下文路径设置为非根值;即/嵌入我可以在我的嵌入式码头服务器上访问我的网页。但是,如果我将上下文路径设置为root,即“/”我无法访问该页面。有趣的是,当我通过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 “/” 到 “/嵌入” 一切正常,因为它应该。 如果没有,我收到了404

我可以通过卷曲指挥一个遵循与servlet的成功互动:

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

如果我试图在任何Firefox或 使用http://host:8080/customServlet将servletWebDir设置为“/”的铬我得到了404。请注意,此代码在jetty v8.1.16.v20140903下正常工作。

我在做什么错?在Jetty v9.x中我错过了什么?

使用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的价值。通过curl与自定义servlet交互仍然有效。 如果上面的新代码是正确的,我错过了什么?类路径在错误日志中报告为空。接下来我可以尝试什么?

Joakim:

我试过了你建议的代码。我非常感谢您为编写代码示例所花费的时间和精力。但是,代码在运行时失败。错误日志状态:

STDERR:2015-05-09 15:51:32.278:WARN:/ embed:main:unavailable java.lang.IllegalAccessException:Class org.eclipse.jetty.server.handler.ContextHandler $上下文无法访问类别为customServlet的成员,其修饰符为“private” at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)

该例外无法识别应该公开的确切成员。 我的更新代码确实有效,我不必将一大堆方法从私有方式改为公共方法。

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

您使用的是ServletContextHandler,你不能混合使用ResourceHandler,作为内置ServletContextHandler可以提供文件服务的DefaultServlet(或放弃错误响应),使得ResourceHandler永远不会执行。

要解决:

删除该ResourceHandler(其远不如DefaultServlet反正)。

servletHandler.setBaseResource(Resource)设置为您的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")); 

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

请参阅previous answer about this了解更多详情。

例子:

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); 
     } 
    } 
} 
+0

您好:我没有如你所说。我使用setBaseResource并删除了ResourceHandler。但是,即使我将servletWebDir设置为“/ embed”,它也不起作用。你能否提出另一个建议?感谢您的时间。 –

+0

使用新代码 –

+0

更新您的问题@westsuhanic以糟糕的形式编辑某人回答更多问题,使用您自己的原始问题发布问题更新。 (继续为你做) –

相关问题