Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:


November Discount Launch 2022 – TEMP TOP (NPI)
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:


Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

1. Introduction

In Spring Boot applications, every controller can have its own URL mapping. This makes it easy for a single application to provide web endpoints at multiple locations. For example, we can group our API endpoints into logical groupings such as internal and external.

However, there may be times when we want all of our endpoints under a common prefix. In this tutorial, we'll look at different ways to use a common prefix for all Spring Boot controllers.

2. Servlet Context

The main component responsible for handling web requests in Spring applications is the DispatcherServlet. By customizing this component, we have a fair amount of control over how requests are routed.

Let's take a look at two different ways to customize the DispatcherServlet that will make all of our application endpoints available at a common URL prefix.

2.1. Spring Bean

The first way is by introducing a new Spring bean:

public class DispatcherServletCustomConfiguration {

    public DispatcherServlet dispatcherServlet() {
        return new DispatcherServlet();

    public ServletRegistrationBean dispatcherServletRegistration() {
        ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet(), "/api/");
        return registration;

Here, we're creating a ServletRegistrationBean that wraps the DispatcherServlet bean. Notice that we provide an explicit base URL of /api/. This means all of our endpoints must be accessed at that base URL prefix.

2.2. Application Properties

We can also achieve the same result just by using application properties. In versions of Spring Boot after 2.0.0, we would add the following to our application.properties file:


Prior to that version, the property name is slightly different:


One benefit of this approach is that it only uses normal Spring properties. This means we can easily change or override our common prefix using standard mechanisms like profiles or external property bindings.

2.3. Pros and Cons

The main benefit of these two approaches is also the main downside: They affect every endpoint in the application.

For some applications, this may be perfectly fine. However, some applications may need to use standard endpoint mappings to interact with third-party services – for example, OAuth exchanges. In these cases, a global solution like this may not be a good fit.

3. Annotations

Another way we can add a prefix to all of the controllers in a Spring application is using annotations. Below, we'll look at two different approaches.

3.1. SpEL

The first way involves using Spring Expression Language (SpEL) with the standard @RequestMapping annotation. With this approach, we simply add a property to each controller that we want to prefix:

@RequestMapping(path = "${apiPrefix}/users")
public class UserController {


Then, we simply specify the property value in our application.properties:


3.2. Custom Annotation

Another way to achieve this is by creating our own annotation:

public @interface ApiPrefixController {
    @AliasFor(annotation = Component.class)
    String value() default "";

Then, we only need to apply the annotation to each controller we want to prefix:

public class SomeController {
    public String getAll(){
        // ...

3.3. Pros and Cons

These two approaches address the main concern of the previous method: They both offer fine-grained control over which controllers get the prefix. We can apply the annotations to specific controllers only, rather than impacting all endpoints in the application.

4. Server-Side Forward

One final way we will look at is using a server-side forward. Unlike a redirect, a forward does not involve a response back to the client. This means our application can pass requests between endpoints without affecting the client.

To get started, let's write a simple controller with two endpoints:

class EndpointController {
    public String endpoint1() {
        return "Hello from endpoint 1";

    public String endpoint2() {
        return "Hello from endpoint 2";

Next, we create a new controller that is based on the prefix we want:

public class ApiPrefixController {

    public ModelAndView route(ModelMap model) {
        if(new Random().nextBoolean()) {
            return new ModelAndView("forward:/endpoint1", model);
        else {
            return new ModelAndView("forward:/endpoint2", model);

This controller has a single endpoint that acts as a router. In this case, it essentially flips a coin to forward the original request to one of our other two endpoints.

We can verify it's working by sending a few consecutive requests:

> curl http://localhost:8080/api/endpoint
Hello from endpoint 2
> curl http://localhost:8080/api/endpoint
Hello from endpoint 1
> curl http://localhost:8080/api/endpoint
Hello from endpoint 1
> curl http://localhost:8080/api/endpoint
Hello from endpoint 2
> curl http://localhost:8080/api/endpoint
Hello from endpoint 2

The main benefit of this approach is that it is very powerful. We can apply any logic we want to determine how to forward a request: URL path, HTTP method, HTTP headers, and so on.

5. Conclusion

In this article, we've learned several ways to apply a common prefix to every controller in a Spring application. As with most decisions, each approach comes with pros and cons that should be carefully considered before implementation.

As always, the code examples in this tutorial can be found over on GitHub.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:


Generic footer banner
1 Comment
Inline Feedbacks
View all comments
Comments are closed on this article!