Reputation: 31090
How can I use a Servlet Filter to change an incoming URL from
http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123
to
http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123
?
Update: according to BalusC's steps below, I came up with the following code:
public class UrlRewriteFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
//
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
String requestURI = request.getRequestURI();
if (requestURI.startsWith("/Check_License/Dir_My_App/")) {
String toReplace = requestURI.substring(requestURI.indexOf("/Dir_My_App"), requestURI.lastIndexOf("/") + 1);
String newURI = requestURI.replace(toReplace, "?Contact_Id=");
req.getRequestDispatcher(newURI).forward(req, res);
} else {
chain.doFilter(req, res);
}
}
@Override
public void destroy() {
//
}
}
The relevant entry in web.xml
look like this:
<filter>
<filter-name>urlRewriteFilter</filter-name>
<filter-class>com.example.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>urlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I tried both server-side and client-side redirect with the expected results. It worked, thanks BalusC!
Upvotes: 205
Views: 250020
Reputation: 22
URL rewiting in Filter can be done in two ways.
(1) Client side URL redirection by using HttpServletResponse#sendRedirect(...........) // ..... means String where to redirect.
(2) Server side URL redirection by using HttpServletRequest#getRequestDispatcher.forward(request,response)
Client side redirection is little bit comlicated because you have to keep in mind that redirected url should not match with the Filter mapping. If redirectedurl match with with Filter mapping then the Filter will repeatedly send redirection url and it will fall in infinite loop. Therefore you will never get response.
Server side redirection is little bit safer because server sends URL to some other server, outside hackerwill not do anything. Threfore you may use Serverside redirection in Filter.
Upvotes: -1
Reputation: 1109532
jakarta.servlet.http.HttpFilter
.doFilter()
method, use HttpServletRequest#getRequestURI()
to grab the path.java.lang.String
methods like substring()
, split()
, concat()
and so on to extract the part of interest and compose the new path.ServletRequest#getRequestDispatcher()
and then RequestDispatcher#forward()
to forward the request/response to the new URL (server-side redirect, not reflected in browser address bar), or use HttpServletResponse#sendRedirect()
to redirect the response to the new URL (client side redirect, reflected in browser address bar).@WebFilter
annotation on an url-pattern
of /*
or /Check_License/*
, depending on the context path.Don't forget to add a check in the code if the URL needs to be changed and if not, then just call FilterChain#doFilter()
, else it will call itself in an infinite loop.
Alternatively you can also just use an existing 3rd party API to do all the work for you, such as Tuckey's UrlRewriteFilter which can be configured the way as you would do with Apache's mod_rewrite
.
Upvotes: 297
Reputation: 5071
In my case, I use Spring and for some reason forward
did not work with me, So I did the following:
public class OldApiVersionFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (httpServletRequest.getRequestURI().contains("/api/v3/")) {
HttpServletRequest modifiedRequest = new HttpServletRequestWrapper((httpServletRequest)) {
@Override
public String getRequestURI() {
return httpServletRequest.getRequestURI().replaceAll("/api/v3/", "/api/");
}
};
chain.doFilter(modifiedRequest, response);
} else {
chain.doFilter(request, response);
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void destroy() {}
}
Make sure you chain the modifiedRequest
Upvotes: 5
Reputation: 31679
A simple JSF Url Prettyfier filter based in the steps of BalusC's answer. The filter forwards all the requests starting with the /ui path (supposing you've got all your xhtml files stored there) to the same path, but adding the xhtml suffix.
public class UrlPrettyfierFilter implements Filter {
private static final String JSF_VIEW_ROOT_PATH = "/ui";
private static final String JSF_VIEW_SUFFIX = ".xhtml";
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = ((HttpServletRequest) request);
String requestURI = httpServletRequest.getRequestURI();
//Only process the paths starting with /ui, so as other requests get unprocessed.
//You can register the filter itself for /ui/* only, too
if (requestURI.startsWith(JSF_VIEW_ROOT_PATH)
&& !requestURI.contains(JSF_VIEW_SUFFIX)) {
request.getRequestDispatcher(requestURI.concat(JSF_VIEW_SUFFIX))
.forward(request,response);
} else {
chain.doFilter(httpServletRequest, response);
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
Upvotes: 10
Reputation: 570595
You could use the ready to use Url Rewrite Filter with a rule like this one:
<rule>
<from>^/Check_License/Dir_My_App/Dir_ABC/My_Obj_([0-9]+)$</from>
<to>/Check_License?Contact_Id=My_Obj_$1</to>
</rule>
Check the Examples for more... examples.
Upvotes: 22