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

كتابة مرشح Servlet

يمكن لمرشحات Servlet توقيف الطلبات والإستجابات بشكل ديناميكي لتحويل أو استخدام المعلومات الموجودة في الطلبات أو الإستجابات.

يمكن إضافة واحدة أو أكثر من مرشحات Servlet إلى Servlet أو مجموعة من Servlets. يمكن أيضًا إضافة مرشحات Servlet إلى ملفات JavaServer Pages (JSP) وصفحات HTML. يتم استدعاء جميع المرشحات المضافة قبل استدعاء Servlet.

مرشحات Servlet هي فئات Java يمكن استخدامها في برمجة Servlet، يمكنها تحقيق ما يلي:

  • توقيف هذه الطلبات قبل الوصول إلى الموارد الخلفية.

  • معالجة هذه الاستجابات قبل إرسالها إلى العميل.

أنواع المرشحات الموصى بها بناءً على المعايير المختلفة:

  • مرشحات التحقق من الهوية (Authentication Filters).

  • مرشحات ضغط البيانات (Data compression Filters).

  • مرشحات التشفير (Encryption Filters).

  • مرشحات إطلاق أحداث الوصول إلى الموارد.

  • مرشحات تحويل الصور (Image Conversion Filters).

  • مرشحات السجلات والمراجعة (Logging and Auditing Filters).

  • مرشحات سلسلة MIME-TYPE (MIME-TYPE Chain Filters).

  • مرشحات الترقيم (Tokenizing Filters).

  • مرشحات XSL/T (XSL/T Filters)، تحويل محتوى XML.

يُعلن المرشح من خلال علامة XML في ملف التكوين التوزيعي (web.xml) ثم يتم ربطه إلى اسم Servlet أو نمط URL في وثيقة التكوين التوزيعي للتطبيق.

عند بدء Web Container بتشغيل تطبيق الويب، يقوم بإنشاء نموذج لكل مرشح تم تسميته في وثيقة التكوين.

ترتيب تنفيذ المرشحات يتطابق مع الترتيب المحدد في ملف التكوين web.xml، عادة ما يتم ضبط المرشحات قبل جميع Servlets.

طرق مرشحات Servlet

المُرشح هو فئة Java قامت بتنفيذ واجهة javax.servlet.Filter. تعريف واجهة javax.servlet.Filter بثلاث طرق:

序号方法 & 描述
1public void doFilter (ServletRequest, ServletResponse, FilterChain)
该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器。
2public void init(FilterConfig filterConfig)
web 应用程序启动时,web 服务器将创建Filter 的示例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
3public void destroy()
Servlet容器在销毁过滤器示例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

FilterConfig 使用

Filter 的 init 方法中提供了一个 FilterConfig 对象。

如 web.xml 文件配置如下:

<filter>
    <filter-name>LogFilter</filter-name>
    <filter-class>com.w3codebox.test.LogFilter</filter-class>
    <init-param>
        <param-name>الموقع</param-name>
        <param-value>موقع التعليم الأساسي</param-value>
    </init-param>
</filter>

在 init 方法使用 FilterConfig 对象获取参数:

public void  init(FilterConfig config) throws ServletException {
    // 获取初始化参数
    String site = config.getInitParameter("Site"); 
    // 输出初始化参数
    System.out.println("网站名称: " + site); 
}

Servlet 过滤器示例

以下是 Servlet 过滤器的示例,将输出网站名称和地址。本示例让您对 Servlet 过滤器有基本的了解,您可以使用相同的概念编写更复杂的过滤器应用程序:

package com.w3codebox.test;
// 导入必需的 java 库
import javax.servlet.*;
import java.util.*;
//实现 Filter 类
public class LogFilter implements Filter  {
    public void  init(FilterConfig config) throws ServletException {
        // 获取初始化参数
        String site = config.getInitParameter("Site"); 
        // 输出初始化参数
        System.out.println("网站名称: " + site); 
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
        // 输出站点名称
        System.out.println("站点网址:http://ar.oldtoolbag.com");
        // 把请求传回过滤链
        chain.doFilter(request,response);
    }
    public void destroy( ){
        /* 在 Filter 示例被 Web 容器从服务移除之前调用 */
    }
}

这边使用前文提到的 DisplayHeader.java 为实例:

// 导入必需的 java 库
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/DisplayHeader")
// 扩展 HttpServlet 类
public class DisplayHeader extends HttpServlet {
    // 处理 GET 方法请求的方法
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        // 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String title = "HTTP Header طلب مثال - شبكة التعليم الأساسي مثال";
        String docType =
            "<!DOCTYPE html> \n"
            out.println(docType +
            "<html>\n"+
            "<head><meta charset=\"utf-8\"><title>" + title + "</title></head>\n"+
            "<body bgcolor=\"#f0f0f0\">\n"+
            "<h1 align=\"center\">" + title + "</h1>\n"+
            "<table width=\"100%\" border=\"1\" align=\"center\">\n"+
            "<tr bgcolor=\"#949494\">\n"+
            "<th>اسم الرأس</th><th>قيمة الرأس</th>\n"+
            "</tr>\n");
        Enumeration headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String paramName = (String)headerNames.nextElement();
            out.print("<tr><td>" + paramName + "</td>\n");
            String paramValue = request.getHeader(paramName);
            out.println("<td> " + paramValue + "</td></tr>\n");
        }
        out.println("</table>\n</body></html>");
    }
    // معالجة طلب طريقة POST
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

توصيل المرشح Servlet في Web.xml

تعريف المرشح، ثم قم بتوصيله إلى URL أو Servlet، وهو شبيه بشكل عام بتعريف Servlet ثم توصيله إلى نمط URL. web.xml أنشئ المدخل التالي للعلامة filter في

<?xml version="1.0" encoding="UTF-8"?>  
<web-app>  
<filter>
  <filter-name>LogFilter</filter-name>
  <filter-class>com.w3codebox.test.LogFilter</filter-class>
  <init-param>
    <param-name>الموقع</param-name>
    <param-value>موقع التعليم الأساسي</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>LogFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>  
  <!-- اسم الكائن -->  
  <servlet-name>DisplayHeader</servlet-name>  
  <!-- الملف الذي يحتوي عليه -->  
  <servlet-class>com.w3codebox.test.DisplayHeader</servlet-class>  
</servlet>  
<servlet-mapping>  
  <servlet-name>DisplayHeader</servlet-name>  
  <!-- عنوان الوجهة -->  
  <url-pattern>/TomcatTest/DisplayHeader</url-pattern>  
</servlet-mapping>  
</web-app>

هذه المرشحات تنطبق على جميع Servlets، لأننا قد specified في التكوين /* . إذا كنت ترغب في تطبيق المرشحات فقط على Servletات قليلة، يمكنك تحديد مسار Servlet معين.

الآن حاول طلب أي Servlet باستخدام الطريقة الشائعة، وسترى السجلات التي يتم إنشاؤها في خادم الويب. يمكنك أيضًا استخدام مسجل Log4J لسجل هذه السجلات في ملف منفرد.

الآن دعنا نزور هذا العنوان المثال http://localhost:8080/TomcatTest/DisplayHeader, ثم راقب محتوى الخروج في الشاشة التالية:

استخدام مرشحات متعددة

يمكن للبرنامج التطبيقي الويب تعريف عدة مرشحات مختلفة لغرض معين. افترض أنك قد قمت بتعريف مرشحين متصفح_التحقق و متصفح_السجلاتتحتاج إلى إنشاء خريطة مختلفة كما هو موضح أدناه، وتبقى العمليات الأخرى مشابهة لتلك التي تم شرحها سابقًا:

<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>com.w3codebox.test.LogFilter</filter-class>
   <init-param>
      <param-name>test-param</param-name>
      <param-value>Initialization Parameter</param-value>
   </init-param>
</filter>
<filter>
   <filter-name>AuthenFilter</filter-name>
   <filter-class>com.w3codebox.test.AuthenFilter</filter-class>
   <init-param>
      <param-name>test-param</param-name>
      <param-value>Initialization Parameter</param-value>
   </init-param>
</filter>
<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
   <filter-name>AuthenFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

ترتيب تطبيق الفلاتر

ترتيب عناصر filter-mapping في web.xml يحدد ترتيب تطبيق المحول إلى Servlet. إذا كنت ترغب في عكس ترتيب الفلاتر، فما عليك سوى عكس ترتيب عناصر filter-mapping في ملف web.xml.

على سبيل المثال، سينطبق LogFilter أولاً، ثم AuthenFilter في العينة أعلاه، ولكن في العينة التالية سيتم عكس هذا الترتيب:

<filter-mapping>
   <filter-name>AuthenFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

شرح نقاط التركيب في web.xml

  • <filter> يحدد فلترًا.

    • <filter-name> يستخدم لتعيين اسم للـ filter، لا يمكن أن يكون محتوى هذا العنصر فارغًا.

    • <filter-class> عنصر يستخدم لتعيين اسم الكائن الكامل المحدد للـ filter.

    • <init-param> عنصر يستخدم لتعيين المعلمات الابتدائية للـ filter، ويحدد <param-name> عنصر اسم المعلمات، و <param-value> عنصر يعين القيمة.

    • في الملفات المرشحة، يمكن استخدام كائن واجهة FilterConfig للاستفسار عن المعلمات الابتدائية.

  • <filter-mapping> عنصر يستخدم لتعيين الموارد التي يتحكم فيها الفلتر. يمكن تحديد الموارد التي يتحكم فيها الفلتر بطرقين: اسم Servlet و مسار طلب الوصول إلى الموارد

    • <filter-name> 子ئية تستخدم لتعيين اسم التسجيل للـ filter. يجب أن يكون هذا القيمة قد تم إعلانه في داخل <filter> عنصر.

    • <url-pattern> يحدد مسار الطلب الذي يُقترح مرشحه (نمط URL المرتبط بالمرشح)

  • <servlet-name> يحدد اسم Servlet الذي يُقترح مرشحه.

  • <dispatcher> يحدد الطريقة التي يتم بها استدعاء المصادر التي يُقترح مرشحها من قبل محول الويب، وهي REQUEST, INCLUDE, FORWARD وERROR واحدة منها، بشكل افتراضي REQUEST. يمكن للمستخدم تعيين عدة عناصر <dispatcher> لتعيين طرق متعددة للتحكم في كيفية استدعاء Filter للموارد.

  • قيم يمكن تعيينها لـ <dispatcher> ومعانيها

    • REQUEST: عند زيارة المستخدم للصفحة مباشرة، سيقوم محول الويب بتشغيل المرشح. إذا تم الوصول إلى المصدر المستهدف من خلال طريقة include() أو forward() من RequestDispatcher، فإن المرشح لن يتم استدعاؤه.

    • INCLUDE: إذا تم الوصول إلى المصدر المستهدف من خلال طريقة include() من RequestDispatcher، فإن المرشح سيتم استدعاؤه. بعيدًا عن ذلك، لن يتم استدعاء المرشح.

    • FORWARD: إذا تم الوصول إلى المصدر المستهدف من خلال طريقة forward() من RequestDispatcher، فإن المرشح سيتم استدعاؤه. بعيدًا عن ذلك، لن يتم استدعاء المرشح.

    • ERROR: إذا تم استدعاء المصدر المستهدف من خلال ميكانيكية معالجة الاستثناءات التصريحية، فإن المرشح سيتم استدعاؤه. بعيدًا عن ذلك، لن يتم استدعاء المرشح.