Add Prefix to All Spring Boot Controllers – 为所有Spring Boot控制器添加前缀

最后修改: 2022年 3月 30日

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.

在Spring Boot应用程序中,每个控制器都可以有自己的URL映射。这使得一个应用程序可以很容易地在多个地方提供网络端点。例如,我们可以将我们的API端点分为逻辑分组,如内部和外部。

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.

然而,有时我们可能希望所有的端点都在一个共同的前缀下。在本教程中,我们将探讨为所有Spring Boot控制器使用共同前缀的不同方法。

2. Servlet Context

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:

第一种方法是引入一个新的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.

在这里,我们要创建一个ServletRegistrationBean来包装DispatcherServlet Bean。请注意,我们提供了一个明确的基础URL,即/api/这意味着我们所有的端点都必须通过这个基础URL前缀来访问

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 file:

我们也可以通过使用应用程序属性来实现同样的结果。在Spring Boot 2.0.0之后的版本中,我们要在application.properties文件中添加以下内容。


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

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



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.