UrlRewriteFilter 将参数发送到控制器

UrlRewriteFilter send params to controller

我有一个简单的 JSF 应用程序。并试图了解 UrlRewriteFilter。

首先我URL喜欢: http://testSite/autocomplete?action=lookup&id=45

我想获取参数 actionid 但同时我需要用户(和 google-bot ) 从未见过这种 URL 但总是 http://testSite/lookup/45

我重写了 url 但无法将参数发送到服务器控制器。请帮忙。

这是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&amp;id=(.*)</from>
        <!--  <run class="com.ajax.AutoCompleteServlet" method="doGet" />-->
        <to type="redirect">%{context-path}/lookup/</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></param-value>
            </init-param>
        </run>
    </rule>
</urlrewrite>

和 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 ????

    }
}

这确实是预期的行为。您正在重定向到 URL,这些参数在路径信息中而不是查询字符串中。

你基本上有 2 个选择:

  1. 添加执行转发的规则(无重定向!),另请参阅 documentation 中的 "Clean a URL"。

    <rule>
        <from>^/lookup/(.*)$</from>
        <to>/autocomplete?action=lookup&amp;id=</to>
    </rule>
    
  2. 改为从路径信息中获取这些参数。

    String[] params = request.getPathInfo().substring(1).split("/");
    String action = params[0]; // "lookup"
    String id = params[1]; // "45"
    // ...
    

与具体问题无关,如果 "dirty" URL 已经事先发布到网络上并且已经被搜索引擎收录,你会确实更好地使用 <to type="redirect-permanent"> (HTTP 301) instead of <to type="redirect"> (HTTP 302)。这将指示搜索机器人从索引中删除 URL 而不是保留 URL.