In this example, we will understand how HandlerMapping works when using following method of AbstractHandlerMapping:
public void setDefaultHandler(@Nullable Object defaultHandler)
A default handler (such as a Controller instance or a handler object/method) is used for all URI requests which are not matched by any other handlers.
By default, every HandlerMapping's default handler is set to null. To make the default handler work, we have to set it to an object of a type which one of the registered HandlerAdapters can process.
Example
We are customizing the default RequestMappingHandlerMapping in this example. We are setting the default handler as an object of type HttpRequestHandler.
package com.logicbig.example;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.web.accept.ApiVersionStrategy;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.resource.ResourceUrlProvider;
@Configuration
@ComponentScan
public class AppConfig extends WebMvcConfigurationSupport {
@Bean
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping(
@Qualifier("mvcContentNegotiationManager")
ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcApiVersionStrategy") @Nullable
ApiVersionStrategy apiVersionStrategy,
@Qualifier("mvcConversionService")
FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider")
ResourceUrlProvider resourceUrlProvider) {
// Fetch the default instance constructed by Spring
RequestMappingHandlerMapping m = super.requestMappingHandlerMapping(
contentNegotiationManager,
apiVersionStrategy,
conversionService,
resourceUrlProvider
);
m.setDefaultHandler(new MyDefaultHandler());
return m;
}
}
package com.logicbig.example;
import org.springframework.web.HttpRequestHandler;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class MyDefaultHandler implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request,
HttpServletResponse response)
throws IOException {
PrintWriter writer = response.getWriter();
writer.write("response from MyDefaultHandler, uri: "
+ request.getRequestURI());
}
}
package com.logicbig.example;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ExampleController {
@RequestMapping("/example")
@ResponseBody
public String handle () {
return "response from ExampleController";
}
}
The above controller isn't strictly necessary to demonstrate the default handler settings, but we are just using it to see that the rest of our application is working as expected.
To try examples, run embedded Jetty (configured in pom.xml of example project below):
mvn jetty:run
Output
 $ curl -s "http://localhost:8080/random" response from MyDefaultHandler, uri: /random
 $ curl -s "http://localhost:8080/example" response from ExampleController
This shows that only /example is mapped to our ExampleController; the rest of the URIs are forwarded to the default handler.
Example ProjectDependencies and Technologies Used: - spring-webmvc 7.0.6 (Spring Web MVC)
Version Compatibility: 3.2.9.RELEASE - 7.0.6 Version compatibilities of spring-webmvc with this example: Versions in green have been tested.
- jakarta.servlet-api 6.1.0 (Jakarta Servlet API documentation)
- JDK 25
- Maven 3.9.11
|