English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

مناقشة مختصرة لـ Filter في Java

مقدمة لـ Filter

يُسمى Filter أيضًا بـمُرشح، وهو تقنية أكثر استخدامه في تقنية Servlet، حيث يمكن للمطورين من خلال تقنية Filter، تمرير كل الموارد التي يديرها خادم الويب: مثل Jsp، Servlet، ملفات الصور الثابتة أو ملفات html الثابتة، وغيرها من الموارد، لتحقيق بعض الوظائف الخاصة. مثل تحقيق التحكم في الوصول على مستوى URL، مرشح الكلمات الحساسة، ضغط معلومات الاستجابة، وغيرها من الوظائف المتقدمة.

يُستخدم بشكل رئيسي لمعالجة مسبقة طلبات المستخدم، كما يمكنه معالجة HttpServletResponse بعدة طرق. عملية استخدام Filter بشكل كامل: يقوم Filter بمعالجة مسبقة طلب المستخدم، ثم يمرر الطلب إلى Servlet لمعالجته ويقوم بإنشاء استجابة، وأخيرًا يقوم Filter بمعالجة استجابة الخادم.

وظيفة Filter

استخدام Filter لمنع وصول HttpServletRequest إلى Servlet قبل وصوله إلى Servlet، يمكن التحقق من HttpServletRequest حسب الحاجة وتعديل رؤوس HttpServletRequest وبياناتها.

استخدام Filter لمنع وصول HttpServletResponse إلى العميل قبل وصوله إلى العميل، يمكن التحقق من HttpServletResponse حسب الحاجة وتعديل رؤوس HttpServletResponse وبياناتها.

كيفية استخدام Filter لتحقيق التحقق

يوجد طريقة doFilter في واجهة Filter، عند كتابة Filter وتحديد الموارد التي يتحكم فيها المُرشح، سيُطلق الخادم الويب على طريقة doFilter للمُرشح في كل مرة يُطلق على طريقة service لموارد الويب، لذا يمكن كتابة الكود في هذه الطريقة لتحقيق الغرض التالي:

تفيذ قطعة من الكود قبل الوصول إلى الموارد المستهدفة.

إذا كان يجب الوصول إلى الموارد المستهدفة (أي إذا كان يجب السماح للمستخدمين بالوصول إلى موارد الويب).

عندما يُطلق على طريقة doFilter، يُنقل كائن filterChain إلى الخادم الويب، كائن filterChain هو أكثر كائن في واجهة filter، ويعطي أيضًا طريقة doFilter، يمكن للمطورين اتخاذ قرار حول ما إذا كان يجب تفعيل هذه الطريقة أم لا، إذا تم تفعيل هذه الطريقة، فإن الخادم الويب سيُطلق على طريقة service لموارد الويب، أي أن يتم الوصول إلى موارد الويب، وإلا فإن موارد الويب لن يتم الوصول إليها.

خطوتين لتحقيق تطوير Filter

كتابة فئة java لتحقيق واجهة Filter و تنفيذ طريقة doFilter.

 يتم تسجيل الفئات التي تم كتابتها في ملف web.xml وتعيين الموارد التي يمكن أن يتحكم فيها المُرشح.

شرح لكل عناصر web.xml

  • <filter> يحدد مُرشحًا.
  • يستخدم <filter-name> لتعيين اسم للمُرشح، ولا يمكن أن يكون محتوى هذا العنصر فارغًا.
  • يستخدم عناصر <filter-class> لتعيين اسم الكائن الكامل المحدد للمُرشح.
  • يستخدم عناصر <init-param> لتعيين معلمات التحسين للمُرشح، حيث يحدد عناصر <param-name> اسم المعلمة و <param-value> يحدد قيمتها.
  • في المُرشح، يمكن استخدام كائن واجهة FilterConfig للوصول إلى معلمات التحسين.
  • عنصر <filter-mapping> يستخدم لتعيين الموارد التي يتحكم فيها المُرشح. يمكن تحديد الموارد التي يتحكم فيها المُرشح بطرقين: اسم servlet و مسار طلب الوصول إلى الموارد
  • <filter-name> يُستخدم لتحديد اسم التسجيل للفلتر. يجب أن يكون هذا القيمة هي اسم الفلتر الذي تم إعلانه في عنصر <filter>}
  • <url-pattern> يحدد مسار الطلب الذي يتم تمريره إلى Filter (نمط URL المرتبط بالفلتر)
  • <servlet-name> يحدد اسم Servlet الذي يتم تمريره إلى Filter.
  • <dispatcher> يحدد كيفية استدعاء Servlet من قبل Servlet Container التي يتم تمريرها إلى Filter، ويمكن أن تكون REQUEST،INCLUDE،FORWARD أو ERROR واحدة، ويكون الافتراضي REQUEST. يمكن للمستخدم تعيين عدة عناصر <dispatcher> لتعيين طرق متعددة لتمرير Filter إلى الموارد.
  • القيم التي يمكن تعيينها لـ <dispatcher> ومدلولاتها
  • طلب: عند زيارة المستخدم للصفحة مباشرةً، سيقوم خادم الويب بتشغيل الفلتر. إذا تم الوصول إلى المصدر المستهدف من خلال طريقة include() أو forward() لمدير الطلبات، فإن الفلتر لن يتم استدعاؤه.
  • تضمين: إذا تم الوصول إلى المصدر المستهدف من خلال طريقة include() لمدير الطلبات، فإن هذا الفلتر سيتم استدعاؤه. بالإضافة إلى ذلك، لن يتم استدعاء الفلتر.
  • تحويل: إذا تم الوصول إلى المصدر المستهدف من خلال طريقة forward() لمدير الطلبات، فإن هذا الفلتر سيتم استدعاؤه، بالإضافة إلى ذلك، لن يتم استدعاء الفلتر.
  • خطأ: إذا تم استدعاء المصدر المستهدف من خلال ميكانيكية معالجة الاستثناءات المعلن عنها، فإن هذا الفلتر سيتم استدعاؤه. بالإضافة إلى ذلك، لن يتم استدعاء الفلتر.

سلسلة Filter

في تطبيق ويب، يمكن تطوير كتابة عدة Filter، وتُدعى هذه الفلترات معًا Filter Chain.

يقرر الخادم الويب ترتيب Filter في ملف web.xml، لتحديد أي Filter يتم استدعاؤه أولاً، وعند استدعاء طريقة doFilter الأولى، يخلق الخادم الويب كائن FilterChain يمثل سلسلة Filter ويقوم بتوصيله إلى هذه الطريقة. إذا قام المطور بالتقديم على طريقة doFilter لكائن FilterChain، فإن الخادم الويب سيقوم بالتحقق مما إذا كان هناك filter آخر في كائن FilterChain، إذا كان موجودًا، فإنه سيقوم بتشغيل الفلتر الثاني، وإذا لم يكن موجودًا، فإنه سيقوم بتشغيل المصدر المستهدف.

حياة Filter

public void init(FilterConfig filterConfig) throws ServletException;//初始化

مثل Servlet برنامج نكتب، يتم إنشاء وتدمير Filter بواسطة خادم الويب. عند بدء تطبيق الويب، سيقوم خادم الويب بإنشاء نموذج Filter، واستدعاء نهج init، قراءة تكوين web.xml، وإكمال وظيفة التكوين للنموذج، مما يجعل استعداد التحقق للمستخدمين اللاحقين (سيتم إنشاء نموذج filter مرة واحدة فقط، وسيتم تنفيذ نهج init مرة واحدة فقط). يمكن للمطورين الحصول على نموذج FilterConfig الذي يمثل معلومات تكوين filter من خلال نهج init.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException; // حجب الطلب

يؤدي هذا النهج إلى عملية التحقق الفعلية. عند طلب العميل الوصول إلى URL المرتبطة بالفيلتر، يتم تنفيذ Servlet Filter قبل تنفيذ نهج doFilter. يتم استخدام معامل FilterChain للوصول إلى الفلاتر التالية.

public void destroy(); // تدمير

بعد إنشاء نموذج Filter، سيبقى في ذاكرة النظام، يتم تدميره عند إزالة تطبيق الويب أو إيقاف الخادم. يتم استدعاء هذا النهج قبل تفريغ نموذج Filter من قبل حاوية الويب. يتم تنفيذ هذا النهج مرة واحدة فقط في حياة Filter. يمكن في هذا النهج إطلاق موارد المستخدم للفيلتر.

واجهة FilterConfig

يمكن للمستخدم عند تكوين الفيلتر استخدام تكوين بعض المعلمات التأسيسية للفيلتر، عند تفاعل حاوية الويب بإنشاء نموذج Filter، يتم تمرير نموذج filterConfig الذي يحتوي على معلمات التأسيسية للفيلتر. لذلك، يمكن للمطورين عند كتابة filter الحصول على ما يلي من خلال طريقة نموذج filterConfig:

String getFilterName(); // الحصول على اسم الفيلتر. 
String getInitParameter(String name); // عودة قيمة المعلمة التأسيسية المحددة باسمها في وصف التركيب. إذا لم تكن موجودة، يتم عودة null. 
Enumeration getInitParameterNames(); // عودة مجموعة المجموعات التي تحتوي على أسماء جميع المعلمات التأسيسية للفيلتر. 
public ServletContext getServletContext(); // عودة مرجع ServletContext.

مثال على استخدام Filter

استخدام Filter لتحقق من أمان تسجيل الدخول للمستخدم

في الأيام القديمة، شاركت في صيانة مشروع، بعد مغادرة المستخدم لنظام، إذا كنت تزور العناوين السابقة في شريط العناوين، بناءً على URL، يمكنك ما زلت الوصول إلى صفحة الاستجابة للنظام. ذهبت لتحقق من ذلك ووجدت أن لم يتم التحقق من تصحيح تسجيل الدخول للطلبات. أضفت filter لحل المشكلة!}

أولاً، قم بتهيئة web.xml

<filter>
  <filter-name>SessionFilter</filter-name>
  <filter-class>com.action.login.SessionFilter</filter-class>
  <init-param>
    <param-name>logonStrings</param-name><!-- لا تنشط التحقق للصفحات الخاصة بالدخول -->
    <param-value>/project/index.jsp;login.do</param-value>
  </init-param>
  <init-param>
    <param-name>includeStrings</param-name><!-- تنشيط التحقق فقط للسلاسل المحددة بعد الفلتر -->
    <param-value>.do;.jsp</param-value>
  </init-param>
  <init-param>
    <param-name>redirectPath</param-name><!-- لم يتم التحقق من الدخول، انتقل إلى صفحة الدخول -->
    <param-value>/index.jsp</param-value>
  </init-param>
  <init-param>
    <param-name>disabletestfilter</param-name><!-- Y: تنشيط الفلتر -->
    <param-value>N</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>SessionFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

ثم قم بكتابة FilterServlet

باكجيت com.action.login;
استيراد java.io.IOException;
استيراد javax.servlet.Filter;
استيراد javax.servlet.FilterChain;
استيراد javax.servlet.FilterConfig;
استيراد javax.servlet.ServletException;
استيراد javax.servlet.ServletRequest;
استيراد javax.servlet.ServletResponse;
استيراد javax.servlet.http.HttpServletRequest;
استيراد javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
*/
 /* �断用户是否登录,未登录则退出系统
 */
public class SessionFilter implements Filter {
  public FilterConfig config;
  public void destroy() {
    this.config = null;
  }
  public static boolean isContains(String container, String[] regx) {
    boolean result = false;
    for (int i = 0; i < regx.length; i++) {
      if (container.indexOf(regx[i]) != -1) {
        return true;
      }
    }
    return result;
  }
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest hrequest = (HttpServletRequest)request;
    HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);
    String logonStrings = config.getInitParameter("logonStrings");    // 登录登陆页面
    String includeStrings = config.getInitParameter("includeStrings");  // 过滤资源后缀参数
    String redirectPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");// 没有登陆转向页面
    String disabletestfilter = config.getInitParameter("disabletestfilter"); // ما إذا كان المرشح فعالًا أو لا
    if (disabletestfilter.toUpperCase().equals("Y")) { // غير فعال
      chain.doFilter(request, response);
      return;
    }
    String[] logonList = logonStrings.split(";");
    String[] includeList = includeStrings.split(";");
    if (!this.isContains(hrequest.getRequestURI(), includeList)) { // تصفية فقط لقوائم المعاملات المحددة
      chain.doFilter(request, response);
      return;
    }
    if (this.isContains(hrequest.getRequestURI(), logonList)) { // لا تقم بتصفية صفحة تسجيل الدخول
      chain.doFilter(request, response);
      return;
    }
    String user = (String) hrequest.getSession().getAttribute("useronly"); // تحقق من تسجيل الدخول للمستخدم
    if (user == null) {
      wrapper.sendRedirect(redirectPath);
      return;
    } else {
      chain.doFilter(request, response);
      return;
    }
  }
  public void init(FilterConfig filterConfig) throws ServletException {
    config = filterConfig;
  }
}

بهذا يمكن إكمال التحقق من تسجيل الدخول للمستخدمين عبر هذا المرشح.

مرشح منع تلف اللغة الصينية

عند استخدام إطار Spring للمشروع، عند استخدام مجموعة مختلفة من حروف الت编码 في صفحات JSP المتاحة وملفات Java، قد يحدث مشكلة في تلف البيانات المقدمة من النموذج أو في تلف ملفات الاسماء الصينية في التحميل/التحميل، في هذه الحالة يمكن استخدام هذا المرشح.

<filter>
  <filter-name>encoding</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name><!--used to specify a specific character set-->
    <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
    <param-name>forceEncoding</param-name><!--true: no matter whether the request specifies a character set, use encoding; false: if the request has specified a character set, do not use encoding-->
    <param-value>false</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>encoding</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

هذا هو نهاية محتوى هذا المقال، نأمل أن يكون قد ساعدكم في التعلم، ونأمل أن تدعموا تعليمات الصياح بشكل أكبر.

البيان: محتويات هذا المقال تم جمعها من الإنترنت، حقوق النشر مملوكة للمالك الأصلي، تم جمع المحتوى من قبل المستخدمين على الإنترنت الذين قدموه بأنفسهم، ويستخدم هذا الموقع حقوق الملكية غير المكتسبة، ولا يتم تعديل المحتوى بشكل إنساني، ولا يتحمل هذا الموقع أي مسؤولية قانونية مرتبطة بذلك. إذا كنت قد وجدت محتوى يشتبه في انتهاك حقوق النسخ، فالرجاء إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (عند إرسال البريد الإلكتروني، يرجى استبدال # بـ @) لإبلاغنا، وقدم الدليل على الدليل، وإذا تم التحقق من ذلك، سيتم حذف المحتوى المزعوم فوراً.

دليل Elasticsearch