আমি <ফিল্ম-ম্যাপিং> এর ভিতরে <url-pattern> থেকে কিছু কংক্রিট url বাদ দিতে পারি?


127

আমি চাই একটি কংক্রিট বাদে সমস্ত url- এর জন্য কিছু কংক্রিট ফিল্টার প্রয়োগ করা হোক (অর্থাত্‍ /*বাদে /specialpath)।

এটা করার কোন সম্ভাবনা আছে?


কোডের উদাহরণ:

<filter>
    <filter-name>SomeFilter</filter-name>
    <filter-class>org.somproject.AFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SomeFilter</filter-name>
    <url-pattern>/*</url-pattern>   <!-- the question is: how to modify this line?  -->
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

উত্তর:


156

মানক সার্ভলেট এপিআই এই সুবিধাটি সমর্থন করে না। আপনি এটির মতো টুকির মতো (যা অনেকটা অ্যাপাচি এইচটিপিটিডি'র মতো mod_rewrite) এর জন্য একটি পুনর্লিখন-ইউআরএল ফিল্টার ব্যবহার করতে বা doFilter()ফিল্টার শ্রবণের পদ্ধতিতে একটি চেক যোগ করতে চাইতে পারেন /*

String path = ((HttpServletRequest) request).getRequestURI();
if (path.startsWith("/specialpath/")) {
    chain.doFilter(request, response); // Just continue chain.
} else {
    // Do your business stuff here for all paths other than /specialpath.
}

আপনি যদি প্রয়োজন init-paramহয় তবে ফিল্টার হিসাবে-উপেক্ষা করার উপায়গুলি নির্দিষ্ট করতে পারেন যাতে আপনি web.xmlযেভাবেই এটি নিয়ন্ত্রণ করতে পারেন । আপনি এটি ফিল্টারটিতে নিম্নলিখিত হিসাবে পেতে পারেন:

private String pathToBeIgnored;

public void init(FilterConfig config) {
    pathToBeIgnored = config.getInitParameter("pathToBeIgnored");
}

যদি ফিল্টারটি তৃতীয় পক্ষের API এর অংশ হয় এবং সুতরাং আপনি এটিকে পরিবর্তন করতে পারবেন না, তবে এটিকে আরও নির্দিষ্ট করে মানচিত্র করুন url-pattern, উদাহরণস্বরূপ /otherfilterpath/*এবং একটি নতুন ফিল্টার তৈরি করুন /*যেখানে তৃতীয় পক্ষের ফিল্টারটির সাথে মেলে এমন পথে অগ্রসর হবে।

String path = ((HttpServletRequest) request).getRequestURI();
if (path.startsWith("/specialpath/")) {
    chain.doFilter(request, response); // Just continue chain.
} else {
    request.getRequestDispatcher("/otherfilterpath" + path).forward(request, response);
}

এই ফিল্টারটি নিজেকে অসীম লুপে ডেকে এড়াতে আপনাকে এটিকে REQUESTকেবলমাত্র এবং তৃতীয় পক্ষের ফিল্টারটিতে শুনতে (প্রেরণ) করতে হবে FORWARD

আরো দেখুন:


3
আমার সমস্যাটি হ'ল ফিল্টারটি আমার নয়, এটি উপাদান উপাদান পাঠাগার থেকে।
রোমান

4
আপনি ব্যতিক্রমগুলি সম্পাদন করতে আপনি যে কোডটি ব্যবহার করতে চান তা যুক্ত করার জন্য Ypu এর পক্ষে উপযুক্ত লাইব্রেরি ফিল্টারটি নেওয়া উচিত এবং তা প্রসারিত করা উচিত।
gbtimmon

@ বালাসসি যদি "/ স্পেশালপথ" স্রেফ জেএস, সিএসএস ইত্যাদির মতো স্থিতিশীল সংস্থান সরবরাহ করে তবে চেইন.ডো ফিল্টার () প্রতিক্রিয়াটি ধীর করে দেয়? ফিল্টারটি শৃঙ্খলা ছাড়াই সরাসরি উত্সটি সরবরাহ করার কোনও পদ্ধতি আছে?
বেনহুরসিডি

@ বেনহুরসিডি: আপনি কীভাবে এই পারফরম্যান্সের উদ্বেগ নিয়ে আসতে পারেন তা আমার আসলেই ধারণা নেই।
বালুসসি

13

আমি এরিক ডগের্টি দ্বারা বর্ণিত একটি পদ্ধতির ব্যবহার করেছি : আমি একটি বিশেষ সার্লেট তৈরি করেছি যা সর্বদা 403 কোড সহ উত্তর দেয় এবং এর ম্যাপিংটি সাধারণের সামনে রেখে দেয়।

ম্যাপিং টুকরা:

  <servlet>
    <servlet-name>generalServlet</servlet-name>
    <servlet-class>project.servlet.GeneralServlet</servlet-class>
  </servlet>
 <servlet>
    <servlet-name>specialServlet</servlet-name>
    <servlet-class>project.servlet.SpecialServlet</servlet-class>
 </servlet>
 <servlet-mapping>
    <servlet-name>specialServlet</servlet-name>
    <url-pattern>/resources/restricted/*</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
    <servlet-name>generalServlet</servlet-name>
    <url-pattern>/resources/*</url-pattern>
 </servlet-mapping>

এবং সার্লেট ক্লাস:

public class SpecialServlet extends HttpServlet {
    public SpecialServlet() {
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
    }
}

9

আপনি যখন কোনও নির্দিষ্ট ফিল্টার এবং নিম্নলিখিত সমস্তগুলি প্রতিরোধ করতে চান তখন এই পদ্ধতিটি কার্যকর হয়। এটি উদাহরণস্বরূপ ভাল কাজ করা উচিত। আপনার অ্যাপ্লিকেশনটিকে যুক্তি না দেওয়ার পরিবর্তে (গুইসফিল্টারের মতো কোনও ফিল্টারের মাধ্যমে) আপনার সার্লেট পাত্রে কিছু সামগ্রী স্থিতিশীল সংস্থান হিসাবে পরিবেশন করতে চান:

ডিফল্ট সার্লেটে আপনার স্থিতিশীল সংস্থান ফাইলগুলির সাথে ফোল্ডারটি মানচিত্র করুন। একটি সার্লেট ফিল্টার তৈরি করুন এবং এটি আপনার ওয়েব.এক্সএমএল-এ গুয়াস ফিল্টারের আগে রাখুন। আপনার তৈরি ফিল্টারটিতে আপনি কিছু অনুরোধ গুইস ফিল্টার এবং অন্যকে সরাসরি প্রেরণকারীর কাছে ফরোয়ার্ড করার মধ্যে পৃথক করতে পারেন। উদাহরণ অনুসরণ করে ...

web.xml

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>StaticResourceFilter</filter-name>
    <filter-class>com.project.filter.StaticResourceFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>StaticResourceFilter</filter-name>
    <url-pattern>/static/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

StaticResourceFilter.class

public class StaticResourceFilter implements Filter {

    private final static Logger LOGGER = LoggerFactory.getLogger(StaticResourceFilter.class);

    private static final String RESOURCE_PATH = "/static/";
    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        LOGGER.info("StaticResourceFilter initialized");
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response,
                         final FilterChain chain) throws IOException, ServletException {

        String path = ((HttpServletRequest) request).getServletPath();
        if (path.toLowerCase().startsWith(RESOURCE_PATH)) {
            request.getRequestDispatcher(path).forward(request, response);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        LOGGER.info("StaticResourceFilter destroyed");
    }
}

দুর্ভাগ্যক্রমে আপনি যদি নিম্নলিখিতগুলি ধরে রেখে ফিল্টার চেইনে কেবল একটি পদক্ষেপ এড়াতে চান তবে এটি কার্যকর হবে না।


আমি আপনার সমাধানটি নিয়ে যাওয়ার চেষ্টা করেছি, তবে যে ফিল্টারগুলিতে আমি ফিল্টারটি প্রয়োগ করি এবং চেইনটি ভেঙে ফেলি, তার জন্য আমি অনুসরণের ত্রুটি পাই; স্ট্যাটিক রিসোর্স ফিল্টার দ্বারা ছুঁড়ে দেওয়া ব্যাতিক্রম ব্যতিক্রম: java.io.FileNotFoundException। কোন ধারণা কেন?
শ্যালমেটি

বহু-প্রসঙ্গ স্থাপনার সালে ব্যবহার .getRequestURI()BREAK (একটি 404 সম্ভবত করে) কারণ .getRequestDispatcherসমাধান করা প্রসঙ্গ পথে আপেক্ষিক । যদি আপনার প্রসঙ্গের পথটি থাকে /aতবে আপনার উদাহরণে অনুরোধটি ইউআরআই হবে /a/staticএবং এটি ব্যবহারের পরিবর্তে এর getRequestDispatcher("/a/static")সমাধানের কারণ হবে /a/a/static। স্থির করুন: .getServletPath()পরিবর্তে ব্যবহার করুন .getRequestURI()। আমি এটিকে ঠিক করার জন্য একটি সম্পাদনা জমা দেব, তবে কেবল এফওয়াইআই
রেড

3

আমি মনে করি না আপনি যা করতে পারেন, শুধুমাত্র অন্যান্য কনফিগারেশন বিকল্প পাথ যে আপনার ফিল্টার করা করতে চান গনা হয় তাই পরিবর্তে /*কিছু যোগ করতে পারিনি আপনি /this/*এবং /that/*ইত্যাদি, কিন্তু আপনি দর্শন আছে যে একটি যথেষ্ট সমাধান হতে হবে না path পথের।

আপনি যা করতে পারেন তা হল ফিল্ডারে একটি প্যারামিটার যুক্ত করুন যা একটি এক্সপ্রেশন সরবরাহ করে (নিয়মিত প্রকাশের মতো) যা মেলানো পথগুলির জন্য ফিল্টার কার্যকারিতা এড়াতে ব্যবহৃত হয়। সার্ভলেট ধারক এখনও সেই ইউআরএলগুলির জন্য আপনার ফিল্টারকে কল করবে তবে কনফিগারেশনের উপর আপনার আরও ভাল নিয়ন্ত্রণ থাকবে।

সম্পাদন করা

এখন আপনি উল্লেখ করেছেন যে ফিল্টারটির উপর আপনার কোনও নিয়ন্ত্রণ নেই, আপনি যা করতে পারতেন তা হল superতার পদ্ধতিগুলিতে সেই ফিল্টার কলিং পদ্ধতিগুলির উত্তরাধিকারী হ'ল আপনি যে url পাথটি এড়াতে চান তা উপস্থিত না থাকলে এবং @ বালাসক প্রস্তাবিত, বা বিল্ডের মতো ফিল্টার চেইন অনুসরণ করুন একটি ফিল্টার যা একই পরিস্থিতিতে আপনার ফিল্টার এবং প্রতিনিধিদের ইনস্ট্যান্ট করে। উভয় ক্ষেত্রেই ফিল্টার প্যারামিটারগুলিতে আপনার যুক্ত হওয়া এক্সপ্রেশন প্যারামিটার এবং আপনি যে ফিল্টারটি উত্তরাধিকারসূত্রে অর্পণ করেন বা প্রতিনিধিত্ব করেন সেগুলি উভয়ই অন্তর্ভুক্ত করবে।

একটি প্রতিনিধি ফিল্টার (একটি মোড়ক) তৈরির সুবিধা হ'ল আপনি মোড়কযুক্ত ফিল্টারের ফিল্টার ক্লাসটিকে প্যারামিটার হিসাবে যুক্ত করতে পারেন এবং এটির মতো অন্য পরিস্থিতিতে এটি পুনরায় ব্যবহার করতে পারেন।


3

জাভা কোডে ইউআরএল প্যাটার্ন (/ {সার্ভিসনেম} / এপিআই / স্ট্যাটাস /) এর উপর ভিত্তি করে আমারও ফিল্টার করতে হয়েছিল।

if (path.startsWith("/{servicename}/api/statistics/")) {
validatingAuthToken(((HttpServletRequest) request).getHeader("auth_token"));
filterChain.doFilter(request, response);            
}

তবে এটি উদ্ভট, যে সার্লেটটি (/ *) ব্যতীত ইউআরএল প্যাটার্ন সমর্থন করে না, এটি সার্লেট এপিআই'র জন্য খুব সাধারণ বিষয় হওয়া উচিত!


0

আমি একই সমস্যাটির মুখোমুখি হয়েছি, তবে নীচে একটি আনসার দেখছি।

web.xml

 <!-- set this param value for the filter-->
    <init-param>
            <param-name>freePages</param-name>
            <param-value>
            MainFrame.jsp;
            </param-value>
    </init-param>

filter.java

strFreePages = config.getInitParameter("freePages"); //get the exclue pattern from config file
isFreePage(strRequestPage)  //decide the exclude path

এইভাবে আপনাকে কংক্রিট ফিল্টার ক্লাসটি হয়রান করতে হবে না।


0

যদি কোনও কারণে আপনি মূল ফিল্টার ম্যাপিং (আমার ক্ষেত্রে "/ *") পরিবর্তন করতে না পারেন এবং আপনি একটি অপরিবর্তনীয় তৃতীয় পক্ষের ফিল্টারটিতে প্রেরণ করছেন, আপনি নিম্নলিখিতগুলি দরকারী পেতে পারেন:

  • বাইপাস করার পথটি বিরত করুন
  • ফিল্টার চেইনের শেষ রিংটি এড়িয়ে চলুন (সার্ভলেট নিজেই)
  • স্কিপিং প্রতিবিম্বের মাধ্যমে করা হয়, ডিবাগ মোডে ধারক দৃষ্টান্তগুলি পরিদর্শন করে

ওয়েবলোজিক 12.1.3 এ নিম্নলিখিত কাজ করে:

      import org.apache.commons.lang3.reflect.FieldUtils;
      import javax.servlet.Filter;

      [...]

      @Override   
      public void doFilter(ServletRequest request, ServletRespons response, FilterChain chain) throws IOException, ServletException { 
          String path = ((HttpServletRequest) request).getRequestURI();

          if(!bypassSWA(path)){
              swpFilterHandler.doFilter(request, response, chain);

          } else {
              try {
                  ((Filter) (FieldUtils.readField(
                                (FieldUtils.readField(
                                        (FieldUtils.readField(chain, "filters", true)), "last", true)), "item", true)))
                  .doFilter(request, response, chain);
              } catch (IllegalAccessException e) {
                  e.printStackTrace();
              }           
          }   
      }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.