I had to upgrade the dependencies of a project from:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/>
</parent>
To the version 3.0.0 and traslated web.xml configuration to java code.
One of them is this:
<servlet-mapping>
<servlet-name>ServletName</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
That was translated into java code like this:
@Configuration
@Slf4j
public class MyServlet implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
ServletRegistration.Dynamic servlet = servletContext.addServlet("ServletName",
new DispatcherServlet(new AnnotationConfigWebApplicationContext()));
servlet.setLoadOnStartup(1);
servlet.setAsyncSupported(true);
servlet.addMapping("*.do");
}
But when I call this api:
POST /api/private/smartphone.do
Mapped with this code:
@PostMapping(value = "/private/{type}", produces = MediaType.APPLICATION_JSON_VALUE)
public JsonResponse getSmartphones(@PathVariable SType type) { ... }
The ".do" is not removed and type is equal "smartphone.do" which is not the desired result because SType is an enum like this:
public enum SType {
smartphone("smartphone"), laptop("laptop"), appliances("appliances");
private String name;
SType (String name) {
this.name = name;
}
public String get() {
return name;
}
}
I've made a few attempts:
implements WebMvcConfigurer
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setPathMatcher(new CustomPathMatcher());
}
private static class CustomPathMatcher extends AntPathMatcher {
@Override
public boolean match(String pattern, String path) {
if (path.endsWith(".do")) {
path = path.substring(0, path.length() - 3);
}
return super.match(pattern, path);
}
}
extends HttpServlet
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
var req = request.getRequestURI();
if(req.endsWith(".do")) {
request.getRequestDispatcher(req.substring(0, req.length() - 3));
}
}
Beans
@Bean
public HandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();
mapping.setUseSuffixPatternMatch(false);
return mapping;
}
update 1
Adding an interceptor seem to resolve the problem.
public class ExtensionInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws Exception {
String path = request.getRequestURI();
if (path.endsWith(".do")) {
String newPath = path.substring(0, path.length() - 3);
request.getRequestDispatcher(newPath).forward(request, response);
return false;
}
return true;
}
}
implements WebMvcConfigurer
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ExtensionInterceptor()).addPathPatterns("/private/**");
}
update 2
@PostMapping("/private/{type}.do")
Seems to do the job.