Я использую причал v9.2.10.v20150310 с версией java "1.8.0_45" на Linux-сервере с ядром 3.18.9.
Проблема в том, что если я установил для пути контекста значение, отличное от корневого; т.е. / embed Я могу получить доступ к своей веб-странице на моем встроенном сервере причала. Однако, если я установил контекстный путь как root; т.е. "/" Я не могу получить доступ к странице. Интересно, что эта проблема не проявляется, когда я взаимодействую с сервлетом через curl.
Вот код:
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:
Если я попытаюсь использовать http://host:8080/customServlet в firefox или chrome с servletWebDir, установленным на "/ "Я получаю 404. Обратите внимание, что этот код отлично работает под причалом 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 по-прежнему работает. Если приведенный выше новый код верен, я что-то пропустил? Путь к классу отображается в журналах ошибок как null. Что я могу попробовать дальше?
Иоаким:
Я попробовал предложенный вами код. Я очень ценю время и усилия, которые вы потратили на подготовку образца кода. Однако код не работает во время выполнения. В журнале ошибок указано:
STDERR: 2015-05-09 15: 51: 32.278: WARN: / embed: main: unavailable java.lang.IllegalAccessException: Class org.eclipse.jetty.server.handler.ContextHandler $ Context не может получить доступ к члену класса customServlet с модификаторы "private" в sun.reflect.Reflection.ensureMemberAccess (Reflection.java:102)
Исключение не указывает точного члена, который должен быть обнародован. Мой обновленный код действительно работает, и мне не нужно менять целую кучу методов с частных на общедоступные.
Йоаким, не могли бы вы объяснить преимущества вашего решения, которое, если я не ошибаюсь, требует изменения частных методов и элементов данных на элементы и методы общедоступных данных и, следовательно, теряет некоторые преимущества инкапсуляции.
Обновленный код, устраняющий эту проблему:
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 );
server
обслуживает статические ресурсы для меня. 07.03.2017