Issue #3799 Programmatic listeners from ServletContextListeners. (#3824)

* Issue #3799 Programmatic listeners from ServletContextListeners.

Ensure programmatic listeners added from ServletContextListeners are
called.

Signed-off-by: Jan Bartel <janb@webtide.com>

* Issue #3799 add distribution test

Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
This commit is contained in:
Jan Bartel 2019-07-01 15:14:19 +02:00 committed by GitHub
parent 154e036b1d
commit e26179e8e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 706 additions and 54 deletions

View File

@ -62,6 +62,9 @@ import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.MimeTypes;
@ -110,12 +113,15 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
public static final int SERVLET_MAJOR_VERSION = 3;
public static final int SERVLET_MINOR_VERSION = 1;
public static final Class<?>[] SERVLET_LISTENER_TYPES =
{
ServletContextListener.class,
ServletContextAttributeListener.class,
ServletRequestListener.class,
ServletRequestAttributeListener.class
};
{
ServletContextListener.class,
ServletContextAttributeListener.class,
ServletRequestListener.class,
ServletRequestAttributeListener.class,
HttpSessionIdListener.class,
HttpSessionListener.class,
HttpSessionAttributeListener.class
};
public static final int DEFAULT_LISTENER_TYPE_INDEX = 1;
public static final int EXTENDED_LISTENER_TYPE_INDEX = 0;
@ -643,7 +649,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
_eventListeners.add(listener);
if (!(isStarted() || isStarting()))
{
_durableListeners.add(listener);
}
if (listener instanceof ContextScopeListener)
{
@ -704,10 +712,15 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
_programmaticListeners.add(listener);
}
protected boolean isProgrammaticListener(EventListener listener)
public boolean isProgrammaticListener(EventListener listener)
{
return _programmaticListeners.contains(listener);
}
public boolean isDurableListener(EventListener listener)
{
return _durableListeners.contains(listener);
}
/**
* @return true if this context is shutting down

View File

@ -22,6 +22,8 @@ import java.util.EventListener;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.eclipse.jetty.server.handler.ContextHandler;
/**
* ListenerHolder
*
@ -32,7 +34,6 @@ import javax.servlet.ServletException;
public class ListenerHolder extends BaseHolder<EventListener>
{
private EventListener _listener;
private boolean _initialized = false;
public ListenerHolder()
{
@ -68,35 +69,6 @@ public class ListenerHolder extends BaseHolder<EventListener>
setHeldClass(_listener.getClass());
}
public void initialize(ServletContext context) throws Exception
{
if (!_initialized)
{
initialize();
if (_listener == null)
{
//create an instance of the listener and decorate it
try
{
_listener = (context instanceof ServletContextHandler.Context)
? context.createListener(getHeldClass())
: getHeldClass().getDeclaredConstructor().newInstance();
}
catch (ServletException ex)
{
Throwable cause = ex.getRootCause();
if (cause instanceof InstantiationException)
throw (InstantiationException)cause;
if (cause instanceof IllegalAccessException)
throw (IllegalAccessException)cause;
throw ex;
}
}
_initialized = true;
}
}
@Override
public void doStart() throws Exception
{
@ -107,6 +79,29 @@ public class ListenerHolder extends BaseHolder<EventListener>
super.stop();
throw new IllegalStateException(msg);
}
ContextHandler contextHandler = ContextHandler.getCurrentContext().getContextHandler();
if (_listener == null)
{
//create an instance of the listener and decorate it
try
{
ServletContext scontext = contextHandler.getServletContext();
_listener = (scontext instanceof ServletContextHandler.Context)
? scontext.createListener(getHeldClass())
: getHeldClass().getDeclaredConstructor().newInstance();
}
catch (ServletException ex)
{
Throwable cause = ex.getRootCause();
if (cause instanceof InstantiationException)
throw (InstantiationException)cause;
if (cause instanceof IllegalAccessException)
throw (IllegalAccessException)cause;
throw ex;
}
}
contextHandler.addEventListener(_listener);
}
@Override
@ -115,7 +110,6 @@ public class ListenerHolder extends BaseHolder<EventListener>
super.doStop();
if (!_extInstance)
_listener = null;
_initialized = false;
}
@Override

View File

@ -107,6 +107,8 @@ public class ServletContextHandler extends ContextHandler
protected int _options;
protected JspConfigDescriptor _jspConfig;
private boolean _startListeners;
public ServletContextHandler()
{
this(null, null, null, null, null);
@ -347,14 +349,11 @@ public class ServletContextHandler extends ContextHandler
for (ListenerHolder holder : _servletHandler.getListeners())
{
holder.start();
//we need to pass in the context because the ServletHandler has not
//yet got a reference to the ServletContext (happens in super.startContext)
holder.initialize(_scontext);
addEventListener(holder.getListener());
}
}
}
_startListeners = true;
super.startContext();
// OK to Initialize servlet handler now that all relevant object trees have been started
@ -365,6 +364,7 @@ public class ServletContextHandler extends ContextHandler
@Override
protected void stopContext() throws Exception
{
_startListeners = false;
super.stopContext();
}
@ -1417,8 +1417,19 @@ public class ServletContextHandler extends ContextHandler
ListenerHolder holder = getServletHandler().newListenerHolder(Source.JAVAX_API);
holder.setListener(t);
getServletHandler().addListener(holder);
addProgrammaticListener(t);
getServletHandler().addListener(holder);
if (_startListeners)
{
try
{
holder.start();
}
catch (Exception e)
{
throw new IllegalStateException(e);
}
}
}
@Override

View File

@ -18,25 +18,48 @@
package org.eclipse.jetty.servlet;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EventListener;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
@ -61,15 +84,6 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ServletContextHandlerTest
{
private Server _server;
@ -157,8 +171,7 @@ public class ServletContextHandlerTest
}
public static class MyTestSessionListener implements HttpSessionAttributeListener, HttpSessionListener
{
{
@Override
public void sessionCreated(HttpSessionEvent se)
{
@ -184,6 +197,187 @@ public class ServletContextHandlerTest
{
}
}
public static class MySCAListener implements ServletContextAttributeListener
{
public static int adds = 0;
public static int removes = 0;
public static int replaces = 0;
@Override
public void attributeAdded(ServletContextAttributeEvent event)
{
++adds;
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event)
{
++removes;
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event)
{
++replaces;
}
}
public static class MyRequestListener implements ServletRequestListener
{
public static int destroys = 0;
public static int inits = 0;
@Override
public void requestDestroyed(ServletRequestEvent sre)
{
++destroys;
}
@Override
public void requestInitialized(ServletRequestEvent sre)
{
++inits;
}
}
public static class MyRAListener implements ServletRequestAttributeListener
{
public static int adds = 0;
public static int removes = 0;
public static int replaces = 0;
@Override
public void attributeAdded(ServletRequestAttributeEvent srae)
{
++adds;
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae)
{
++removes;
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae)
{
++replaces;
}
}
public static class MySListener implements HttpSessionListener
{
public static int creates = 0;
public static int destroys = 0;
@Override
public void sessionCreated(HttpSessionEvent se)
{
++creates;
}
@Override
public void sessionDestroyed(HttpSessionEvent se)
{
++destroys;
}
}
public static class MySAListener implements HttpSessionAttributeListener
{
public static int adds = 0;
public static int removes = 0;
public static int replaces = 0;
@Override
public void attributeAdded(HttpSessionBindingEvent event)
{
++adds;
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event)
{
++removes;
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event)
{
++replaces;
}
}
public static class MySIListener implements HttpSessionIdListener
{
public static int changes = 0;
@Override
public void sessionIdChanged(HttpSessionEvent event, String oldSessionId)
{
++changes;
}
}
public class InitialListener implements ServletContextListener
{
@Override
public void contextInitialized(ServletContextEvent sce)
{
//Add all of the sorts of listeners that are allowed
try
{
MySCAListener mySCAListener = sce.getServletContext().createListener(MySCAListener.class);
sce.getServletContext().addListener(mySCAListener);
MyRequestListener myRequestListener = sce.getServletContext().createListener(MyRequestListener.class);
sce.getServletContext().addListener(myRequestListener);
MyRAListener myRAListener = sce.getServletContext().createListener(MyRAListener.class);
sce.getServletContext().addListener(myRAListener);
MySListener mySListener = sce.getServletContext().createListener(MySListener.class);
sce.getServletContext().addListener(mySListener);
MySAListener mySAListener = sce.getServletContext().createListener(MySAListener.class);
sce.getServletContext().addListener(mySAListener);
MySIListener mySIListener = sce.getServletContext().createListener(MySIListener.class);
sce.getServletContext().addListener(mySIListener);
}
catch (Exception e)
{
fail(e);
}
//And also test you can't add a ServletContextListener from a ServletContextListener
try
{
MyContextListener contextListener = sce.getServletContext().createListener(MyContextListener.class);
sce.getServletContext().addListener(contextListener);
fail("Adding SCI from an SCI!");
}
catch (IllegalArgumentException e)
{
//expected
}
catch (Exception x)
{
fail(x);
}
sce.getServletContext().setAttribute("foo", "bar");
}
@Override
public void contextDestroyed(ServletContextEvent sce)
{
}
}
@BeforeEach
public void createServer()
@ -232,6 +426,114 @@ public class ServletContextHandlerTest
assertTrue((Boolean)root.getServletContext().getAttribute("MySCI.startup"));
assertTrue((Boolean)root.getServletContext().getAttribute("MyContextListener.contextInitialized"));
}
@Test
public void testListenersFromContextListener() throws Exception
{
ContextHandlerCollection contexts = new ContextHandlerCollection();
_server.setHandler(contexts);
ServletContextHandler root = new ServletContextHandler(contexts, "/", ServletContextHandler.SESSIONS);
ListenerHolder initialListener = new ListenerHolder();
initialListener.setListener(new InitialListener());
root.getServletHandler().addListener(initialListener);
ServletHolder holder0 = root.addServlet(TestServlet.class, "/test");
_server.start();
ListenerHolder[] listenerHolders = root.getServletHandler().getListeners();
assertNotNull(listenerHolders);
for (ListenerHolder l : listenerHolders)
{
assertTrue(l.isStarted());
assertNotNull(l.getListener());
//all listeners except the first should be programmatic
if (!"org.eclipse.jetty.servlet.ServletContextHandlerTest$InitialListener".equals(l.getClassName()))
{
assertFalse(root.isDurableListener(l.getListener()));
assertTrue(root.isProgrammaticListener(l.getListener()));
}
}
EventListener[] listeners = root.getEventListeners();
assertNotNull(listeners);
List<String> listenerClassNames = new ArrayList<>();
for (EventListener l : listeners)
listenerClassNames.add(l.getClass().getName());
assertTrue(listenerClassNames.contains("org.eclipse.jetty.servlet.ServletContextHandlerTest$MySCAListener"));
assertTrue(listenerClassNames.contains("org.eclipse.jetty.servlet.ServletContextHandlerTest$MyRequestListener"));
assertTrue(listenerClassNames.contains("org.eclipse.jetty.servlet.ServletContextHandlerTest$MyRAListener"));
assertTrue(listenerClassNames.contains("org.eclipse.jetty.servlet.ServletContextHandlerTest$MySListener"));
assertTrue(listenerClassNames.contains("org.eclipse.jetty.servlet.ServletContextHandlerTest$MySAListener"));
assertTrue(listenerClassNames.contains("org.eclipse.jetty.servlet.ServletContextHandlerTest$MySIListener"));
//test ServletRequestAttributeListener
String response = _connector.getResponse("GET /test?req=all HTTP/1.0\r\n\r\n");
assertThat(response, Matchers.containsString("200 OK"));
assertEquals(1, MyRAListener.adds);
assertEquals(1, MyRAListener.replaces);
assertEquals(1, MyRAListener.removes);
//test HttpSessionAttributeListener
response = _connector.getResponse("GET /test?session=create HTTP/1.0\r\n\r\n");
String sessionid = response.substring(response.indexOf("JSESSIONID"), response.indexOf(";"));
assertThat(response, Matchers.containsString("200 OK"));
assertEquals(1, MySListener.creates);
assertEquals(1, MySAListener.adds);
assertEquals(0, MySAListener.replaces);
assertEquals(0, MySAListener.removes);
StringBuffer request = new StringBuffer();
request.append("GET /test?session=replace HTTP/1.0\n");
request.append("Host: localhost\n");
request.append("Cookie: "+sessionid+"\n");
request.append("\n");
response = _connector.getResponse(request.toString());
assertThat(response, Matchers.containsString("200 OK"));
assertEquals(1, MySListener.creates);
assertEquals(1, MySAListener.adds);
assertEquals(1, MySAListener.replaces);
assertEquals(0, MySAListener.removes);
request = new StringBuffer();
request.append("GET /test?session=remove HTTP/1.0\n");
request.append("Host: localhost\n");
request.append("Cookie: "+sessionid+"\n");
request.append("\n");
response = _connector.getResponse(request.toString());
assertThat(response, Matchers.containsString("200 OK"));
assertEquals(1, MySListener.creates);
assertEquals(1, MySAListener.adds);
assertEquals(1, MySAListener.replaces);
assertEquals(1, MySAListener.removes);
//test HttpSessionIdListener.sessionIdChanged
request = new StringBuffer();
request.append("GET /test?session=change HTTP/1.0\n");
request.append("Host: localhost\n");
request.append("Cookie: "+sessionid+"\n");
request.append("\n");
response = _connector.getResponse(request.toString());
assertThat(response, Matchers.containsString("200 OK"));
assertEquals(1, MySIListener.changes);
sessionid = response.substring(response.indexOf("JSESSIONID"), response.indexOf(";"));
//test HttpServletListener.sessionDestroyed
request = new StringBuffer();
request.append("GET /test?session=delete HTTP/1.0\n");
request.append("Host: localhost\n");
request.append("Cookie: "+sessionid+"\n");
request.append("\n");
response = _connector.getResponse(request.toString());
assertThat(response, Matchers.containsString("200 OK"));
assertEquals(1, MySListener.destroys);
//test ServletContextAttributeListener
//attribute was set when context listener registered
assertEquals(1, MySCAListener.adds);
response = _connector.getResponse("GET /test?ctx=all HTTP/1.0\r\n\r\n");
assertThat(response, Matchers.containsString("200 OK"));
assertEquals(1, MySCAListener.replaces);
assertEquals(1, MySCAListener.removes);
}
@Test
public void testFindContainer() throws Exception
@ -670,6 +972,62 @@ public class ServletContextHandlerTest
resp.setStatus(HttpServletResponse.SC_OK);
PrintWriter writer = resp.getWriter();
writer.write("Test");
String action = req.getParameter("session");
if (!Objects.isNull(action))
{
if ("create".equalsIgnoreCase(action))
{
//Make a session
HttpSession session = req.getSession(true);
session.setAttribute("some", "thing");
}
else if ("change".equalsIgnoreCase(action))
{
HttpSession session = req.getSession(true);
req.changeSessionId();
}
else if ("replace".equalsIgnoreCase(action))
{
HttpSession session = req.getSession(false);
session.setAttribute("some", "other");
}
else if ("remove".equalsIgnoreCase(action))
{
HttpSession session = req.getSession(false);
session.removeAttribute("some");
}
else if ("delete".equalsIgnoreCase(action))
{
HttpSession session = req.getSession(false);
session.invalidate();
}
else
resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
action = req.getParameter("req");
if (!Objects.isNull(action))
{
//test all attribute ops
req.setAttribute("some", "value");
req.setAttribute("some", "other");
req.removeAttribute("some");
return;
}
action = req.getParameter("ctx");
if (!Objects.isNull(action))
{
//change and remove context attribute
req.getServletContext().setAttribute("foo", "foo");
req.getServletContext().removeAttribute("foo");
return;
}
}
}
}

View File

@ -81,6 +81,13 @@
<type>war</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>

View File

@ -0,0 +1,98 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.tests.distribution;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.util.IO;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class DynamicListenerTests
extends AbstractDistributionTest
{
@Test
public void testSimpleWebAppWithJSP() throws Exception
{
Path jettyBase = Files.createTempDirectory( "jetty_base");
String jettyVersion = System.getProperty("jettyVersion");
DistributionTester distribution = DistributionTester.Builder.newInstance()
.jettyBase(jettyBase)
.jettyVersion(jettyVersion)
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
.build();
String[] args1 = {
"--create-startd",
"--approve-all-licenses",
"--add-to-start=resources,server,http,webapp,deploy,jsp,jmx,servlet,servlets,security,websocket"
};
try (DistributionTester.Run run1 = distribution.start(args1))
{
assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
File war = distribution.resolveArtifact( "org.eclipse.jetty:test-jetty-webapp:war:" + jettyVersion);
distribution.installWarFile(war, "test");
Path etc = Paths.get(jettyBase.toString(),"etc");
if(!Files.exists(etc))
{
Files.createDirectory(etc);
}
Files.copy(Paths.get("src/test/resources/realm.ini"),
Paths.get(jettyBase.toString(),"start.d").resolve("realm.ini"));
Files.copy(Paths.get("src/test/resources/realm.properties"),
etc.resolve("realm.properties"));
Files.copy(Paths.get("src/test/resources/test-realm.xml"),
etc.resolve("test-realm.xml"));
int port = distribution.freePort();
try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
{
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
startHttpClient();
ContentResponse response = client.GET("http://localhost:" + port + "/test/testservlet/foo");
assertEquals(HttpStatus.OK_200, response.getStatus());
String content = response.getContentAsString();
System.out.println(content);
assertThat(content, containsString("All Good"));
assertThat(content, containsString("requestInitialized"));
assertThat(content, containsString("requestInitialized"));
assertThat(content, not(containsString("<%")));
}
} finally
{
IO.delete(jettyBase.toFile());
}
}
}

View File

@ -0,0 +1,9 @@
#
# Example of providing a demo configuration, using a ${jetty.base}
#
# Additional ini files are in demo-base/start.d
#
# Create and configure the test realm
etc/test-realm.xml
jetty.demo.realm=etc/realm.properties

View File

@ -0,0 +1,25 @@
#
# This file defines users passwords and roles for a HashUserRealm
#
# The format is
# <username>: <password>[,<rolename> ...]
#
# Passwords may be clear text, obfuscated or checksummed. The class
# org.eclipse.util.Password should be used to generate obfuscated
# passwords or password checksums
#
# If DIGEST Authentication is used, the password must be in a recoverable
# format, either plain text or OBF:.
#
jetty: MD5:164c88b302622e17050af52c89945d44,user
admin: CRYPT:adpexzg3FUZAk,server-administrator,content-administrator,admin,user
other: OBF:1xmk1w261u9r1w1c1xmq,user
plain: plain,user
user: password,user
# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
digest: MD5:6e120743ad67abfbc385bc2bb754e297,user
j2ee: j2ee,Administrator,Employee
javajoe: javajoe,VP,Manager
CN\=CTS,\ OU\=Java\ Software,\ O\=Sun\ Microsystems\ Inc.,\ L\=Burlington,\ ST\=MA,\ C\=,US=,Administrator

View File

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Configure Authentication Login Service -->
<!-- Realms may be configured for the entire server here, or -->
<!-- they can be configured for a specific web app in a context -->
<!-- configuration (see $(jetty.home)/webapps/test.xml for an -->
<!-- example). -->
<!-- =========================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.security.HashLoginService">
<Set name="name">Test Realm</Set>
<Set name="config"><Property name="jetty.demo.realm" default="etc/realm.properties"/></Set>
<Set name="hotReload">false</Set>
</New>
</Arg>
</Call>
<Get class="org.eclipse.jetty.util.log.Log" name="rootLogger">
<Call name="warn"><Arg>demo test-realm is deployed. DO NOT USE IN PRODUCTION!</Arg></Call>
</Get>
</Configure>

View File

@ -0,0 +1,50 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package com.acme;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import java.util.ArrayList;
import java.util.List;
public final class AddListServletRequestListener
implements ServletRequestListener
{
public void requestDestroyed( ServletRequestEvent event )
{
List al = (List) event.getServletContext().getAttribute( "arraylist" );
if ( al != null )
{
event.getServletContext().removeAttribute( "arraylist" );
}
}
public void requestInitialized( ServletRequestEvent event )
{
List al = (List) event.getServletContext().getAttribute( "arraylist" );
if ( al == null )
{
al = new ArrayList();
}
al.add( "in requestInitialized method of "+ getClass().getName() );
event.getServletContext().setAttribute( "arraylist", al );
}
}

View File

@ -31,6 +31,7 @@ import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
@ -139,6 +140,18 @@ public class TestListener implements HttpSessionListener, HttpSessionAttributeLi
EnumSet.of(DispatcherType.ERROR, DispatcherType.ASYNC, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST),
true,
"/*");
try
{
AddListServletRequestListener listenerClass =
sce.getServletContext().createListener( AddListServletRequestListener.class );
sce.getServletContext().addListener( listenerClass );
}
catch ( ServletException e )
{
throw new RuntimeException( e.getMessage(), e );
}
}
@Override

View File

@ -0,0 +1,38 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package com.acme;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
public class TestServlet extends HttpServlet
{
@Override
protected void doGet( HttpServletRequest req, HttpServletResponse resp )
throws ServletException, IOException
{
List l = (List) getServletContext().getAttribute( "arraylist" );
resp.getOutputStream().println( "All Good " + l.toString() );
}
}

View File

@ -188,6 +188,18 @@
<url-pattern>/jsp/foo/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.acme.TestServlet</servlet-class>
<load-on-startup>10</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/testservlet/*</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/error404.html</location>