eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

1. Introduction

In Spring MVC, the DispatcherServlet acts as front controller – receiving all incoming HTTP requests and processing them.

Simply put, the processing occurs by passing the requests to the relevant component with the help of handler mappings.

HandlerMapping is an interface that defines a mapping between requests and handler objects. While Spring MVC framework provides some ready-made implementations, the interface can be implemented by developers to provide customized mapping strategy.

This article discusses some of the implementations provided by Spring MVC namely BeanNameUrlHandlerMapping, SimpleUrlHandlerMapping, ControllerClassNameHandlerMapping, their configuration, and the differences between them.

2. BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping is the default HandlerMapping implementation. BeanNameUrlHandlerMapping maps request URLs to beans with the same name.

This particular mapping has support for direct name matching and also for pattern matching using the “*” pattern.

For example, an incoming URL “/foo” maps to a bean called “/foo”. An example of pattern mapping is mapping requests to “/foo*” to beans with names starting with “/foo” like “/foo2/” or “/fooOne/”.

Let’s configure this example here and register a bean controller that handles requests to “/beanNameUrl”:

@Configuration
public class BeanNameUrlHandlerMappingConfig {
    @Bean
    BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() {
        return new BeanNameUrlHandlerMapping();
    }

    @Bean("/beanNameUrl")
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

This is the XML equivalent of the above Java based config:

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<bean name="/beanNameUrl" class="com.baeldung.WelcomeController" />

It’s important to note that in both of these configurations, defining a bean for BeanNameUrlHandlerMapping is not required as it is provided by Spring MVC. Removing this bean definition will cause no problems and requests will still be mapped to their registered handler beans.

Now all requests to “/beanNameUrl” will be forwarded by DispatcherServlet to “WelcomeController“. WelcomeController returns a view name called “welcome“.

The following code tests this configuration and makes sure that the correct view name is returned:

public class BeanNameMappingConfigTest {
    // ...

    @Test
    public void whenBeanNameMapping_thenMappedOK() {
        mockMvc.perform(get("/beanNameUrl"))
          .andExpect(status().isOk())
          .andExpect(view().name("welcome"));
    }
}

3. SimpleUrlHandlerMapping

Next, the SimpleUrlHandlerMapping is the most flexible HandlerMapping implementation. It allows for direct and declarative mapping between either bean instances and URLs or between bean names and URLs.

Let’s map requests “/simpleUrlWelcome” and “/*/simpleUrlWelcome” to the “welcome” bean:

@Configuration
public class SimpleUrlHandlerMappingConfig {

    @Bean
    public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
        SimpleUrlHandlerMapping simpleUrlHandlerMapping
          = new SimpleUrlHandlerMapping();
        
        Map<String, Object> urlMap = new HashMap<>();
        urlMap.put("/simpleUrlWelcome", welcome());
        simpleUrlHandlerMapping.setUrlMap(urlMap);
        
        return simpleUrlHandlerMapping;
    }

    @Bean
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

Alternatively, here’s the equivalent XML configuration:

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /simpleUrlWelcome=welcome
            /*/simpleUrlWelcome=welcome
        </value>
    </property>
</bean>
<bean id="welcome" class="com.baeldung.WelcomeController" />

It’s important to note that in the XML configuration, a mapping between “<value>” tag must be done in a form accepted by java.util.Properties class and it should follow the syntax: path= Handler_Bean_Name.

The URL should normally be with a leading slash, however, if the path doesn’t begin with one, Spring MVC adds it automatically.

A different way to configure the above example in XML is to use the “props” property instead of “value”. Props have a list of “prop” tag where each defines a mapping where “key” referred to the mapped URL and the value of the tag is the name of the bean.

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/simpleUrlWelcome">welcome</prop>
            <prop key="/*/simpleUrlWelcome">welcome</prop>
        </props>
    </property>
</bean>

The following test case makes sure that requests to “/simpleUrlWelcome” is handled by “WelcomeController” which returns a view name called “welcome” :

public class SimpleUrlMappingConfigTest {
    // ...

    @Test
    public void whenSimpleUrlMapping_thenMappedOK() {
        mockMvc.perform(get("/simpleUrlWelcome"))
          .andExpect(status().isOk())
          .andExpect(view().name("welcome"));
    }
}

4. ControllerClassNameHandlerMapping (removed in Spring 5)

The ControllerClassNameHandlerMapping maps URL to a registered controller bean (or a controller annotated with the @Controller annotation) that has, or starts with, the same name.

It can be more convenient in many scenarios especially for simple controller implementations that handle a single request type. The convention used by Spring MVC is to use the name of the class and remove the “Controller” suffix, then change the name to a lower case and return it as the mapping with a leading “/”.

For example “WelcomeController” would return as mapping to “/welcome*”, i.e. to any URL that starts with “welcome”.

Let’s configure ControllerClassNameHandlerMapping:

@Configuration
public class ControllerClassNameHandlerMappingConfig {

    @Bean
    public ControllerClassNameHandlerMapping controllerClassNameHandlerMapping() {
        return new ControllerClassNameHandlerMapping();
    }

    @Bean
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

Note that ControllerClassNameHandlerMapping is deprecated from Spring 4.3 in favor of annotation driven handler methods.

Another important note is that controller names will always be returned in lowercase (minus the “Controller” suffix). So if we have a controller called “WelcomeBaeldungController“, it will only handle requests to “/welcomebaeldung” and not to “/welcomeBaeldung”.

In both Java config and XML config below, we define ControllerClassNameHandlerMapping bean and register beans for the controllers that we will use to handle requests. We also register a bean of type “WelcomeController” and that bean will handle all requests that start with “/welcome”.

Here’s the equivalent XML configuration:

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
<bean class="com.baeldung.WelcomeController" />

When using the above configuration, requests to “/welcome” will be handled by the “WelcomeController“.

The following code will make sure that requests to “/welcome*” such as “/welcometest” is handled by “WelcomeController” which returns a view name called “welcome“:

public class ControllerClassNameHandlerMappingTest {
    // ...

    @Test
    public void whenControllerClassNameMapping_thenMappedOK() {
        mockMvc.perform(get("/welcometest"))
          .andExpect(status().isOk())
          .andExpect(view().name("welcome"));
    }
}

5. Configuring Priorities

Spring MVC framework allows more than one implementation of HandlerMapping interface at the same time.

Let us create a configuration and register two controllers, both mapped to URL “/welcome”, only using different mapping and returning different view names:

@Configuration
public class HandlerMappingDefaultConfig {

    @Bean("/welcome")
    public BeanNameHandlerMappingController beanNameHandlerMapping() {
        return new BeanNameHandlerMappingController();
    }

    @Bean
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

With no explicit handler mapper registered, a default BeanNameHandlerMapping will be used. Let us assert this behaviour with the test:

@Test
public void whenConfiguringPriorities_thenMappedOK() {
    mockMvc.perform(get("/welcome"))
      .andExpect(status().isOk())
      .andExpect(view().name("bean-name-handler-mapping"));
}

If we explicitly register a different handler mapper, the default mapper will be overridden. However, it is interesting to see what happens when two mappers are explicitly registered:

@Configuration
public class HandlerMappingPrioritiesConfig {

    @Bean
    BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() {
        BeanNameUrlHandlerMapping beanNameUrlHandlerMapping 
          = new BeanNameUrlHandlerMapping();
        return beanNameUrlHandlerMapping;
    }

    @Bean
    public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
        SimpleUrlHandlerMapping simpleUrlHandlerMapping
          = new SimpleUrlHandlerMapping();
        Map<String, Object> urlMap = new HashMap<>();
        urlMap.put("/welcome", simpleUrlMapping());
        simpleUrlHandlerMapping.setUrlMap(urlMap);
        return simpleUrlHandlerMapping;
    }

    @Bean
    public SimpleUrlMappingController simpleUrlMapping() {
        return new SimpleUrlMappingController();
    }

    @Bean("/welcome")
    public BeanNameHandlerMappingController beanNameHandlerMapping() {
        return new BeanNameHandlerMappingController();
    }
}

To get the control over which mapping is used, the priorities are set using setOrder(int order) method. This method takes one int parameter where lower value mean higher priority.

In XML configuration you can configure priorities by using a property called “order”:

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="order" value="2" />
</bean>

Let us add order properties to handler mapping beans, via following beanNameUrlHandlerMapping.setOrder(1) and simpleUrlHandlerMapping.setOrder(0). The lower value of the order property reflects higher precedence. Let us assert new behaviour with the test:

@Test
public void whenConfiguringPriorities_thenMappedOK() {
    mockMvc.perform(get("/welcome"))
      .andExpect(status().isOk())
      .andExpect(view().name("simple-url-handler-mapping"));
}

When testing the above configuration, you see that requests to “/welcome” will be handled by SimpleUrlHandlerMapping bean which calls a SimpleUrlHandlerController and returns simple-url-handler-mapping view. We can easily configure the BeanNameHandlerMapping to take precedence by adjusting accordingly the values of order property.

6. Conclusion

In this article we discussed how URL mapping are handled in Spring MVC framework by exploring the different implementations in the framework.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)