带有SpringMVC的JdbcTemplate的空指针异常

时间:2015-04-11 23:22:03

标签: java spring jdbc jdbctemplate

我对Java很陌生,但我想尝试用SpringMVC构建一个简单的项目。它只是一个简单的CRUD应用程序,应该允许人们发布笔记。

当我尝试提交注释的表单或查询时,当我尝试在JdbcTemplate上调用方法时,我得到一个空指针异常。这是我的应用程序类的代码:

package mvc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;

@SpringBootApplication
public class SpringMvcApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(SpringMvcApplication.class, args);
    }

    @Autowired
    JdbcTemplate jdbcTemplate;

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public void run(String... string) throws Exception {
        System.out.println("Creating tables");
        jdbcTemplate.execute("drop table notes if exists");
        jdbcTemplate.execute(("create table notes(" +
                "id serial, content varchar(255), author varchar(255))"));
    }

    public static SpringMvcApplication instance = new SpringMvcApplication();
    public static SpringMvcApplication getInstance() { return instance; }

}

这是我的NoteController.java:

package mvc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class NoteController {
    @RequestMapping("/notes")
    public String index() {
        return "index";
    }

    @RequestMapping("/notes/new")
    public String newNote(Model model) {
        model.addAttribute("note",new Note());
        return "new";
    }

    @RequestMapping(value="/notes", method= RequestMethod.POST)
    public String create(Note note, Model model) {
        model.addAttribute("note", note);
        Note.create(note.getContent(), note.getAuthor());
        return "show";
    }

    @RequestMapping(value = "/notes/{noteId}", method=RequestMethod.GET)
    public String show(@PathVariable String noteId) {
        long id = Long.parseLong(noteId);
        Note note = Note.find(id);
        return "show";
    }
}

我的笔记模型:

package mvc;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

public class Note {

    private Long id;
    private String content;
    private String author;

    public Note() {}

    public Note(Long id, String content, String author) {
        this.id = id;
        this.content = content;
        this.author = author;
    }

    public Long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }

    public String getAuthor() {
        return author;
    }

    public String toString() {
        return content + "by " + author;
    }

    public static void create(String content, String author) {
        JdbcTemplate jdbcTemplate = SpringMvcApplication.getInstance().getJdbcTemplate();
        jdbcTemplate.update("INSERT INTO notes(content, author) values (?,?)", content, author);
    }

    public static Note find(Long id) {
        JdbcTemplate jdbcTemplate = SpringMvcApplication.getInstance().getJdbcTemplate();
        List<Note> notes = jdbcTemplate.query("SELECT id, content, author FROM notes WHERE id = ?", new Object[]{id},
                new RowMapper<Note>() {
                    @Override
                    public Note mapRow(ResultSet rs, int rowNum) throws SQLException {
                        return new Note(rs.getLong("id"), rs.getString("content"),
                                rs.getString("author"));
                    }
                });
        return notes.get(0);
    }
}

这是我的pom.xml:

<?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>

<groupId>org.test</groupId>
<artifactId>mvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Spring MVC</name>
<description>MVC Project for Ship It Saturday</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <start-class>mvc.SpringMvcApplication</start-class>
    <java.version>1.7</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.2.4</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.2.2</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.3-1100-jdbc41</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
    </dependency>
</dependencies>

我不确定这里的代码是什么问题。我正在关注一些不同的指南,但大多数都不清楚代码在做什么。我确信这里可能存在一些非常明显的问题,但我对Spring和Java完全不熟悉,所以我没有看到它。

编辑:

以下是我认为跟踪的相关部分:

2015-04-11 19:01:35.125 ERROR 24895 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
    at mvc.Note.create(Note.java:44)
    at mvc.NoteController.create(NoteController.java:30)

我还应该提一下,SpringMVCApplication类中的run()方法在创建表时效果很好,如果我使用静态数据将insert和query语句移动到该方法中也可以。只有当我将它们移动到自己的方法中时,我才能动态地使用它们,一切都崩溃了。

1 个答案:

答案 0 :(得分:0)

正如评论中已经提到的那样,SpringMvcApplication.getInstance()将无法正常工作。你需要一些东西来连接&#34; spring-world&#34;与#34; not-spring-world&#34;。一种可能的解决方案是将ApplicationContext保存为单身。

@SpringBootApplication
public class SpringMvcApplication {

    private static ApplicationContext context;

    public static void main(String[] args) {
        context = SpringApplication.run(SpringMvcApplication.class, args);
    }

    public static JdbcTemplate getJdbcTemplate() {
        return context.getBean(JdbcTemplate.class);
    }

}

也许你必须根据自己的需要进行调整。