Programing

구체적인 URL을 제외 할 수 있습니까?

lottogame 2020. 7. 13. 08:10
반응형

구체적인 URL을 제외 할 수 있습니까? 내부 ?


콘크리트 하나를 제외한 모든 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>

표준 서블릿 API는이 기능을 지원하지 않습니다. Tuckey 와 유사한 rewrite-URL 필터를 사용하거나 (아파치 HTTPD와 매우 유사한 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");
}

필터는 제 3 자 API의 일부이며 따라서 당신은보다 구체적인에서 매핑, 수정할 수없는 경우 url-pattern, 예를 들어, /otherfilterpath/*및에 새로운 필터를 생성 /*하는 앞으로 제 3 자 필터와 일치하는 경로를.

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합니다.

또한보십시오:


Eric Daugherty가 설명 한 접근 방식을 사용했습니다 . 항상 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);
    }
}

This approach works when you want to prevent a certain filter and all the following ones. It should work well if you eg. want to serve some content as static resources within your servlet container instead of letting your application logic (through a filter like GuiceFilter):

Map the folder with your static resource files to the default servlet. Create a servlet filter and put it before the GuiceFilter in your web.xml. In your created filter, you can separate between forwarding some requests to the GuiceFilter and others directly to the dispatcher. Example follows...

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

Unfortunately if you just want to skip a single step in the filter chain while keeping those that follows, this will not work.


I don't think you can, the only other configuration alternative is to enumerate the paths that you want to be filtered, so instead of /* you could add some for /this/* and /that/* etc, but that won't lead to a sufficient solution when you have alot of those paths.

What you can do is add a parameter to the filter providing an expression (like a regular expression) which is used to skip the filter functionality for the paths matched. The servlet container will still call your filter for those url's but you will have better control over the configuration.

Edit

Now that you mention you have no control over the filter, what you could do is either inherit from that filter calling super methods in its methods except when the url path you want to skip is present and follow the filter chain like @BalusC proposed, or build a filter which instantiates your filter and delegates under the same circumstances. In both cases the filter parameters would include both the expression parameter you add and those of the filter you inherit from or delegate to.

The advantage of building a delegating filter (a wrapper) is that you can add the filter class of the wrapped filter as parameter and reuse it in other situations like this one.


I also Had to filter based on the URL pattern(/{servicename}/api/stats/)in java code .

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

But its bizarre, that servlet doesn't support url pattern other than (/*), This should be a very common case for servlet API's !


I have encounterd the same issue, but I find a anwser showing below.

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

this way you don't have to harass the concrete Filter class.


If for any reason you cannot change the original filter mapping ("/*" in my case) and you are dispatching to an unchangeable third-party filter, you can find useful the following:

  • Intercept the path to be bypassed
  • Skip to and execute the last ring of the filter chain (the servlet itself)
  • The skipping is done via reflection, inspecting the container instances in debug mode

The following works in Weblogic 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();
              }           
          }   
      }

참고URL : https://stackoverflow.com/questions/3125296/can-i-exclude-some-concrete-urls-from-url-pattern-inside-filter-mapping

반응형