봄에 내 인증 필터 내에서 서비스를 자동 배선할 수 없음
토큰으로 사용자를 인증하려고 하는데, 내부에서 서비스를 자동으로 연결하려고 할 때AuthenticationTokenProcessingFilternull 포인터 예외가 발생합니다.자동 배선 서비스가 null이기 때문에 이 문제를 어떻게 해결할 수 있습니까?
나의AuthenticationTokenProcessingFilter학급
@ComponentScan(basePackages = {"com.marketplace"})
public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
    @Autowired
    @Qualifier("myServices")
    private MyServices service;
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        @SuppressWarnings("unchecked")
        Map<String, String[]> parms = request.getParameterMap();
        if (parms.containsKey("token")) {
            try {
                String strToken = parms.get("token")[0]; // grab the first "token" parameter
                User user = service.getUserByToken(strToken);
                System.out.println("Token: " + strToken);
                DateTime dt = new DateTime();
                DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
                DateTime createdDate = fmt.parseDateTime(strToken);
                Minutes mins = Minutes.minutesBetween(createdDate, dt);
                if (user != null && mins.getMinutes() <= 30) {
                    System.out.println("valid token found");
                    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
                    authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
                    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getEmailId(), user.getPassword());
                    token.setDetails(new WebAuthenticationDetails((HttpServletRequest) request));
                    Authentication authentication = new UsernamePasswordAuthenticationToken(user.getEmailId(), user.getPassword(), authorities); //this.authenticationProvider.authenticate(token);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }else{
                    System.out.println("invalid token");
                }
            } catch(Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("no token found");
        }
        // continue thru the filter chain
        chain.doFilter(request, response);
    }
}
 
다음을 추가하려고 했습니다.AppConfig
@Bean(name="myServices")
    public MyServices stockService() {
        return new MyServiceImpl();
    }
 
내 AppConfig 주석은
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.marketplace")
public class AppConfig extends WebMvcConfigurerAdapter {
개봉 후 필터에서 종속성 주입을 사용할 수 없습니다.일반 필터를 사용하고 있지만 서블릿 필터는 봄까지 관리되지 않습니다.자바독스가 지적한 바와 같이
이 일반 필터 기본 클래스는 Spring org.springframework.context에 종속되지 않습니다.ApplicationContext 개념입니다.필터는 일반적으로 자체 컨텍스트를 로드하지 않고 필터의 ServletContext를 통해 액세스할 수 있는 Spring 루트 응용 프로그램 컨텍스트에서 서비스 빈에 액세스합니다(org.spring 프레임워크 참조).거미줄.지지하다.웹 응용 프로그램 컨텍스트 유틸리티).
쉬운 영어로 봄이 서비스를 주입하기를 기대할 수는 없지만, 첫 번째 통화에서 게으르게 설정할 수는 있습니다.예.
public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
    private MyServices service;
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if(service==null){
            ServletContext servletContext = request.getServletContext();
            WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
            service = webApplicationContext.getBean(MyServices.class);
        }
        your code ...    
    }
}
충분히 오래된 질문이지만, 저를 좋아하는 사람들을 위해 이 문제에 대한 제 대답을 추가하겠습니다.
다음에서 필터를 상속해야 합니다.GenericFilterBean그리고 그것을 스프링으로 표시합니다.@Component 
@Component
public class MyFilter extends GenericFilterBean {
    @Autowired
    private MyComponent myComponent;
 //implementation
}
 
그런 다음 Spring 컨텍스트에 등록합니다.
@Configuration
public class MyFilterConfigurerAdapter extends WebMvcConfigurerAdapter {
    @Autowired
    private MyFilter myFilter;
    @Bean
    public FilterRegistrationBean myFilterRegistrationBean() {
        FilterRegistrationBean regBean = new FilterRegistrationBean();
        regBean.setFilter(myFilter);
        regBean.setOrder(1);
        regBean.addUrlPatterns("/myFilteredURLPattern");
        return regBean;
    }
}
 
이렇게 하면 필터의 구성 요소가 올바르게 자동으로 배선됩니다.
나는 단지 그것을 추가해서 그것을 작동시켰습니다.
춘두자동 배선 지원 프로세스현재 상황에 기반한 주입(이);
명시적 한정자를 추가하려고 시도했을 때도 우리가 왜 이것을 해야 하는지 잘 모르겠습니다. 그리고 지금 코드는 다음과 같습니다.
public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        @SuppressWarnings("unchecked")
        Map<String, String[]> parms = request.getParameterMap();
        if (parms.containsKey("token")) {
필터 클래스가 GenericFilterBean을 확장하면 다음과 같은 방법으로 앱 컨텍스트에서 빈에 대한 참조를 얻을 수 있습니다.
public void initFilterBean() throws ServletException {
@Override
public void initFilterBean() throws ServletException {
        WebApplicationContext webApplicationContext =
            WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        //reference to bean from app context
        yourBeanToInject = webApplicationContext.getBean(yourBeanToInject.class);
        //do something with your bean
        propertyValue = yourBeanToInject.getValue("propertyName");
}
 
하드 코딩 빈 이름을 좋아하지 않거나 둘 이상의 빈 참조를 필터에 삽입해야 하는 사용자를 위한 덜 명시적인 방법은 다음과 같습니다.
@Autowired
private YourBeanToInject yourBeanToInject;
@Override
public void initFilterBean() throws ServletException{
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, getServletContext());
    //do something with your bean
    propertyValue = yourBeanToInject.getValue("propertyName");
}
필요한 경우 빈 필터와 패스를 매개 변수로 구성할 수 있습니다.필터가 어디에 있는지 스프링 컨텍스트에서 알고 있습니다. 스프링의 자동 스캔처럼 의존성 주입을 받을 수 없습니다.하지만 마법 같은 것을 하기 위해 필터에 넣을 수 있는 멋진 주석이 있는지 100% 확신할 수는 없습니다.
   <filter>
   <filter-name>YourFilter</filter-name>
       <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
<filter-mapping>
   <filter-name>YourFilter</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>
 
그런 다음 spring.xml에 콩을 주입합니다.
  <bean id="YourFilter" class="com.YourFilter">
     <property name="param">
        <value>values</value>
     </property>
  </bean>
나는 파티에 늦었지만 이 해결책은 나에게 효과가 있었습니다.
web.xml.applicationContext에 ContextLoaderListener를 추가합니다.
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
 
그런 다음 MyFilter Spring Bean 추가자동 배선 지원 프로세스모든 종속성을 추가하는 필터에 웹 응용 프로그램 컨텍스트를 추가하는 InjectionBasedOnServletContext.
@Component
public class MyFilter implements Filter {
    @Autowired
    @Qualifier("userSessionServiceImpl")
    private UserSessionService userSessionServiceImpl;
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain 
    chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) req;
        if (userSessionServiceImpl == null) {
            ServletContext context = httpRequest.getSession().getServletContext();
        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, context);
    }
       .... (for brevity)
    }
 
}
언급URL : https://stackoverflow.com/questions/32494398/unable-to-autowire-the-service-inside-my-authentication-filter-in-spring
'programing' 카테고리의 다른 글
| 서비스 계층 및 컨트롤러: 무엇을 담당합니까? (0) | 2023.07.26 | 
|---|---|
| 스프링 자동 배선 aop 원형 종속성 (0) | 2023.07.26 | 
| Angular 2의 요소에 RouterLink 또는 다른 속성 지시어를 조건부로 추가합니다. (0) | 2023.07.26 | 
| Swagger가 Spring Boot을 사용하여 Spring Data Rest API를 감지하지 못함 (0) | 2023.07.21 | 
| 테이블의 CONNECT BY LEVEL이 추가 행을 반환하는 이유는 무엇입니까? (0) | 2023.07.21 |