我在带有3.18.9内核的linux机器上使用带有java版本“1.8.0_45”的jetty v9.2.10.v20150310 .
问题是,如果我将上下文路径设置为非根值;即,/ embed我可以在我的嵌入式码头服务器上访问我的网页 . 但是,如果我将上下文路径设置为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从“/”更改为“/ embed”,一切正常 . 如果不是,我会得到404 .
我可以通过curl命令与servlet成功交互,如下所示:
curl http:// host:8080 / customServlet?command = exp
如果我尝试在firefox或chrome中使用http://host:8080/customServlet并且servletWebDir设置为"/"我得到404.请注意,此代码在jetty v8.1.16.v20140903下正常工作 .
我究竟做错了什么?我在Jetty v9.x中错过了什么?
Updated code that uses setBaseResource and drops the 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:WARN:/ embed:main:不可用java.lang.IllegalAccessException:类org.eclipse.jetty.server.handler.ContextHandler $ Context无法访问类customServlet的成员修饰符“private”at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
该例外并未确定应公开的确切成员 . 我的更新代码确实有效,我不必将一大堆方法从私有更改为公共 .
Joakim请您解释一下您的解决方案的好处,如果我没有弄错,需要将私有方法和数据成员更改为公共数据成员和方法,从而失去封装的一些好处 .
Updated Code that fixes this problem:
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
永远不会执行 .To Fix:
放弃
ResourceHandler
(无论如何它远远低于DefaultServlet
) .将servletHandler.setBaseResource(Resource)设置为Web应用程序根目录(静态文件所在的目录) . 这可以是URL,URI或文件系统路径引用 .
例子:
资源路径应指向目录,而不是特定文件 .
有关详细信息,请参阅previous answer about this .
Example: