Spring Boot 1.4: Gherkin tests

In this post I show how you can implement Gherkin tests for Spring Boot 1.4.1. Here is an example of a Gherkin based test script:


The FeatureScenarioScenario OutlineGiven, When, Then and And constructs are part of the Gherkin test language [1]. Such tests are popular in Behavior-driven development (BDD) and is meant as a common tool between users from the business and users from the development team [2].

The idea is that you can execute such a Gherkin script and get a test result (did it work or not?)

Notice the Gherkin language, there is nothing that prevents you from writing such tests even before the real business code exists. In fact it is a BDD best practice to write the tests before the feature gets implemented:

Imagine if you and the business wrote Gherkin tests as part of a User Story’s acceptance criteria…

I haven’t done this yet. But I bet there are a lot of BDD practitioners that have.

About the Spring Boot 1.4 example

I have prepared a Spring Boot 1.4.1 based example on GitHub. Consult that to see the code in its entirety and true surroundings. The example consists of:

  • The Gherkin test script you saw at the beginning of this post: It’s a script that tests a “greetings” RESTful(ish) resource.
  • The greetings resource: A super simple Spring MVC @RestController that accepts a caller name as input and emits a greeting message as output. This is the resource being tested.

I have used a 5 step recipe for making this work….

Step 1 of 5: Configure the build script

The example uses Gradle as it’s build technology. The Gherkin test support comes via the Cucumber-JVM test framework [3] and the Gradle Cucumber Plugin [4]. Here’s the Gradle script:

buildscript {
    repositories {
        // So that the Gradle Cucumber Plugin can be downloaded:
        maven { url "https://plugins.gradle.org/m2/" }
    dependencies {

apply plugin: 'java'
apply plugin: 'spring-boot'
// So that the Gradle Cucumber Plugin gets activated:
apply plugin: 'com.github.samueltbrown.cucumber'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    testCompile 'org.springframework.boot:spring-boot-starter-test'
    // So that you can use the cucumber API's for your step implementations:
    cucumberCompile 'info.cukes:cucumber-java:1.2.5'
    cucumberCompile 'info.cukes:cucumber-junit:1.2.5'
    cucumberCompile 'info.cukes:cucumber-spring:1.2.5'

cucumber {
    // So that you can generate some pretty (...) reports:
    formats = ['pretty', 'json:build/cucumber/cucumber.json', 'junit:build/cucumber/cucumber.xml', 'html:build/cucumber/html']

    // So that you can run all features/scenarios except for those annotated with @Ignore:
    tags = ['~@Ignore']

Notice the comments in the buildscript. They highlight what parts of the Gradle script are particularly interesting.

By using the Gradle Cucumber Plugin you now have the support for a new source folder structure:

|--- java
|--- resources

You put the Gherkin step implementations in the src/cucumber/java directory and the Gherkin scripts under the src/cucumber/resources directory.

Step 2 of 5: Write the Gherkin tests

The Gherkin tests are written in a .feature file. In the example I put the following contents into src/cucumber/resources/greetingsResource.feature:


This script contains 3 test scenarios.

The two first tests are based on the Scenario Outline and uses data from the Examples block. First column is the input we send to the greetings resource. Second and third columns are the expected outputs given that input. So: If we send in Duke to the greetings resource then we expect an HTTP status code 200 and a body with the message Hello World, Duke.

The third test is a Scenario that is not based on example input data. This test is just for fun 😉 [5].

In the real world you would cover error conditions as well. So if you are testing a RESTful resource, like in this example, you would test for client errors 4xx etc.

Step 3 of 5: Implement the Gherkin steps test code

Here’s the step implementations for the Gherkin script:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration // Don't ask
public class GreetingsResourceSteps {

  private TestRestTemplate restTemplate;

  private String caller; // input

  private ResponseEntity<String> response; // output

  @Given("I use the caller (.*)")
  public void useCaller(String caller) {
    this.caller = caller;

  @When("I request a greeting")
  public void requestGreeting() {
    response = restTemplate
        .exchange("/greetings/{caller}", HttpMethod.GET, null, String.class, caller);

  @Then("I should get a response with HTTP status code (.*)")
  public void shouldGetResponseWithHttpStatusCode(int statusCode) {

  @And("The response should contain the message (.*)")
  public void theResponseShouldContainTheMessage(String message) {


Take a look at the class definition: this is where we tell the cucumber test framework to kickstart the Spring container. In fact it’s just like you would do in a typical Spring Boot 1.4 integration test: using the @SpringBootTest annotation. Said in another way: The Spring ApplicationContext will be launched prior to executing the Gherkin test scenarios.

Now take a look at lines 5+6: Here we inject Springs TestRestTemplate. We use this to send HTTP requests for our RESTful resource. Again, this is just like you would do in a typical Spring Boot 1.4 integration test.

Now take a look at the @Given, @When, @Then, and @And annotations: These define the methods implementing the steps. You can track them right back to the src/cucumber/resources/greetingsResource.feature file. Notice how we use simple regular expressions to map step input (fx caller values) to method parameters.

In case of errors, the steps throws ordinary java.lang.AssertionErrors via the awesome AssertJ library [6].

See? It almost looks like a normal Spring Boot integration test. One major difference is the need for storing intermediate state in the class itself (or somewhere else: fx a shared class). Well rest in the knowledge that any involved step classes, here GreetingsResourceSteps, are disposed after each Scenario. Said in another way: you have a fresh “steps” instance for each scenario.

You may also want to take a look at the @Before and @After cucumber annotations. They resemble the same from JUnit.

Step 4 of 5: Implement the feature being tested

Lastly, we get to the actual feature. It’s just the ordinary @RestController:

public class GreetingsController {

  public ResponseEntity<?> getGreeting(@PathVariable String caller) {

    if ("0xCAFEBABE".equalsIgnoreCase(caller)) {
      return new ResponseEntity<>(HttpStatus.I_AM_A_TEAPOT);

    String greeting = String.format("Hello World, %s", caller);

    return new ResponseEntity<>(greeting, HttpStatus.OK);


Ahem … I obviously wrote this controller after the Gherkin tests.

Step 5 of 5: Run the Gherkin tests and get the result

Thanks to the Gradle Cucumber Plugin, running the tests is a matter of:

./gradlew clean cucumber

Here is an example output:


And here is an example output from the HTML generated report at ./build/cucumber/html/index.html:


Using Jenkins as a CI server? You can find a bunch of cucumber plugins for that. Just point the plugins to your build/cucumber directory and you are good to go.

In retrospective

This example was all about testing a RESTful resource. But Gherkin style tests are not limited to that:

The Gherkin step implemention code could test anything

You could drive Selenium tests if you want to. Or Spring @Service beans. You decide.

The important thing is that it helps you and the business drive the right solution


[1] Gherkin language:

[2] Behavior-driven development (BDD) on Wikipedia:

[3] Cucumber-JVM:

[4] Gradle Cucumber Plugin

[5] 418

[6] AssertJ

Tagged with: , , ,
Posted in BDD, Spring

Spring 4.3: Custom annotations

In this post I will show you how to bend the Spring Framework a little bit. In particular I will show you how you can make code like this:

public class GreeterService {

  private Message greetingMsg;

  public String sayHello(@NotNull String caller) {
    return greetingMsg.format(caller);


@BusinessService declares a perfectly valid Spring bean. It comes with the support for @NotNull parameter checks. @NotNull is from the bean validation API – no need to exercise too many keystrokes.

@LocalizedMessage is a perfectly valid injection capable annotation. Here we use that to inject a Message bean. This bean is context aware – it knows about the @LocalizedMessage annotation’s value attribute. With this information, Message is used from method sayHello to return Locale aware messages. ( AWESOME TIP UNLOCKED ).

Please note that:

just because you can doesn’t mean you should

Be careful about how creative you get when bending the Spring Framework. It could easily contribute to a codebase where only a few specialized authors understand what is really going on.

The next sections jumps right into the solution. I have prepared a working example at GitHub. Consult that to see the source code in it’s entirety and true surroundings. The example is based in Spring Boot 1.4.1 and Spring Framework 4.3.3.

Test cases

Here’s a few integration tests documenting how the service works:

public class GreeterServiceIntegrationTests {

  private GreeterService greeterService;

  public void sayHello_whenInvoked_thenReturnsEnglishGreeting() {

    // Given
    String caller = "Duke";

    // When
    String greeting = greeterService.sayHello(caller);

    // Then
    assertThat(greeting).isEqualTo("Hello World, Duke");

  @Test(expected = IllegalArgumentException.class)
  public void sayHello_whenInvokedWithNullArgument_thenThrowsIllegalArgumentException() {

    // Given
    String caller = null;

    // When

    // Then
    // ( kapOOOf )

  public void sayHello_whenLocaleIsDanish_andInvoked_thenReturnsDanishGreeting() {

    // Given
    LocaleContextHolder.setLocale(new Locale("da", "DK"));
    String caller = "Duke";

    // When
    String greeting = greeterService.sayHello(caller);

    // Then
    assertThat(greeting).isEqualTo("Hej Verden, Duke");

  @Before @After
  public void resetLocaleBeforeAndAfterEachTestCase() {

From the second test case, notice that the service apparently knows how to validate the incoming parameter.
From the first and the third test cases, notice that the service is locale aware.

The @BusinessService annotation

The @BusinessService annotation is a custom “stereotype” annotation. Spring already has a bunch of stereotype annotations, including: @Service, @Controller, @Repository, and so on. But you can also add your own – as in the case of @BusinessService:

public @interface BusinessService {

The only thing that makes this annotation special is the @Component annotation. With that in place you can now use the @BusinessService annotation to declare Spring beans.

Spring Framework even allows you to meta-annotate your custom stereotype annotations with other framework annotations. For example with @SessionScope and @Transactional. If you annotate beans with such a composed annotation, then they would both be HTTP session scoped as well as transactional of nature. Consult the reference documentation for further information on that subject [1].

Enforcing @NotNull functionality

With the custom stereotype annotation in place you can now use it for something. What that “something” is, is entirely up to your imagination. But for this example I would like to ensure that @BusinesService components can benefit from automatic not-null parameter validation, by declaring @NotNull as hints. I have used Spring AOP for that in my example – it is extremely simple:

public class NotNullParameterAspect {

  public void before(JoinPoint caller) {

    Method method = getCurrentMethod(caller);

    Object[] parameters = caller.getArgs();

    Annotation[][] parameterAnnotations = method.getParameterAnnotations();

    // Throw exception if a parameter value is null AND
    // at the same time declares that it must be @NotNull
    for (int i = 0; i < parameters.length; i++) {
      Object parameterValue = parameters[i];
      Annotation[] annotationsOnParameter = parameterAnnotations[i];

      if (parameterValue == null && hasNotNullAnnotation(annotationsOnParameter)) {
        String msgTemplate = String.format("Parameter at index %s must not be null", i);
        throw new IllegalArgumentException(msgTemplate);


  private boolean hasNotNullAnnotation(Annotation... annotations) {
    return Arrays.asList(annotations).stream().
              anyMatch(a -> a.annotationType() == NotNull.class);

  private Method getCurrentMethod(JoinPoint joinPoint) {
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    return signature.getMethod();

The @Before annotation tells spring that the method should be executed before any invocation on beans that are annotated with @BusinessService. The method body, the advice, throws an IllegalArgumentException if a parameter is null and @NotNull annotated at the same time.

It’s just an example here. You could do anything in such an advice. In fact there are other types as well, including: @After, @Around, etc. Imagine what you could do with them…

Spring AOP is super powerful. I barely scratched the surface here. So if this is new to you – then check out the appropriate section in the reference documentation [2]. It can be a bit heavy – so remember to bring some dark coffee.

The custom dependency injection annotation: @LocalizedMessage

In a typical Spring application you pick between @Autowired, @Resource, @Value, @Inject when injecting a bean into another bean. But it’s super easy to create your own:

public @interface LocalizedMessage {

  String value() default "";


Take note of the @Autowired annotation. Without it, we would additionally have to specify one of the standard annotations on the injection targets as well, ie: @Autowired @LocalizedMessage Message message. Also take note of the value attribute – this is used to declare the name of the resource bundle key of interest.

Implementing the @LocalizedMessage support

In order for the Message bean to be injected it must be… well a bean. Here is how that is declared:

public class MessageConfig {

  public MessageSource messageSource() {

    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();

    return messageSource;

  @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  public Message message(InjectionPoint ip) {

    LocalizedMessage localizedMessage = AnnotationUtils
        .getAnnotation(ip.getAnnotatedElement(), LocalizedMessage.class);

    String resourceBundleKey = localizedMessage.value();

    return new Message(messageSource(), resourceBundleKey);


Notice the message factory (/producer) method. It accesses the InjectionPoint class to fetch the resource bundle key of interest (fx. “greeterservice.greeting” declared in GreeterService). With that information and a valid MessageSource it then creates the Message bean.

Note that the scope of the message bean is prototype. It is very important for this case, as it ensures that each injection of Message is a new instance. Singleton scope here would have the effect that injections of Message beans would re-use the same instance (effectively tied to the same resource bundle message – despite the annotation key values at the injection targets).

In retrospective

The title claimed “Spring 4.3: Custom annotations”. To be honest, Spring Framework have had support for custom stereotypes for a long time. Many, many years. So that’s not new. Neither is the Spring AOP support I’ve shown.

But take a look at the custom dependency injection part. The InjectionPoint class is what makes this possible – and that’s a new thing, since Spring Framework 4.3 [3]. But even this part could have been implemented back in the old days: using a BeanPostProcessor [4]. But it would be a bit messy – at least compared to a simple @Bean factory method.


[1] @Component and further stereotype annotations:

[2] Aspect Oriented Programming with Spring:

[3] Spring 4.3: Introducing the InjectionPoint:

[4] BeanPostProcessor JavaDoc:

Tagged with: , ,
Posted in Spring

Spring 4.3: Introducing the InjectionPoint class

Did you know that Spring Framework 4.3 comes with a “hidden” gem: the InjectionPoint class ?

At the time of writing this post, InjectionPoint is nowhere to be found in the Spring Framework Reference Documentation [2].

About the InjectionPoint class

The InjectionPoint class [1] is a new feature that you can use in @Bean producer methods. It is specifically useful in @Bean methods that produces prototype scoped beans. And with it, you can get detailed information about the “places” into which your beans are injected. Said in another way:

@Bean methods can now be made context aware

If you know about Contexts and Dependency Injection (CDI) – then you may have heard about such a feature before. It is in fact an “oldie” in that context.


I’ve prepared an example on GitHub – consult that for the source code in its full context. The example is based on Spring Boot 1.4 and therefore Spring Framework 4.3. Please bear with me …. in lack of a better example…

Imagine you want to inject a greeting into your GreeterService:

public class GreeterService {

  @Autowired @Greeting(language = Language.EN)
  private String greeting;

  public String sayHello(String caller) {
    return String.format("%s, %s", greeting, caller);


… here is one way you could implement it:

public class MyBeanConfig {

  public String greeting(InjectionPoint ip) {

    Greeting greeting = findAnnotation(ip.getAnnotatedElement(),

    return (Language.DA == greeting.language()) ? "Hej Verden" : "Hello World";


Notice how this @Bean method uses the InjectionPoint to get access to the annotation on the dependency injection target field (GreeterService.greeting). The Greeting annotation is some annotation I dreamt up – super simple (not even a Qualifier).

In addition to the annotations on the dependency injection target field (/method/constructor…) you can also get the class object of the containing class (GreeterService in the above example). Take a look at the JavaDoc for further information [1].

That’s it! Now, imagine what you can do with it 😉 …

Relation to scope

I propose that InjectionPoint is specifically designed to work with prototype scoped beans. You may think that’s weird – but think about it this way:

  • If you use InjectionPoint in a singleton scoped @Bean method…
  • And if you have multiple places where the bean is injected…
  • Then how would Spring know which InjectionPoint to hand to you?

You know what? I actually tested that…and it turns out I was given the first InjectionPoint. To be completely honest: that surprised me. I actually would have expected an exception from the container. But no – I just got “the first” injection target encountered by the container. Imagine what use you have of that. My best guess is: no use at all.

CDI, by the way, only allows InjectionPoints when used with the dependent scope. Please take into account that CDI’s dependent scope and Spring’s prototype scope are roughly equivalent.


[1] Spring Frameworks JavaDoc on the InjectionPoint class:

[2] Spring Framework Reference Documentation:


Tagged with: ,
Posted in Spring

Java: Custom logger factory that automatically infers the class name

In this post I show how you can declare loggers like this:

public class MyService {
    private static final Logger LOG = MyLoggerFactory.getLogger();

There is no argument to the MyLoggerFactory::getLogger method. Contrast that to the normal way to declare a logger:

public class MyService {
    private static final Logger LOG = LoggerFactory.getLogger(MyService.class);

This is business as usual. But have you ever made that silly mistake where you copy/paste a class – and then, in the new class, forget to change the argument to that logger? It can be horribly misleading when reading log files afterwards.

The custom MyLoggerFactory::getLogger method is really super simple to implement: 3 lines of meat.

UPDATE: Alternative to the custom factory

On Reddit, while announcing this post, I was made aware of a simple alternative to the custom logger factory technique described in this post:

public class MyService {
    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.Lookup.lookupClass());

That technique uses a plain standard Java SE API to get the class name – see [1]. Personally I think this is a clever technique as well!

I guess it is a matter of personal preferences to decide which logger declaration you want to use. If you still find the logger factory compelling – then read on…


I have prepared an example on GitHub – consult that to see the code in its entirety and full context. But here it goes, using SLF4j/Logback:

package com.never.that.copy.paste.mistake.again;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyLoggerFactory {

    public static Logger getLogger() {

        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

        String callersClassName = stackTrace[2].getClassName();

        return LoggerFactory.getLogger(callersClassName);

3 lines of meat. The magic number 2 represents the class calling MyLoggerFactory::getLogger. The first positions in the stackTrace array represents the invocation to the Thread::getStackTrace method as well as this MyLoggerFactory::getLogger method itself.

I chose to name the method getLogger here, so that it aligns with the underlying logging framework SLF4j/Logback.

Please note, that no code here is specific to SLF4j/Logback: So go ahead and implement a corresponding factory for your own favorite logging framework.

The example on GitHub has a very limited JUnit test that shows it works as expected:

package com.never.that.copy.paste.mistake.again;

import org.junit.Test;
import org.slf4j.Logger;

import static org.junit.Assert.assertEquals;

public class MyLoggerFactoryTests {

    public void getLogger_whenGivenNothing_thenReturnsLoggerWithCallersClassName() {

        // Given
        // ( a little bit of magic ... )

        // When
        Logger loggerOne = MyLoggerFactory.getLogger();
        Logger loggerTwo = LoggerTester.LOG;

        // Then
        assertEquals(MyLoggerFactoryTests.class.getName(), loggerOne.getName());
        assertEquals(LoggerTester.class.getName(), loggerTwo.getName());

    private static class LoggerTester {
        private static final Logger LOG = MyLoggerFactory.getLogger();


That’s all there is to it.


[1] Java SE’s MethodHandles API:

Tagged with: ,
Posted in Java SE

Spring Boot: Show all logging events for one Web request only

In this post I show how you for a single Web request can make your Spring Boot application dump all log statements on all categories (TRACE, DEBUG, INFO, WARN, ERROR). Everything – but only for the specific Web request that you care about. I show the technique using Spring Boot 1.4. 

Here’s an example. Imagine a call to:


The trace query parameter is completely unknown to the actual GreetingController. But it instructs your application to log everything related to that request:

Screen Shot 2016-08-24 at 20.50.01
With this amount of information you can go ahead and troubleshoot those hard to understand production issues! Compare that to what you will get without the trace support:

Screen Shot 2016-08-24 at 20.52.04
The best thing: once you have implemented support for the trace query parameter, you can use it on any Web request to your application: Servlets, JSP’s, SOAP endpoints, REST endpoints and so on. In fact: they don’t even know about it.

Spring Boot implementation

I have prepared a GitHub example – consult that to see all source code in its entirety and full context. 

Here is what you need to do:

  1. Create a ThreadLocal(ish) object that knows when everything should be logged
  2. Create a Web filter that manages this ThreadLocal(ish) object
  3. Hook into the logging provider so that it can use the ThreadLocal(ish) object to decide wether or not to log a logging event

Spring Boot’s default logging provider is Logback. So I have used that in this example when implementing step three. Here it goes.

Step 1 of 3: Class ThreadLoggingSupport

public class ThreadLoggingSupport {

    private static final Map<Long, Boolean> THREAD_TO_ENABLED = new HashMap<>();

    public static void logEverything(boolean enabled) {
        THREAD_TO_ENABLED.put(Thread.currentThread().getId(), enabled);

    public static boolean shouldLogEverything() {
        return Optional.ofNullable(THREAD_TO_ENABLED.get(Thread.currentThread().getId()))

    public static void cleanup() {

The purpose of this class is to allow code in the Web layer (next step) to communicate with the logging system (step 3).

(I deliberately chose not to use a ThreadLocal here: since the use of it in step 3 would have made it bind to all threads that uses Logback – and not only the Web container threads.)

Step 2 of 3: Class ThreadLoggingFilterBean

public class ThreadLoggingFilterBean extends GenericFilterBean {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            boolean logEverythingForThisRequest = "on".equalsIgnoreCase(request.getParameter("trace"));
            chain.doFilter(request, response);
        } finally {


This is an ordinary Spring GenericFilterBean. All Web requests goes through this filter. Notice how it pulls out the trace query parameter value. If it has the value on then it will tell the log system to go nuts – logging everything it receives.

Step 3 of 3: Class ThreadLoggingInitializer

public class ThreadLoggingInitializer {

    private static org.slf4j.Logger LOG = LoggerFactory.getLogger(ThreadLoggingInitializer.class);

    public void handleContextRefresh(ContextRefreshedEvent event) {
        LoggerContext loggerContext = ((Logger) LoggerFactory.getLogger("")).getLoggerContext();
        loggerContext.addTurboFilter(new TurboFilter() {
            public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
                return (ThreadLoggingSupport.shouldLogEverything()) ? FilterReply.ACCEPT : FilterReply.NEUTRAL;
        LOG.info("ThreadLogging support initialized");

This is where we enter Logback specifics: We register a global log filter (a TurboFilter) that knows when to:

  • Force the logging of a specific logging event, or
  • Ignore the specific logging event

All logging events go through this filter – so it is important to avoid putting expensive code here.

Here we simply check the ThreadLocal(ish) state and use that to decide wether the current logging event should be logged or ignored. Ignoring it here means that this filter wont interfere in the decision. For more information about Logback and its filter support, refer to the online manual [1].

Closing remarks

Here I used Web requests as an example. But you can easily apply this technique to incoming JMS messages, scheduled jobs and so on.

Also, the technique was explained using Spring Boot. But you can easily apply it to other Web frameworks as well.

Be creative – bend that spoon.


[1] Logback – Chapter 7: Filters

Tagged with: ,
Posted in Spring

Spring Boot: Sessions actuator endpoint

This post shows how you can implement a custom Spring Boot Actuator endpoint that prints information about all active HttpSessions:

Screen Shot 2016-08-22 at 22.23.45

HttpSession meta data is prefixed with @ signs: id, creation time and last accessed time. The other values are a raw dump of all the HttpSession attributes.

You can use this endpoint during development to inspect active sessions. Or you can use it on production systems when troubleshooting customer issues. Whatever you choose, make sure that you secure such an endpoint appropriately: You could expose some very sensitive data.

For an introduction to custom Spring Boot Actuator endpoints, refer to my previous post: Spring Boot: Introduce your own insight endpoints.


I have prepared a GitHub example based on Spring Boot 1.4 – find it here. Consult that to see the code in it’s entirety and full context. Here’s the main principles that makes this possible:

  • Create a class to act as a registry of all active HttpSessions
  • Create an HttpSession listener that registers and de-registers the HttpSessions
  • Create a Spring Boot Actuator endpoint that dumps the internal state of all of the HttpSessions

Step 1 of 3: Class SessionRegistry

public class SessionRegistry {

    private final Map<String, HttpSession> httpSessionMap = new ConcurrentSkipListMap<>();

    public void addSession(HttpSession httpSession) {
        this.httpSessionMap.put(httpSession.getId(), httpSession);

    public void removeSession(HttpSession httpSession) {

    public List<HttpSession> getSessions() {
        return new ArrayList<>(httpSessionMap.values());

The httpSessionMap is a concurrent version of Map: to avoid ConcurrentModificationExceptions.

Step 2 of 3: Class SessionListener

public class SessionListener implements HttpSessionListener {

    private SessionRegistry sessionRegistry;

    public void sessionCreated(HttpSessionEvent se) {

    public void sessionDestroyed(HttpSessionEvent se) {

This is a Spring’ified version of a traditional Servlet container component: HttpSessionListener. This class maintains the registry.

Step 3 of 3: Class SessionActuatorEndpoint

This is the interesting part – where we create a Spring Boot Actuator endpoint:

public class SessionsActuatorEndpoint extends AbstractMvcEndpoint {

    private SessionRegistry sessionRegistry;

    public SessionsActuatorEndpoint() {
        super("/sessions", true/*sensitive*/);

    @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public SessionStateActuatorEndpointResponse listActiveSessions() {
        return new SessionStateActuatorEndpointResponse("Active HTTP sessions", sessionRegistry.getSessions());

    @JsonPropertyOrder({"info", "numberOfActiveSessions", "sessions"})
    public static class SessionStateActuatorEndpointResponse {

        private String info;

        private int numberOfActiveSessions;

        private List<Map<String, String>> sessions;

        public SessionStateActuatorEndpointResponse(String info, List<HttpSession> httpSessions) {
            this.info = info;
            this.numberOfActiveSessions = httpSessions.size();
            this.sessions = httpSessions.stream()

        private Map<String, String> getSessionState(HttpSession httpSession) {
            Map<String, String> sessionState = new LinkedHashMap<>();
            sessionState.put("@session_id", httpSession.getId());
            sessionState.put("@session_creation_time", formatDateTime(httpSession.getCreationTime()));
            sessionState.put("@session_last_accessed_time", formatDateTime(httpSession.getLastAccessedTime()));
            for (Enumeration<String> attributeNames = httpSession.getAttributeNames(); attributeNames.hasMoreElements(); ) {
                String attributeName = attributeNames.nextElement();
                Object attributeValue = httpSession.getAttribute(attributeName);
                sessionState.put(attributeName, attributeValue instanceof String || attributeValue instanceof Number ?
                        attributeValue.toString() : ReflectionToStringBuilder.toString(attributeValue));
            return sessionState;

        private String formatDateTime(long epoch) {
            Instant instant = Instant.ofEpochMilli(epoch);
            ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
            return zonedDataTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);


The thing that makes this a Spring Boot Actuator endpoint is that it declares AbstractMvcEndpoint as its superclass. Also take note of the constructor: this is where you register the path at which this endpoint can be found (‘/sessions‘).

The inner class SessionStateActuatorEndpointResponse represents the JSON response structure. I’ve selected some meta data that I find interesting and added that in the output – prefixed with ‘@’ characters. Other than that, it simply dumps all HttpSession attributes. Notice that it uses commons ReflectionToStringBuilder for object structures other than Strings and Numbers.


Tagged with:
Posted in Spring

Spring Boot: Introduce your own insight endpoints

In this post I show how you can develop custom Spring Boot Actuator HTTP endpoints for obtaining detailed insight into your Spring Boot application’s runtime behavior.

Here’s an example:

Screen Shot 2016-08-18 at 20.28.21

The above output is simple. Yet it can be useful to have in many applications. Like the “official” Spring Boot Actuator info output.

If you don’t find this concrete example interesting, then I’m sure that you can find something in your Spring Boot applications that you would find interesting to have insight into. In fact, I recommend that you think about areas of your application that you would like to have insight into. Then provide endpoints that gives you this visibility.

When you develop a new feature, I bet you add unit tests and integration tests etc. So, while you are at it: add insight HTTP endpoints too.

Do this, so that you better understand the application’s behavior. And do it, because when your system is in production and poop hits the fan: then insight HTTP endpoints may be there to save your b…ehind.

About Spring Boot Actuator

Spring Boot Actuator offers a suite of HTTP endpoints that provide standard insight into a Spring Boot application. With them you can: show thread stacks, beans in the ApplicationContext, latest HTTP requests, information about the current application version, performance metrics and much more.

These insight “tools” are extremely useful. But:

The Spring Boot Actuator HTTP endpoints don’t know anything that’s specific about your application


You can have much more insight

The fantastic Spring Boot team has, in traditional Spring framework spirit, ensured that the actuator framework is open for extension by us. And it is very easy!

I have created an example on GitHub – ready for pull and play. Consult that for the full picture. But for your convenience – here is how I implemented the active users HTTP endpoint:

public class ActiveUsersActuatorEndpoint extends AbstractMvcEndpoint {

    private ActiveUsersService activeUsersService;

    public ActiveUsersActuatorEndpoint() {
        super("/activeusers", false /* sensitive */);

    @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public ActiveUsersResponse listActiveUsers() {
        return new ActiveUsersResponse("Active users right now", activeUsersService.listActiveUsers());

    @JsonPropertyOrder({"info", "activeUsers"})
    public static class ActiveUsersResponse {

        private String info;

        private List&lt;String&gt; activeUsers;

        public ActiveUsersResponse(String info, List&lt;String&gt; activeUsers) {
            this.info = info;
            this.activeUsers = activeUsers;


This example extends a Spring Boot Actuator specific class: AbstractMvcEndpoint. They have their own AbstractEndpoint as well – but that’s not so cool: you cannot use the flexible @RequestMapping annotation with that.

See the Spring Boot Reference Guide for further details on custom actuator endpoints [1].

Don’t use the normal Spring MVC controllers for this

Instead of registering your custom insight HTTP endpoints the Spring Boot Actuator way, you could also just expose plain Spring MVC endpoints. But that’s not a wise approach.

Here’s why:

  • You would produce a parallel insight tool framework (alongside Spring Boot Actuator). That can be confusing for new developers on the application. Also, they may wonder why you don’t just do it “the standard way” (as described in this post).
  • If you register your own insight HTTP endpoints with Spring Boot Actuator – then they “follow along” with the location of the standard actuator endpoints. This includes the root URL context and the port number. So – should you choose to expose Spring Boot Actuator on 9090 instead of 8080 – then your custom endpoints would “follow along”.


[1] Spring Boot Reference Guide: Adding custom endpoints:

Tagged with:
Posted in Spring