2011-02-15 10 views
10

मुझे उम्मीद है कि किसी ने पहले से ही यह लिखा है:मुझे जावा सर्वलेट फ़िल्टर कहां मिल सकता है जो आउटपुट पर रेगेक्स लागू करता है?

एक सर्वलेट फ़िल्टर जिसे नियमित अभिव्यक्ति खोज/प्रतिस्थापित पैटर्न के साथ कॉन्फ़िगर किया जा सकता है और उन्हें HTML आउटपुट पर लागू किया जा सकता है।

क्या ऐसी कोई चीज मौजूद है?

+0

वास्तव में क्या आप बदलना चाहते हैं? अनुरोध यूआरएल या प्रतिक्रिया शरीर? टकी के UrlRewriteFilter उत्कृष्ट है, लेकिन यह यूआरएल को फिर से लिखना है (जैसे कि अपाचे HTTPD के रिवाइटरूले के साथ संभव है)। प्रतिक्रिया निकाय को बदलने के लिए, आपको कार्यात्मक आवश्यकता के बारे में अधिक विशिष्ट होना होगा। ऐसा कोई फ़िल्टर दिमाग में नहीं आता है, लेकिन यह XSS को रोकने के लिए उपयोगकर्ता द्वारा नियंत्रित इनपुट को स्वच्छ करने की तरह बहुत गंध करता है। ऐसे मामले में, नौकरी के लिए रेगेक्स बिल्कुल गलत उपकरण है। – BalusC

+0

मुझे खेद है कि मैं अस्पष्ट था। मैंने यह इंगित करने के लिए प्रश्न संपादित किया है कि मैं HTML आउटपुट को संशोधित करना चाहता हूं। –

+0

एचटीएमएल आउटपुट में बिल्कुल क्या है? चूंकि एचटीएमएल को पार्स और संशोधित करने के लिए रेगेक्स का उपयोग करना बेहद खराब अभ्यास है, ऐसा कोई फ़िल्टर कभी लिखा नहीं गया था। कृपया कार्यात्मक आवश्यकता को और स्पष्ट करें। इसके लिए आपको फ़िल्टर क्यों चाहिए? क्यों न सिर्फ दृश्य पक्ष में बदलाव करें? आदि – BalusC

उत्तर

14

मैं एक नहीं मिल सकता है, तो मैं एक ने लिखा है:

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

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); 
    } 
} 

उदाहरण 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> 
+0

बहुत बढ़िया सामान, बस इसी तरह के मुद्दे को हल करने में मेरी सहायता के लिए इसका इस्तेमाल किया! – Zugwalt

+0

मैं इस तरह की त्रुटियों को रोकने के लिए out.close() से पहले out.flush() की अनुशंसा करता हूं: java.net.ProtocolException: सामग्री की लंबाई-लंबाई को पूरा नहीं किया, लिखा: '27026' बाइट्स ने कहा: '27023 बाइट्स – rudolfv

4

मुझे यकीन नहीं है कि यह क्या देख रहा है, लेकिन एक यूआरएल फिर से लिखने वाला फ़िल्टर है। यह regex का समर्थन करता है। कृपया यहां देखें http://www.tuckey.org/urlrewrite/

आशा है कि इससे मदद मिलती है।

+0

यह लाइब्रेरी न केवल आने वाले यूआरएल के पुनर्लेखन का समर्थन करता है बल्कि एचटीएमएल पेज पर लिंक का संशोधन भी करता है: http://urlrewritefilter.googlecode.com/svn/trunk/src/doc/manual/4.0/index.html#outbound -रूले अच्छा। – rwitzel

2

SiteMesh इस प्रकार के काम के लिए लोकप्रिय है।


SiteMesh एक स्टैंडअलोन परियोजना में ले जाया गया है: http://www.sitemesh.org/

संबंधित मुद्दे