I have simple JSF application. And trying to understand UrlRewriteFilter.
First I have URL like: http://testSite/autocomplete?action=lookup&id=45
I want to get params action and id but in the same time I need user (and google-bot) never seen this type of URL but always http://testSite/lookup/45
I make this rewriting of url but cannot send params to the servet-controller. Please help.
This is web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- URL ReWriter -->
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>AutoCompleteServlet</servlet-name>
<servlet-class>com.ajax.AutoCompleteServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AutoCompleteServlet</servlet-name>
<url-pattern>/autocomplete</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
urlrewrite.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
"http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite use-query-string="true">
<rule>
<from>/index.jsp</from>
<to type="redirect">%{context-path}/</to>
</rule>
<rule>
<from>^/autocomplete\?action=lookup&id=(.*)</from>
<!-- <run class="com.ajax.AutoCompleteServlet" method="doGet" />-->
<to type="redirect">%{context-path}/lookup/$1</to>
</rule>
<rule>
<from>^/lookup/(.*)</from>
<run class="com.ajax.AutoCompleteServlet" method="doPost">
<init-param>
<param-name>action</param-name>
<param-value>lookup</param-value>
</init-param>
<init-param>
<param-name>id</param-name>
<param-value>$1</param-value>
</init-param>
</run>
</rule>
</urlrewrite>
And Servlet:
package com.ajax;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
public class AutoCompleteServlet extends HttpServlet {
private ServletContext context;
private ComposerData compData = new ComposerData();
private HashMap composers = compData.getComposers();
@Override
public void init(ServletConfig config) throws ServletException {
this.context = config.getServletContext();
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String action = request.getParameter("action"); // Always null ???
String targetId = request.getParameter("id"); // Always null ????
}
}
That's indeed expected behavior. You're redirecting to an URL with those parameters in path info instead of query string.
You've basically 2 options:
Add a rule which performs a forward (no redirect!), see also "Clean a URL" in documentation.
<rule>
<from>^/lookup/(.*)$</from>
<to>/autocomplete?action=lookup&id=$1</to>
</rule>
Change the servlet to grab those parameters from path info instead.
String[] params = request.getPathInfo().substring(1).split("/");
String action = params[0]; // "lookup"
String id = params[1]; // "45"
// ...
Unrelated to the concrete problem, if the "dirty" URL was already published into the web beforehand and is already indexed by searchbots, you'd really better use <to type="redirect-permanent">
(HTTP 301) instead of <to type="redirect">
(HTTP 302). This will instruct the searchbots to remove the URL from the index instead of keeping as alternate URL.