I am trying to implement dynamic context path I have followed this [blog] (https://www.broadleafcommerce.com/blog/configuring-a-dynamic-context-path-in-spring-boot) I am able to achieve the required result the only issue I am facing is when I am using path variable in my controller my application returns 404.I have given below the sample code for better explanation
@Configuration
public class Config {
@Bean
public WrapRequestFilter wrapRequestFilter() {
return new WrapRequestFilter();
}
@Bean
public FilterRegistrationBean wrapRequestFilterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(wrapRequestFilter());
registrationBean.setName("wrapRequestFilter");
registrationBean.setOrder(-1000001);
return registrationBean;
}
}
Filter Class
public class WrapRequestFilter extends OncePerRequestFilter {
private static final String[] PATHS = new String[] { "/food", "/equipment" };
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException, ServletException, IOException {
ServletContextFacadeRequestWrapper wrapper = new ServletContextFacadeRequestWrapper(request);
String path = getMatchingContextPathForRequest(request);
if (path != null) {
wrapper.setContextPath(request.getContextPath() + path);
String newPath = request.getServletPath().substring(path.length());
if (newPath.length() == 0) {
newPath = "/";
}
wrapper.setServletPath(newPath);
}
filterChain.doFilter(wrapper, response);
}
public String getMatchingContextPathForRequest(HttpServletRequest request) {
for (String path : PATHS) {
if (request.getServletPath().startsWith(path)) {
return path;
}
}
return null;
}
}
Wrapper Class
public class ServletContextFacadeRequestWrapper extends HttpServletRequestWrapper {
private String contextPath;
private String servletPath;
public ServletContextFacadeRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getContextPath() {
if (StringUtils.isNotBlank(contextPath)) {
return contextPath;
}
return super.getContextPath();
}
@Override
public String getServletPath() {
if (StringUtils.isNotBlank(servletPath)) {
return servletPath;
}
return super.getServletPath();
}
@Override
public String getRequestURI() {
String requestURI = super.getRequestURI();
if (requestURI.equals(contextPath)) {
return requestURI + "/";
}
return requestURI;
}
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
public void setServletPath(String servletPath) {
this.servletPath = servletPath;
}
Controller Method 1
@RestController
public class FruitsController {
@PostMapping("/{source}/method2")
public String fruitsMethod(@PathVariable("source") String source){
return "method working";
}
}
Controller Method 2
@RestController
public class FruitsController {
@PostMapping("/method2")
public String fruitsMethod(){
return "method working";
}
}
The issue comes when I hit the given curl using path variable then except food or equipment I am able to get status as 200 with a message "method working" but If I remove path variable from my controller then I am able to get the required result that is when I add food or equipment then I am able to get 200 status with a message "method working" but if I write any other keyword other than food or equipment I am get 404.My main issue is I want to achieve the later scenario using path variable which I am not able to achieve can anyone tell me what is wrong with my code why I am not able to achieve the desired result.I want to achieve my desired result using Controller Method 1 approach
curl --location --request POST 'http://localhost:8080/food/method2'