Skip to main content

Spring Boot Overview

The Juneau REST servlet APIs are designed to work seamlessly with the Spring Boot framework.

See the guide: Build a REST API on Spring Boot

The only restriction is that your top-level REST resource must extend from one of the following classes:

org.apache.juneau.rest.server.springbootBasicSpringRestServlet - Basic servletBasicSpringRestServletGroup - Basic servlet group

These classes are the equivalent to the BasicRestServlet and BasicRestServletGroup except they hook into the injection framework of Spring Boot to provide resolution of beans (e.g. child resources, various configuration classes).

The org.apache.juneau.petstore.springboot package is the canonical Spring Boot sample application demonstrating Juneau REST resources including Spring @Autowired injection.

@SpringBootApplication
@Controller
public class App {

// Entry point method.
public static void main(String[] args) {
new SpringApplicationBuilder(App.class).run(args);
}

// Spring-injected message provider consumed by HelloResource.
@Bean
public HelloMessageProvider helloMessageProvider() {
return new HelloMessageProvider("Hello from Spring-injected bean!");
}

// Returns HelloResource as a Spring bean with its dependency injected via constructor.
@Bean
public HelloResource helloResource(HelloMessageProvider helloMessageProvider) {
return new HelloResource(helloMessageProvider);
}

// Returns the root router as a Spring bean so child resources resolve as Spring beans.
@Bean
public RootResources rootResources() {
return new RootResources();
}

// Registers the console's CSRF boundary on /console/* only; the /petstore API and /petstore-ui are outside it.
@Bean
public FilterRegistrationBean<PetstoreConsoleBoundary> consoleBoundary() {
var reg = new FilterRegistrationBean<>(new PetstoreConsoleBoundary());
reg.addUrlPatterns(PetstoreConsoleBoundary.URL_PATTERN);
reg.setOrder(Ordered.HIGHEST_PRECEDENCE);
reg.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.FORWARD);
return reg;
}

// Mounts the root router servlet at /*.
@Bean
public ServletRegistrationBean<Servlet> rootServlet(RootResources rootResources) {
return new ServletRegistrationBean<>(rootResources, "/*");
}
}

The consoleBoundary() bean (a FilterRegistrationBean) puts the CSRF boundary around the /console/* admin console only, with the highest precedence and on request, async, error and forward dispatches. The /petstore API and the /petstore-ui app are deliberately outside it. See the juneau-petstore tour.

The manual ServletRegistrationBean above hard-codes the mount path (/*). Juneau can instead derive the mount path from a servlet's own @Rest(paths=...) declaration — either automatically via the opt-in auto-configuration (juneau.rest.auto-register=true) or explicitly through the JuneauServletRegistrations.forServlet(...) factory helper. See REST Server — Self-Registration for the cross-runtime story.

The root resource servlet serves as a router page. It extends BasicSpringRestServletGroup so child resources resolve as Spring beans:

@Rest(
title="Juneau Petstore (Spring Boot)",
description="Apache Juneau petstore sample application running under Spring Boot.",
children={
PetstoreConsoleResource.class,
ConsoleAssetsRest.class,
PetStoreResource.class,
PetstoreUiResource.class,
HelloResource.class
}
)
public class RootResources extends BasicSpringRestServletGroup {
private static final long serialVersionUID = 1L;
}

The org.apache.juneau.petstore.springboot.HelloResource class shows an example of a child resource defined as an injected bean, demonstrating Spring @Autowired injection into a Juneau @Rest servlet:

@Rest(
path="/hello",
title="Hello (Spring injection demo)",
description="A trivial REST resource demonstrating Spring @Autowired injection of a HelloMessageProvider bean."
)
public class HelloResource extends BasicRestResource {

private final HelloMessageProvider messageProvider;

@Autowired
public HelloResource(HelloMessageProvider messageProvider) {
this.messageProvider = messageProvider;
}

@RestGet(path="/*", summary="Responds with the Spring-injected message.")
public String sayHello() {
return messageProvider.get();
}
}

The POJO serialized is a simple String, but the message is resolved from the Spring-injected HelloMessageProvider bean. Resolution works because the parent router extends BasicSpringRestServletGroup (which extends BasicSpringRestServlet, which extends SpringRestServlet), which lets child resources be Spring beans.

Choosing the right base class​

Use caseBase classNotes
Single REST resource (non-Spring)BasicRestServlet or BasicRestResourceUse when you don't need Spring bean injection
Single REST resource (Spring Boot)BasicSpringRestServletEnables @Autowired in child resources
Router page (non-Spring)BasicRestServletGroupMounts child resources
Router page (Spring Boot)BasicSpringRestServletGroupMounts child resources with Spring bean resolution

Auto-configuration and properties​

The module needs no @Import or @EnableXxx: JuneauRestAutoConfiguration (opt-in via juneau.rest.auto-register=true) and JuneauRestLoggingAutoConfiguration (on by default when Logback is present) are discovered through Spring Boot's AutoConfiguration.imports. The full class and property tables are in juneau-rest-server-springboot.

See also​