如何使用 Servlet Filter 来更改/重写传入 URL?

问题描述 投票:0回答:5

如何使用 Servlet 过滤器更改传入 URL

http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123

http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123


更新:根据下面BalusC的步骤,我想出了以下代码:

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() {
        //
    }
}

web.xml
中的相关条目如下所示:

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

我尝试了服务器端和客户端重定向,得到了预期的结果。成功了,谢谢 BalusC!

servlets url-rewriting servlet-filters
5个回答
296
投票
  1. 延长
    jakarta.servlet.http.HttpFilter
  2. doFilter()
    方法中,使用
    HttpServletRequest#getRequestURI()
    来抓取路径。
  3. 使用简单的
    java.lang.String
    方法,如
    substring()
    split()
    concat()
    等来提取感兴趣的部分并组成新路径。
  4. 使用
    ServletRequest#getRequestDispatcher()
    然后使用
    RequestDispatcher#forward()
    将请求/响应转发到新 URL(服务器端重定向,不会反映在浏览器地址栏中), 使用
    HttpServletResponse#sendRedirect()
    进行重定向对新 URL 的响应(客户端重定向,反映在浏览器地址栏中)。
  5. 通过 @WebFilter
    url-pattern
    /*
    上的
    /Check_License/*
     注释注册过滤器,具体取决于上下文路径。

不要忘记在代码中添加检查,如果 URL 需要更改,如果不需要,则只需调用

FilterChain#doFilter()
,否则它将在无限循环中调用自身。

或者,您也可以使用现有的第 3 方 API 来为您完成所有工作,例如 Tuckey 的 UrlRewriteFilter,它可以像使用 Apache 的

mod_rewrite
那样进行配置。


22
投票

您可以使用现成的 Url Rewrite Filter 以及如下规则:

<rule>
  <from>^/Check_License/Dir_My_App/Dir_ABC/My_Obj_([0-9]+)$</from>
  <to>/Check_License?Contact_Id=My_Obj_$1</to>
</rule>

查看示例以获取更多...示例。


10
投票

一个简单的 JSF Url Prettyfier 过滤器,基于 BalusC 的回答的步骤。过滤器将以 /ui 路径(假设您已将所有 xhtml 文件存储在那里)开头的所有请求转发到同一路径,但添加 xhtml 后缀。

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 {

    }

}

4
投票

就我而言,我使用Spring,由于某种原因

forward
不适用于我,所以我做了以下操作:

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() {}
}

确保链接修改后的请求


-1
投票

我已经检查了您的程序并进行了必要的更正。希望您的问题能够得到解决。

使用Servlet版本3.0

package mypackage;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet Filter implementation class RequestRedirectingFilter
 */
@WebFilter("/Dir_My_App/*")
public class RequestRedirectingFilter implements Filter {

    private ServletContext context;
    
    public void init(FilterConfig fConfig) throws ServletException {
        this.context = fConfig.getServletContext();
        System.out.println("RequestRedirectingFilter initialized.....................");
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException,ServletException {
        System.out.println("I am here........");
        HttpServletResponse res=(HttpServletResponse)response;
        res.sendRedirect("http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123");
        
    }

    public void destroy() {
        //we can close resources here
    }

}
 

您可以在tomcat 9中部署此程序

© www.soinside.com 2019 - 2024. All rights reserved.