在哪里可以找到将regex应用到输出的Java Servlet过滤器?

时间:2022-12-26 16:09:19

I'm hoping someone has already written this:

我希望有人已经写过:

A servlet filter that can be configured with regular expression search/replace patterns and applies them to the HTML output.

可以使用正则表达式搜索/替换模式配置的servlet筛选器,并将它们应用到HTML输出。

Does such a thing exist?

这种东西存在吗?

3 个解决方案

#1


15  

I couldn't find one, so I wrote one:

我找不到,所以我写了一个:

RegexFilter.java

RegexFilter.java

package com.example;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

/**
 * Applies search and replace patterns. To initialize this filter, the
 * param-names should be "search1", "replace1", "search2", "replace2", etc.
 */
public final class RegexFilter implements Filter {
    private List<Pattern> searchPatterns;
    private List<String> replaceStrings;

    /**
     * Finds the search and replace strings in the configuration file. Looks for
     * matching searchX and replaceX parameters.
     */
    public void init(FilterConfig filterConfig) {
        Map<String, String> patternMap = new HashMap<String, String>();

        // Walk through the parameters to find those whose names start with
        // search
        Enumeration<String> names = (Enumeration<String>) filterConfig.getInitParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if (name.startsWith("search")) {
                patternMap.put(name.substring(6), filterConfig.getInitParameter(name));
            }
        }
        this.searchPatterns = new ArrayList<Pattern>(patternMap.size());
        this.replaceStrings = new ArrayList<String>(patternMap.size());

        // Walk through the parameters again to find the matching replace params
        names = (Enumeration<String>) filterConfig.getInitParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if (name.startsWith("replace")) {
                String searchString = patternMap.get(name.substring(7));
                if (searchString != null) {
                    this.searchPatterns.add(Pattern.compile(searchString));
                    this.replaceStrings.add(filterConfig.getInitParameter(name));
                }
            }
        }
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // Wrap the response in a wrapper so we can get at the text after calling the next filter
        PrintWriter out = response.getWriter();
        CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse) response);
        chain.doFilter(request, wrapper);

        // Extract the text from the completed servlet and apply the regexes
        String modifiedHtml = wrapper.toString();
        for (int i = 0; i < this.searchPatterns.size(); i++) {
            modifiedHtml = this.searchPatterns.get(i).matcher(modifiedHtml).replaceAll(this.replaceStrings.get(i));
        }

        // Write our modified text to the real response
        response.setContentLength(modifiedHtml.getBytes().length);
        out.write(modifiedHtml);
        out.close();
    }

    public void destroy() {
        this.searchPatterns = null;
        this.replaceStrings = null;
    }
}

CharResponseWrapper.java

CharResponseWrapper.java

package com.example;

import java.io.CharArrayWriter;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
 * Wraps the response object to capture the text written to it.
 */
public class CharResponseWrapper extends HttpServletResponseWrapper {
    private CharArrayWriter output;

    public CharResponseWrapper(HttpServletResponse response) {
        super(response);
        this.output = new CharArrayWriter();
    }

    public String toString() {
        return output.toString();
    }

    public PrintWriter getWriter() {
        return new PrintWriter(output);
    }
}

Example web.xml

示例web . xml

<web-app>
    <filter>
      <filter-name>RegexFilter</filter-name>
      <filter-class>com.example.RegexFilter</filter-class>
      <init-param><param-name>search1</param-name><param-value><![CDATA[(<\s*a\s[^>]*)(?<=\s)target\s*=\s*(?:'_parent'|"_parent"|_parent|'_top'|"_top"|_top)]]></param-value></init-param>
      <init-param><param-name>replace1</param-name><param-value>$1</param-value></init-param>
    </filter>
    <filter-mapping>
      <filter-name>RegexFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

#2


4  

I am not sure if this is what looking for, but there is a URL rewrite filter. It supports regex. Please see here http://www.tuckey.org/urlrewrite/

我不确定这是否是我想要的,但是有一个URL重写过滤器。它支持正则表达式。请在这里看到http://www.tuckey.org/urlrewrite/

Hope this helps.

希望这个有帮助。

#3


2  

SiteMesh is popular for this type of work.

SiteMesh在这类工作中很受欢迎。


SiteMesh has moved into a standalone Project: http://www.sitemesh.org/

SiteMesh已经进入了一个独立的项目:http://www.sitemesh.org/

#1


15  

I couldn't find one, so I wrote one:

我找不到,所以我写了一个:

RegexFilter.java

RegexFilter.java

package com.example;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

/**
 * Applies search and replace patterns. To initialize this filter, the
 * param-names should be "search1", "replace1", "search2", "replace2", etc.
 */
public final class RegexFilter implements Filter {
    private List<Pattern> searchPatterns;
    private List<String> replaceStrings;

    /**
     * Finds the search and replace strings in the configuration file. Looks for
     * matching searchX and replaceX parameters.
     */
    public void init(FilterConfig filterConfig) {
        Map<String, String> patternMap = new HashMap<String, String>();

        // Walk through the parameters to find those whose names start with
        // search
        Enumeration<String> names = (Enumeration<String>) filterConfig.getInitParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if (name.startsWith("search")) {
                patternMap.put(name.substring(6), filterConfig.getInitParameter(name));
            }
        }
        this.searchPatterns = new ArrayList<Pattern>(patternMap.size());
        this.replaceStrings = new ArrayList<String>(patternMap.size());

        // Walk through the parameters again to find the matching replace params
        names = (Enumeration<String>) filterConfig.getInitParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if (name.startsWith("replace")) {
                String searchString = patternMap.get(name.substring(7));
                if (searchString != null) {
                    this.searchPatterns.add(Pattern.compile(searchString));
                    this.replaceStrings.add(filterConfig.getInitParameter(name));
                }
            }
        }
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // Wrap the response in a wrapper so we can get at the text after calling the next filter
        PrintWriter out = response.getWriter();
        CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse) response);
        chain.doFilter(request, wrapper);

        // Extract the text from the completed servlet and apply the regexes
        String modifiedHtml = wrapper.toString();
        for (int i = 0; i < this.searchPatterns.size(); i++) {
            modifiedHtml = this.searchPatterns.get(i).matcher(modifiedHtml).replaceAll(this.replaceStrings.get(i));
        }

        // Write our modified text to the real response
        response.setContentLength(modifiedHtml.getBytes().length);
        out.write(modifiedHtml);
        out.close();
    }

    public void destroy() {
        this.searchPatterns = null;
        this.replaceStrings = null;
    }
}

CharResponseWrapper.java

CharResponseWrapper.java

package com.example;

import java.io.CharArrayWriter;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
 * Wraps the response object to capture the text written to it.
 */
public class CharResponseWrapper extends HttpServletResponseWrapper {
    private CharArrayWriter output;

    public CharResponseWrapper(HttpServletResponse response) {
        super(response);
        this.output = new CharArrayWriter();
    }

    public String toString() {
        return output.toString();
    }

    public PrintWriter getWriter() {
        return new PrintWriter(output);
    }
}

Example web.xml

示例web . xml

<web-app>
    <filter>
      <filter-name>RegexFilter</filter-name>
      <filter-class>com.example.RegexFilter</filter-class>
      <init-param><param-name>search1</param-name><param-value><![CDATA[(<\s*a\s[^>]*)(?<=\s)target\s*=\s*(?:'_parent'|"_parent"|_parent|'_top'|"_top"|_top)]]></param-value></init-param>
      <init-param><param-name>replace1</param-name><param-value>$1</param-value></init-param>
    </filter>
    <filter-mapping>
      <filter-name>RegexFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

#2


4  

I am not sure if this is what looking for, but there is a URL rewrite filter. It supports regex. Please see here http://www.tuckey.org/urlrewrite/

我不确定这是否是我想要的,但是有一个URL重写过滤器。它支持正则表达式。请在这里看到http://www.tuckey.org/urlrewrite/

Hope this helps.

希望这个有帮助。

#3


2  

SiteMesh is popular for this type of work.

SiteMesh在这类工作中很受欢迎。


SiteMesh has moved into a standalone Project: http://www.sitemesh.org/

SiteMesh已经进入了一个独立的项目:http://www.sitemesh.org/