3

我是 Spring 新手,想将 spring ioc 连接到我的小型(测试)网络应用程序中。

我有这样的 Servlet ProductServlet

public class ProductServlet extends HttpServlet{
    private static final long serialVersionUID = 1L;
    private RequestHelper requestHelper;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request);
    }

    private void processRequest(HttpServletRequest request){
        requestHelper.process(request);
    }

    public RequestHelper getRequestHelper() {
        return requestHelper;
    }

    public void setRequestHelper(RequestHelper requestHelper) {
        this.requestHelper = requestHelper;
    }

}

和我的 web.xml:

  <servlet>
    <servlet-name>ProductServlet</servlet-name>
    <servlet-class>com.epam.productshop.controller.ProductShop</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ProductServlet</servlet-name>
    <url-pattern>/ProductServlet</url-pattern>
  </servlet-mapping>

     <listener>
      <listener-class>
        org.springframework.web.context.ContextLoaderListener
      </listener-class>
   </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-config.xml
        </param-value>
    </context-param>

而且我也有这样的弹簧配置xml:

<bean id="factory" class="com.epam.productshop.readerfactory.ReaderFactory">
    <property name="file" value="/xml/products.xml" />
</bean>

<bean id="requestHelper" class="com.epam.productshop.requesthelper.RequestHelper" scope="singleton">
    <property name="factory" ref="factory" />
</bean>

<bean name="ProductServlet" class="com.epam.productshop.controller.ProductServlet" scope="singleton">
    <property name="requestHelper" ref="requestHelper"/>        
</bean>

我有这样的问题:

我希望在 servlet init() 期间将 requestHelper 对象设置为我的 servlet。但不是这个,而是给了我空指针。

我正在尝试实现我的 servlet HttpRequestHandler,写入SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, getServletContext());init() 方法和我在互联网上看到的其他东西,但所有这些都不能解决我的问题。

请帮我

4

3 回答 3

6

在你的问题中,你有

<bean name="ProductServlet" class="com.epam.productshop.controller.ProductServlet" scope="singleton">
    <property name="requestHelper" ref="requestHelper"/>        
</bean>

您不能使用 Spring 容器实例化 servlet,它们是由 servlet 容器实例化的。您只是在声明 ProductServlet 的另一个实例。

因此,当调用 Servletinit()方法时,您应该调用

SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, getServletContext());`

要注入 requestHelper @Autowired,请在您的 servlet 中声明一个带注释的字段或属性:

private RequestHelper requestHelper;

@Autowired
public void setRequestHelper(RequestHelper requestHelper){
  this.requestHelper = requestHelper;
}

来自processInjectionBasedOnServletContext javadoc:

根据存储在 ServletContext 中的当前根 Web 应用程序上下文,处理给定目标对象的@Autowired注入。

于 2012-11-19T20:54:50.947 回答
2

这是一个解决方案,可能会对您有所帮助:

public class ProductServlet extends HttpServlet
{
    private static final long serialVersionUID = 1L;
    private RequestHelper requestHelper = null;

    private requestHelperInit(HttpServletRequest request)
    {
       if(requestHelper == null)
       {
          ApplicationContext ap = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
          requestHelper = ap.getBean(RequestHelper.class);
       }
    }
}

然后requestHelperInit(request)在您的doGet()doPost()方法中调用方法作为第一条语句。

如果您仍在寻找解决方案,那么我希望这会对您有所帮助。

于 2013-10-13T12:28:25.097 回答
1

你有几个选择。如果你真的想注入一个 servlet,问题是 servlet 容器已经负责创建 servlet。由于注入是在创建时发生的,而且创建这个 servlet 有点困难,因此您必须使用不太优雅的解决方案。但是,这个问题解释了如何注入 servlet。

另一方面,您可能会考虑放弃这种方法。如果您真的在创建一个 Web 应用程序,那么直接对 servlet api 进行编码是相当少见的。为什么不选择位于 servlet api 之上并提供更高级别功能(即花里胡哨)的众多 Web 应用程序框架之一。其中一个花里胡哨的是,这些框架提供了与 Spring 的便捷集成,因此您可以轻松地注入代码。例如,Struts 2 有一个 spring 插件,它允许您使用 spring 来注入框架创建的所有对象,包括框架基础设施组件。

于 2012-11-19T20:57:39.100 回答