Весенняя загрузка @WebFilter по определенным urlPatterns не работает [дубликат]

Intro

С моего времени в колледже я запрограммировал в Java, JavaScript, Pascal, ABAP , PHP, Progress 4GL, C / C ++ и, возможно, несколько других языки, о которых я не могу сейчас думать.

. Хотя у всех их есть свои лингвистические особенности, каждый из этих языков разделяет многие из тех же основных понятий. Такие понятия включают процедуры / функции, IF -статы, FOR -loops и WHILE -loops.


Традиционный for -луп

Традиционный цикл for состоит из трех компонентов:

  1. Инициализация: выполняется перед тем, как блок look будет выполнен в первый раз
  2. Условие: проверяет условие каждый раз перед цикл цикла выполняется и завершает цикл, если false
  3. Последующая мысль: выполняется каждый раз после выполнения цикла цикла

Эти три компонента разделены друг от друга на символ ;. Содержимое для каждого из этих трех компонентов является необязательным, что означает, что наиболее минимальный цикл for возможен:

for (;;) {
    // Do stuff
}

Конечно, вам нужно будет включить if(condition === true) { break; } или if(condition === true) { return; } где-то внутри этого for -loop, чтобы заставить его перестать работать.

Обычно, хотя инициализация используется для объявления индекса, условие используется для сравнения этого индекса с минимальным или максимальным значением значение, а afterthought используется для увеличения индекса:

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

Использование традиционного цикла for для циклического перемещения по массиву

Традиционный способ массив, это:

for (var i = 0, length = myArray.length; i < length; i++) {
    console.log(myArray[i]);
}

Или, если вы предпочитаете петлю назад, вы делаете это:

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

Однако существует множество вариантов, например, для например, этот:

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

... или этот ...

var i = 0, length = myArray.length;
for (; i < length;) {
    console.log(myArray[i]);
    i++;
}

... или этот:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

В зависимости от того, что лучше всего работает, в значительной степени зависит как от личного вкуса, так и от конкретного варианта использования.

Обратите внимание, что каждый из этих вариантов

[h27] [h27] while loop

Один из альтернатив цикла for - это цикл while. Для циклического прохождения массива вы можете сделать это:

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

Как и обычные петли for, петли while поддерживаются даже самым старым из браузеров.

Кроме того, обратите внимание, что цикл while может быть переписан в виде цикла for. Например, петля while здесь ведет себя точно так же, как это for -loop:

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...in и for...of

In JavaScript, вы также можете сделать это:

for (i in myArray) {
    console.log(myArray[i]);
}

Это должно использоваться с осторожностью, однако, поскольку оно не ведет себя так же, как традиционный цикл for во всех случаях, и есть потенциал побочные эффекты, которые необходимо учитывать. См. . Почему использование & quot; для ... в & quot;

В качестве альтернативы for...in теперь есть и для for...of . ]. В следующем примере показана разница между циклом for...of и контуром for...in:

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // logs 3, 5, 7
}

Кроме того, вам необходимо учитывать, что никакая версия Internet Explorer не поддерживает for...of ( Edge 12 + ) и что для for...in требуется, по меньшей мере, Internet & nbsp; Explorer & nbsp; 10.


Array.prototype.forEach()

Альтернатива for -loops Array.prototype.forEach() , который использует следующий синтаксис:

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach() поддерживается всеми современными браузерами, а также Internet & nbsp; Explorer & nbsp; 9 и более поздними версиями.


Библиотеки

Наконец, во многих библиотеках утилиты также есть свой вариант foreach. AFAIK, три наиболее популярных из них:

jQuery.each() , в jQuery :

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each() , в Underscore.js :

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach() , в Lodash.js :

_.forEach(myArray, function(value, key) {
    console.log(value);
});
154
задан stites 8 January 2016 в 01:22
поделиться

16 ответов

Если вы используете Spring Boot + Spring Security, вы можете сделать это в конфигурации безопасности.

В приведенном ниже примере я добавляю настраиваемый фильтр перед именем UsernamePasswordAuthenticationFilter (см. все фильтры Spring Spring по умолчанию и их порядок ).

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired FilterDependency filterDependency;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .addFilterBefore(
                new MyFilter(filterDependency),
                UsernamePasswordAuthenticationFilter.class);
    }
}

И класс фильтра

class MyFilter extends OncePerRequestFilter  {
    private final FilterDependency filterDependency;

    public MyFilter(FilterDependency filterDependency) {
        this.filterDependency = filterDependency;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
        HttpServletResponse response,
        FilterChain filterChain)
        throws ServletException, IOException {
       // filter
       filterChain.doFilter(request, response);
    }
}
7
ответ дан Christian Ascone 28 August 2018 в 06:06
поделиться

Вы можете использовать @WebFilter javax.servlet.annotation.WebFilter для класса, который реализует javax.servlet.Filter

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {}

Затем используйте @ServletComponentScan для регистрации

2
ответ дан Cwrwhaf 28 August 2018 в 06:06
поделиться

Для обозначения фильтра сервлета нет специальной аннотации. Вы просто объявляете @Bean типа Filter (или FilterRegistrationBean). Пример (добавление настраиваемого заголовка ко всем ответам) находится в собственном Boot EndpointWebMvcAutoConfiguration ;

Если вы только объявляете Filter, он будет применяться ко всем запросам. Если вы также добавили FilterRegistrationBean, вы можете дополнительно указать отдельные сервлеты и шаблоны url для применения.

Примечание:

Начиная с Spring Boot 1.4, FilterRegistrationBean не устарел и просто переместил пакеты с org.springframework.boot.context.embedded.FilterRegistrationBean на org.springframework.boot.web.servlet.FilterRegistrationBean

64
ответ дан Dave Syer 28 August 2018 в 06:06
поделиться

Вот пример моего настраиваемого класса фильтра:

package com.dawson.controller.filter;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@Component
public class DawsonApiFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        if (req.getHeader("x-dawson-nonce") == null || req.getHeader("x-dawson-signature") == null) {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setContentType("application/json");
            httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required headers not specified in the request");
            return;
        }
        chain.doFilter(request, response);
    }
}

И я добавил его в конфигурацию загрузки Spring, добавив его в класс конфигурации следующим образом:

package com.dawson.configuration;

import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
import com.dawson.controller.filter.DawsonApiFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@SpringBootApplication
public class ApplicationConfiguration {
    @Bean
    public FilterRegistrationBean dawsonApiFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new DawsonApiFilter());
// In case you want the filter to apply to specific URL patterns only
        registration.addUrlPatterns("/dawson/*");
        return registration;
    }
}
10
ответ дан DPancs 28 August 2018 в 06:06
поделиться

Если вы хотите настроить сторонний фильтр, вы можете использовать FilterRegistrationBean. Например, эквивалент web.xml

<filter>
     <filter-name>SomeFilter</filter-name>
        <filter-class>com.somecompany.SomeFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SomeFilter</filter-name>
    <url-pattern>/url/*</url-pattern>
    <init-param>
       <param-name>paramName</param-name>
       <param-value>paramValue</param-value>
    </init-param>
</filter-mapping>

Это будут два компонента в вашем файле @Configuration

@Bean
public FilterRegistrationBean someFilterRegistration() {

    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(someFilter());
    registration.addUrlPatterns("/url/*");
    registration.addInitParameter("paramName", "paramValue");
    registration.setName("someFilter");
    registration.setOrder(1);
    return registration;
} 

public Filter someFilter() {
    return new SomeFilter();
}

. Выше было протестировано с пружинной загрузкой 1.2. 3 [/ д2]

115
ответ дан Haim Raman 28 August 2018 в 06:06
поделиться

Используя аннотацию @WebFilter, это можно сделать следующим образом:

@WebFilter(urlPatterns = {"/*" })
public class AuthenticationFilter implements Filter{

    private static Logger logger = Logger.getLogger(AuthenticationFilter.class);

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

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

         logger.info("checking client id in filter");
        HttpServletRequest request = (HttpServletRequest) arg0;
        String clientId = request.getHeader("clientId");
        if (StringUtils.isNotEmpty(clientId)) {
            chain.doFilter(request, response);
        } else {
            logger.error("client id missing.");
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}
4
ответ дан KayV 28 August 2018 в 06:06
поделиться

Из весенних документов,

Встроенные контейнеры сервлетов - добавьте сервлет, фильтр или прослушиватель в приложение

Чтобы добавить сервлет, Фильтр или сервлет * Слушатель предоставляет для него определение @Bean.

Например:

@Bean
public Filter compressFilter() {
    CompressingFilter compressFilter = new CompressingFilter();
    return compressFilter;
}

Добавьте эту конфигурацию @Bean в свой класс @Configuration и фильтр будет зарегистрирован при запуске.

Также вы можете добавить Servlets, Filters и Listeners, используя сканирование классов,

@WebServlet, @WebFilter и @WebListener аннотированные классы могут автоматически регистрироваться в встроенном контейнере сервлетов, аннотируя класс @Configuration с помощью @ServletComponentScan и указывая пакет (ы), содержащий компоненты, которые вы хотите зарегистрировать. По умолчанию @ServletComponentScan будет сканировать из пакета аннотированного класса.

12
ответ дан Lucky 28 August 2018 в 06:06
поделиться

UPDATE: 2017-12-16:

Есть два простых способа сделать это в Spring boot 1.5.8.RELEASE, нет необходимости в xml.

Первый способ: Если у вас нет пространственного шаблона url, вы можете использовать @Component следующим образом: (Полный код и данные здесь https://www.surasint.com/spring-boot-filter/ )

@Component
public class ExampleFilter implements Filter{
   ...
}

Второй способ: если вы хотите использовать шаблоны url, вы можете использовать @WebFilter следующим образом: (Полный код и данные здесь https://www.surasint.com/spring- boot-filter-urlpattern / )

@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter{
 ...
}

Но вам также нужно добавить аннотацию @ServletComponentScan в свой класс @SpringBootApplication:

@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
...
}

Обратите внимание, что @Component это аннотация Spring, но @WebFilter нет. @WebFiler - аннотирование сервлета.

В обоих случаях вам просто нужна базовая зависимость загрузки загрузки в pom.xml (нет необходимости в явной вставке янтарной ямы tomcat)

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>

    <groupId>com.surasint.example</groupId>
    <artifactId>spring-boot-04</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

ВНИМАНИЕ: в первую очередь, если контроллер весной загружается в файл jsp, запрос будет проходить фильтр дважды.

Хотя во втором случае запрос будет проходить фильтр только один раз.

Я предпочитаю второй способ, потому что он больше похож на поведение по умолчанию в спецификации Servlet ( https://docs.oracle.com/cd/E19879-01/819-3669/6n5sg7b0b/index.html)

Здесь вы можете увидеть больше тестового журнала https: / /www.surasint.com/spring-boot-webfilter-instead-of-component/

13
ответ дан Mahozad 28 August 2018 в 06:06
поделиться

вы также можете сделать фильтр с помощью @WebFilter и реализуете Filter, он будет делать.

 @Configuration
        public class AppInConfig 
        {
        @Bean
      @Order(1)
      public FilterRegistrationBean aiFilterRegistration() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(new TrackingFilter());
            registration.addUrlPatterns("/**");
            registration.setOrder(1);
            return registration;
        } 
    @Bean(name = "TrackingFilter")
        public Filter TrackingFilter() {
            return new TrackingFilter();
        }   
    }
0
ответ дан Muni 28 August 2018 в 06:06
поделиться

Сначала добавьте @ServletComponentScan в свой класс SpringBootApplication.

@ServletComponentScan
public class Application {

Во-вторых, создайте файл фильтра, расширяющий фильтр или сторонний класс фильтра, и добавьте @WebFilter в этот файл следующим образом:

@Order(1) //optional
@WebFilter(filterName = "XXXFilter", urlPatterns = "/*",
    dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD},
    initParams = {@WebInitParam(name = "confPath", value = "classpath:/xxx.xml")})
public class XXXFilter extends Filter{
1
ответ дан nikiforovpizza 28 August 2018 в 06:06
поделиться
@WebFilter(urlPatterns="/*")
public class XSSFilter implements Filter {

    private static final org.apache.log4j.Logger LOGGER = LogManager.getLogger(XSSFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        LOGGER.info("Initiating XSSFilter... ");

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpRequestWrapper requestWrapper = new HttpRequestWrapper(req);
        chain.doFilter(requestWrapper, response);
    }

    @Override
    public void destroy() {
        LOGGER.info("Destroying XSSFilter... ");
    }

}

Вам необходимо реализовать фильтр и его необходимо аннотировать с помощью @WebFilter (urlPatterns = "/ *")

. В классе приложений или конфигурации вам необходимо add @ServletComponentScan. Таким образом, ваш фильтр будет зарегистрирован.

0
ответ дан Rahul Anand 28 August 2018 в 06:06
поделиться

Фильтры в основном используются в файлах регистратора, которые варьируются в зависимости от используемого вами логгера. Lemme объясняет для log4j2:

<Filters>
                <!-- It prevents error -->
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
                <!-- It prevents debug -->
                <ThresholdFilter level="debug" onMatch="DENY" onMismatch="NEUTRAL" />
                <!-- It allows all levels except debug/trace -->
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> 
            </Filters>

Фильтры используются для ограничения данных, и я использовал пороговый фильтр далее для ограничьте уровни данных в потоке, я упомянул уровни, которые могут быть ограничены там. Для дальнейшего пояснения см. Порядок уровней log4j2 - Log4J Уровни: ALL> TRACE> DEBUG> INFO> WARN> ERROR> FATAL> OFF

-3
ответ дан saravanan 28 August 2018 в 06:06
поделиться

Я увидел ответ @ Василий Комаров. Аналогичный подход, но с использованием абстрактного класса HandlerInterceptorAdapter вместо использования HandlerInterceptor .

Вот пример ...

@Component
public class CustomInterceptor extends HandlerInterceptorAdapter {
   @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
    }
}

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private CustomInterceptor customInterceptor ;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor );
    }

}
0
ответ дан Shaunak Patel 28 August 2018 в 06:06
поделиться

Ниже приведен пример одного метода включения настраиваемого фильтра в приложение Spring Boot MVC. Не забудьте включить пакет в сканирование компонентов:

package com.dearheart.gtsc.filters;

import java.io.IOException;

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;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
public class XClacksOverhead implements Filter {

  public static final String X_CLACKS_OVERHEAD = "X-Clacks-Overhead";

  @Override
  public void doFilter(ServletRequest req, ServletResponse res,
      FilterChain chain) throws IOException, ServletException {

    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader(X_CLACKS_OVERHEAD, "GNU Terry Pratchett");
    chain.doFilter(req, res);
  }

  @Override
  public void destroy() {}

  @Override
  public void init(FilterConfig arg0) throws ServletException {}

}
92
ответ дан Sudhir N 28 August 2018 в 06:06
поделиться

Это скорее совет, чем ответ, но если вы используете Spring MVC в своем веб-приложении, хорошей идеей является использование Spring HandlerInterceptor вместо Filter

. Он может выполнять ту же работу, но также - Может работать с ModelAndView. Его методы можно вызвать до и после обработки запроса или после завершения запроса. - Он может быть легко протестирован.

1 Внедрите интерфейс HandlerInterceptor и добавьте аннотацию @Component к вашему классу

@Component
public class SecurityInterceptor implements HandlerInterceptor {

    private static Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.getSession(true);
        if(isLoggedIn(request))
            return true;

        response.getWriter().write("{\"loggedIn\":false}");
        return false;
    }

    private boolean isLoggedIn(HttpServletRequest request) {
        try {
            UserSession userSession = (UserSession) request.getSession(true).getAttribute("userSession");
            return userSession != null && userSession.isLoggedIn();
        } catch(IllegalStateException ex) {
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

    }
}

2 Настройте свой перехватчик

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private HandlerInterceptor securityInterceptor;

    @Autowired
    public void setSecurityInterceptor(HandlerInterceptor securityInterceptor) {
        this.securityInterceptor = securityInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(securityInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/logout");
    }

}
1
ответ дан Vasily Komarov 28 August 2018 в 06:06
поделиться

Существует три способа добавить ваш фильтр:

  1. Аннотировать ваш фильтр одним из стереотипов Spring, например @Component
  2. Зарегистрировать @Bean с помощью Filter в пружине @Configuration
  3. Зарегистрировать @Bean с FilterRegistrationBean в Spring @Configuration

Либо # 1, либо 2 будут делать, если вы хотите, чтобы ваш фильтр применялся ко всем запросам без настройки, в противном случае используйте # 3. Вам не нужно указывать проверку компонента для # 1 для работы до тех пор, пока вы помещаете свой класс фильтра в тот же или подпакет вашего класса SpringApplication. Для # 3 использование вместе с # 2 необходимо только тогда, когда вы хотите, чтобы Spring управлял вашим классом фильтра, например, он имел автозависимые связи. Он отлично подходит для меня, чтобы создать новый фильтр, который не нуждается в автоподготовке / инъекции зависимости.

Хотя сочетание # 2 и # 3 отлично работает, я был удивлен, что в итоге два фильтра не применяются дважды. Я предполагаю, что Spring объединяет два компонента как один, когда он вызывает тот же метод для создания обоих. Если вы хотите использовать № 3 только с автооговором, вы можете AutowireCapableBeanFactory. Ниже приведен пример

private @Autowired AutowireCapableBeanFactory beanFactory;

    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        Filter myFilter = new MyFilter();
        beanFactory.autowireBean(myFilter);
        registration.setFilter(myFilter);
        registration.addUrlPatterns("/myfilterpath/*");
        return registration;
    }
52
ответ дан Willie Wheeler 28 August 2018 в 06:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: