2010-09-05 22 views
13

Trong lớp lọc bộ lọc của tôi, tôi đã thêm một số phụ thuộc vào bean (với chú thích @Autowired). Nhưng trong phương pháp doFilter(), tất cả đậu phụ thuộc của tôi có null ...Sử dụng một số hạt trong lớp Lọc bean?

public class FacebookOAuth implements Filter 
{ 
@Autowired 
private BusinessLogger logger; 

@Autowired 
private IUserSessionInfo userSessionInfo; 

@Autowired 
private FacebookOAuthHelper oAuthHelper; 

public void init(FilterConfig fc) throws ServletException 
{ 
    // Nothing to do 
} 

public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException 
{ 
    // HttpServletRequest req = (HttpServletRequest)sr; 
    HttpServletResponse res = (HttpServletResponse) sr1; 

    String code = sr.getParameter("code"); 

    if (StringUtil.isNotBlankStr(code)) 
    { 
     String authURL = this.oAuthHelper.getAuthURL(code); 

this.oAuthHelper bằng tại null (và đậu dependancy khác) ...

Ông có thể giúp tôi?


Thực tế tôi không sử dụng khái niệm MVC ở phía máy chủ (Spring). Đối với khách hàng phụ của tôi, tôi sử dụng công nghệ Flex và BlazeDS servlet tấn giao tiếp với máy chủ của tôi.

Vì vậy, đó là lý do, tôi sử dụng khái niệm bean lọc.

Vì vậy, làm cách nào tôi có thể xử lý khái niệm bean phiên của mình trong bean Lọc của tôi?


Skaffman,

tôi thực hiện ý tưởng của bạn, vì vậy tôi cập nhật application.xml của tôi với:

<bean id="FacebookOAuthHandler" class="com.xx.FacebookOAuthHandler" /> 
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
    <property name="mappings"> 
    <props> 
     <prop key="/fbauth">FacebookOAuthHandler</prop>   
    </props> 
    </property> 
</bean> 

FacebookOAuthHandler lớp học của tôi:

public class FacebookOAuthHandler extends AbstractController 
{ 
@Autowired 
private BusinessLogger logger; 

@Autowired 
private IUserSessionInfo userSessionInfo; 

@Autowired 
private FacebookOAuthHelper oAuthHelper; 

@Override 
protected ModelAndView handleRequestInternal(HttpServletRequest request, 
     HttpServletResponse response) throws Exception { 

    // TODO 

    return null; 
} 

Nhưng, phương pháp này handleRequestInt ernal không bao giờ được gọi khi URL của tôi là: http://xx.xx.xx.xx/MyApp/fbauth

+0

Cấu hình lò xo của bạn trông như thế nào? – GaryF

Trả lời

12

Giả sử Filter này là dây lên trong web.xml của bạn, thì đây không phải là đi làm việc, kể từ khi nó không được quản lý bởi Spring, nó được quản lý bởi container servlet. Vì vậy, những thứ như autowiring sẽ không hoạt động.

Nếu bạn muốn xác định bộ lọc servlet là Spring bean, bạn cần xác định nó trong ngữ cảnh ứng dụng gốc của webapp (sử dụng ContextLoaderListener trong web.xml), và sau đó defining a DelegatingFilterProxy ủy quyền cho bean được Spring quản lý của bạn làm việc.

Tuy nhiên, bạn có thực sự cần một bộ lọc servlet cho việc này không? Những gì tôi biết về công cụ xác thực Facebook, điều này có thể là done just as easily with a Spring HandlerInterceptor. Điều này sẽ làm việc ít hơn đáng kể so với bộ lọc ủy nhiệm.

+0

Hi Skaffman! Cảm ơn rất nhiều cho câu trả lời của bạn. Vâng, tất cả các tệp cấu hình của tôi (web.xml và tệp application.xml của tôi) đều ổn (với ContextLoaderListenner, với delegatingFilterProxy, v.v.). Nhưng, ngay cả với cấu hình này, tôi không thể sử dụng đậu trong bộ lọc của tôi, đúng không? – Anthony

+0

Bạn có thể đưa ra một số ví dụ về cách xác định bộ lọc servlet như một bean mùa xuân không? – Dejell

+0

Tôi thực sự thấy bài viết http://pro-programmers.blogspot.co.il/2011/08/spring-bean-as-servlet-filter.html, nhưng tôi không sử dụng SpringMCV. nó sẽ giúp gì? – Dejell

7

Nhìn vào câu trả lời này trên trang web của mùa xuân: http://forum.springsource.org/showthread.php?60983-Autowiring-the-servlet-filter

Tóm lại - bạn có thể tự buộc vào mùa xuân để áp dụng @Autowire chú thích để bộ lọc của bạn:

public void init(FilterConfig filterConfig) throws ServletException { 

    ServletContext servletContext = filterConfig.getServletContext(); 
    WebApplicationContext webApplicationContext = 
      WebApplicationContextUtils.getWebApplicationContext(servletContext); 

    AutowireCapableBeanFactory autowireCapableBeanFactory = 
      webApplicationContext.getAutowireCapableBeanFactory(); 

    autowireCapableBeanFactory.configureBean(this, BEAN_NAME); 
} 
5

Tôi biết đó là một câu hỏi bây giờ cũ, nhưng không có ví dụ nào về việc sử dụng DelegatingFilterProxy trong các câu trả lời hiện tại và một câu hỏi gần đây yêu cầu ví dụ như vậy được đánh dấu là trùng lặp cho câu hỏi này.

Vì vậy, DelegatingFilterProxy là bộ lọc đặc biệt biết về root ApplicationContext và ủy quyền doFilter cho một bean.

Ví dụ: MyFilter là một lớp thực hiện Filter, và myFilter là một đậu mùa xuân

<bean id=myFilter class="org.example.MyFilter ...>...</bean> 

hoặc trong một lớp cấu hình

@Bean 
public MyFilter myFilter() { 
    MyFilter myFilter = new MyFilter(); 
    //initialization ... 
    return myFilter; 
} 

Trong web.xml, bạn chỉ cần khai báo một DelegatingFilterProxy với cùng một tên là bean:

<filter> 
    <filter-name>myFilter</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>myFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

Điều đó w ay, như myBean là một bean thực, nó có thể được tiêm bình thường với các bean khác với chú thích @Autowired và phương thức doFilter của nó sẽ được gọi bởi DelegatingFilterProxy. Vì bạn có thể sử dụng phương thức init và destroy spring, theo mặc định, các phương thức initdestroy sẽ không được gọi, trừ khi bạn chỉ định init-param "targetFilterLifecycle" là "true".

+0

Tôi đang cố gắng làm điều đó trong dự án của mình, nhưng lúc khởi động máy chủ, một lỗi được đưa ra: Nghiêm trọng: Bộ lọc khởi động ngoại lệ myFilter org.springframework.beans.factory.NoSuchBeanDefinitionException: Không có bean nào có tên 'myFilter' được định nghĩa. Tôi đã cố định cấu hình thông qua XML và Chú thích. Có vẻ như web.xml được đọc trước khi bean được cấu hình. – Alex

+0

Tôi đã sử dụng nó trong nhiều dự án và không bao giờ có bất kỳ vấn đề gì.Nhưng bean phải được khai báo trong bối cảnh gốc, không phải trong dispatcher-servlet. Bạn sẽ cho bạn thấy cách bạn khai báo bean. –

+0

Tôi xin lỗi vì sự rùng rợn của tôi, nhưng làm thế nào tôi có thể khai báo một bean trong ngữ cảnh gốc hoặc dispatcher-servlet? Tôi vừa tạo một lớp cấu hình trong đó tôi đã đặt một chú giải "@Configuration", sau đó tạo một "@Bean" (tham chiếu đến lớp myFilter). – Alex

27

tôi đã phải đối mặt với cùng một vấn đề và ý tưởng đầu tiên của tôi là tự buộc Mùa xuân xin chú thích @Autowired đến bộ lọc như đề xuất ở đây

http://forum.springsource.org/showthread.php?60983-Autowiring-the-servlet-filter

Nhưng tôi không thích những ý tưởng về thể xác định rõ tên đậu trong lớp Java của tôi.

Tôi tìm thấy một cách sạch hơn mà làm việc cũng như:

public void init(FilterConfig filterConfig) throws ServletException { 
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, 
      filterConfig.getServletContext()); 
} 
+1

Cảm ơn nhiều. Điều này thực sự làm việc cho tôi. :) – Akash5288

1

tôi đã nhận được con trỏ null khi truy cập đậu lớp dịch vụ trong lớp lọc bằng Autowiring. Tôi đã tìm kiếm hơn 100 liên kết nhưng không thể tìm thấy giải pháp. Tôi đang sử dụng ứng dụng Khởi động mùa xuân và cấu hình được yêu cầu để lấy đậu trong lớp lọc:

FilterConfig.java cung cấp ngữ cảnh ứng dụng Object.

@Component 
public class FilterConfig implements ApplicationContextAware{ 

private static ApplicationContext context; 


public static ApplicationContext getApplicationContext() { 
     return context; 
    } 
public static <T> T getBean(String name,Class<T> aClass){ 
    return context.getBean(name,aClass); 
} 

@Override 
public void setApplicationContext(ApplicationContext ctx) throws BeansException { 
    context = ctx; 
} 

} 

trong lớp lọc, tôi đã sử dụng như thế này:

UserService userService =FilterConfig.getBean("UserService", UserService.class); 

UserService đây là tên đậu được đề cập trong

@Service("UserService") 
    public class UserServiceImpl implements UserService { ...} 

Không Cấu hình trong lớp chính của Boot xuân: SpringBootServletInitializer

Các vấn đề liên quan