Modifying the PathParam of URI in Filter

Viewed 299

I need to modify URI path Variable. i.e. whenever I receive a request for "/api/stories/27/comments/32", it should get converted to "/api/stories/27/comments/323322X"

I have used Filters to modify the request URI using below specified methods:

@Component
public class HashIDFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        if (request.getRequestURL().toString().contains("/comments/")) {
            HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) {
                @Override
                public String getRequestURI() {
                    System.out.println("orig url:" + request.getRequestURL().toString());
                    String arr[] = request.getRequestURL().toString().split("/comments/");
                    String url = arr[0] + "/comments/" + "3442424/";// HashIdSimple.decode(arr[1]);
                    System.out.println("url:" + url);
                    return url;
                }
            };
request.getRequestDispatcher(requestWrapper.getRequestURI()).forward(request, response);
        } else {
            System.out.println("req");
            chain.doFilter(req, res);
        }
    }
}

Below specified error is reported:

{
    "timestamp": "2019-10-26T14:32:19.932+0000",
    "status": 404,
    "error": "Not Found",
    "message": "No message available",
    "path": "/api/stories/27/comments/32"
}

Instead of RequestDispatcher, I have tried with

chain.doFilter(requestWrapper, response); 

Still no luck as it is calling the API with value as 32 only i.e. previous value only.Please guide me to resolve this issue.

Expectation is that the incoming request URI should get modified in the new URI request and the corresponding API should be called.

1 Answers

Update the code to this by removing HttpServletRequestWrapper :

    @Component
    public class HashIDFilter implements Filter {
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                throws IOException, ServletException {

            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
            if (request.getRequestURL().toString().contains("/comments/")) {  
               String arr[] = request.getRequestURL().toString().split("/comments/");
               String url = arr[0] + "/comments/" + "3442424/";
               request.getRequestDispatcher(url).forward(request, response);
            } else {
                chain.doFilter(req, res);
            }
        }
    }

Add filter in the web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" 
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <filter>
        <filter-name>hashIdFilter</filter-name>
        <filter-class>package.HashIDFilter</filter-class>
    </filter>
    <filter-mapping>
           <filter-name>hashIdFilter</filter-name>
           <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

See this popular SO Question for reference.

Related