Filter out / remove extension from spring rest api

113 views Asked by At

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.

0

There are 0 answers