2

刚接触Spring,由于项目需要,我冲进去了。在将 Spring 用作 Java 应用程序时,我成功地使用了 Spring 的大部分功能,但在 Web 应用程序中没有得到想要的结果。

我正在尝试在 applicationContext.xml 中初始化我的数据源:

<context:annotation-config />
<context:component-scan base-package="learn.spring.webapp.dao" />

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.postgresql.Driver" />
    <property name="url" value="jdbc:postgresql://localhost:5432/postgres" />
    <property name="username" value="postgres" />
    <property name="password" value="postgres" />
</bean>

<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate"
    autowire="constructor" />

网页.xml:

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

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

我成功地在我的应用程序中初始化了 Spring,但未能在我的 dao 类中自动装配 jdbctemplate。

package learn.spring.webapp.dao;

import learn.spring.webapp.model.Manga;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MangaDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void insert(Manga manga){
        String sql = "insert into manga_list values (?,?)";
        jdbcTemplate.update(sql,
                new Object[]{manga.getName(), manga.getAuthor()}); //Null Pointer exception
    }
}

我想在我的 dao 包中自动装配templatebean 。JdbcTemplate当我NullPointerException尝试使用JdbcTemplate. MangaDao正在从 servlet 调用。我想我可能没有正确使用自动装配的注释。请指教。

编辑:

调用 DAO 的 servlet 代码是:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        MangaDao md=new MangaDao();
        Manga manga=new Manga();
        manga.setName("Bleach");
        manga.setAuthor("Kubo Tite");
        md.insert(manga);
    }

而stackTrace如下:

SEVERE: Servlet.service() for servlet TesterServlet threw exception
java.lang.NullPointerException
        at learn.spring.webapp.dao.MangaDao.insert(MangaDao.java:16)
        at learn.spring.webapp.controller.TesterServlet.doGet(TesterServlet.java:33)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:662)
4

4 回答 4

4

我想你的servlet中的代码是这样的:

Manga manga = new Manga();
manga.setName(request.getParameter("name"));
manga.setAuthor(request.getParameter("author"));
MangaDao dao = new MangaDao();
dao.insert(manga); // here you get exception;

但是只有当你得到 bean fron 上下文时,自动装配才有效。

MangaDao dao = appContext.getBean(MangaDao.class);
dao.insert(manga); // should be ok;

那么在哪里可以获得appContext。您应该从文件中加载它并存储以供将来使用。ContextLoaderListener 为您完成了这项工作的一部分。然后您只需将其存储在静态变量中,例如:

@Component
public class AppContext implements ApplicationContextAware {
    private static MangaDao mangaDao = null;
    public static MangaDao getMangaDao() {
        if(mangaDao == null){
            throw new ApplicationContextException("context not initialized");
        }
        return mangaDao;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        mangaDao = applicationContext.getBean(MangaDao.class);
    }
}

确保类AppContext进入包中,用 定义context:component-scan,它会learn.spring.webapp.dao在你的情况下

我强烈建议您使用交易。

于 2012-12-18T15:01:41.367 回答
2

要回答您更新的帖子:

您必须使用在上下文中创建的 bean,而不是创建新实例。尝试自动装配新组件,然后使用它,而不是在控制器中创建新组件。

@Autowired MangaDao mangaDao;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Manga manga=new Manga();
    manga.setName("Bleach");
    manga.setAuthor("Kubo Tite");
    mangaDao.insert(manga);
}

在回答您的原始帖子时:

看起来您只是在组件扫描中缺少正确的包名称。您的 @Component 注释类在 learn.spring.webapp.model 包中,您的扫描没有到达它。尝试在注释扫描中使用更通用的包:

<context:component-scan base-package="learn.spring.webapp" />
于 2012-12-18T14:14:04.103 回答
1

在我使用“SpringBeanAutowiringSupport”抽象类之前,我得到了相同的“null”异常。您应该像这样使用这个抽象类扩展该类:

public class SomeClass extends SpringBeanAutowiringSupport {}
于 2019-02-04T05:35:04.817 回答
0

我建议使用spring-mvc而不是原始 Servlet。

spring-mvc你定义控制器而不是 Servlet。根据您的代码,Spring 控制器可能如下所示:

@Controller 
public class MangaController {

    @Autowired
    private MangaDao dao;

    @RequestMapping(value = "/manga/insert", method = RequestMethod.GET)
    public void doGet() {
        Manga manga = new Manga();
        manga.setName("Bleach");
        manga.setAuthor("Kubo Tite");
        dao.insert(manga);
    }
}

因为控制器由 Spring 管理,所有必需的依赖项都将被注入并准备好供您的代码使用 - 消除NullPointerException.

在您的applicationContext.xml中,您必须在组件扫描中包含控制器包并启用 mvc 功能:

<mvc:annotation-driven />

我强烈建议阅读这篇关于spring-mvc. 它涵盖了所有必需的步骤以及您需要的 Spring 依赖项。

我还建议您查看Spring Reference 文档,如您所见,它非常全面!

于 2012-12-19T13:28:25.597 回答