【问题标题】:NullPointerException possibly related to DataSource connectionNullPointerException 可能与 DataSource 连接有关
【发布时间】:2014-10-31 20:27:49
【问题描述】:

我第一次尝试在 Web 应用程序中使用连接池。目前,当我尝试加载显示从 MySQL 数据库检索到的 2 个推荐的主页时,我得到了这个堆栈跟踪:

java.lang.NullPointerException uk.co.morleys.TestimonialService.getTestimonials(TestimonialService.java:57) uk.co.morleys.HomeController.doGet(HomeController.java:54) javax.servlet.http.HttpServlet.service(HttpServlet.java:621) javax.servlet.http.HttpServlet.service(HttpServlet.java:728) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) org.tukey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176) org.tukey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) org.tukey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) org.tukey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:394) org.tukey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:213) org.tukey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:171) org.tukey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) org.tukey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) org.tukey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:394)

此错误与以下方法有关:

public class TestimonialService {
    ResultSet rs;

    public TestimonialService(){
        rs = null;
    }
    public List<Testimonial> getTestimonials(int limit) throws SQLException{
        List<Testimonial> list = new ArrayList<Testimonial>();
        DataSource dd = DataSourceFactory.getMySQLDataSource();

        try(Connection con = dd.getConnection()){
            PreparedStatement ps = con.prepareStatement("SELECT id, author, testimonial, date FROM morleys_testimonial WHERE isActive=1 ORDER BY date DESC LIMIT ?");
            ps.setInt(1, limit);
            rs = ps.executeQuery();
            while(rs.next()){
                Testimonial Testimonial = new Testimonial();
                Testimonial.setAuthor(rs.getString("author"));
                Testimonial.setTestimonial(rs.getString("testimonial"));
                Testimonial.setDate(rs.getString("date"));
                Testimonial.setID(rs.getInt("id"));
                list.add(Testimonial);
            }
        }catch(SQLException e){
            e.printStackTrace();
        }
        return list;
    }
}

这是 DataDourceFactory 类:

public class DataSourceFactory {

    public static DataSource getMySQLDataSource() {
        Properties props = new Properties();
        FileInputStream fis = null;
        MysqlDataSource mysqlDS = null;
        try {
            fis = new FileInputStream("db.properties");
            props.load(fis);
            mysqlDS = new MysqlDataSource();
            mysqlDS.setURL(props.getProperty("MYSQL_DB_URL"));
            mysqlDS.setUser(props.getProperty("MYSQL_DB_USERNAME"));
            mysqlDS.setPassword(props.getProperty("MYSQL_DB_PASSWORD"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return mysqlDS;
    }

}

这就是我将主页提供给浏览器的方式:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String page = getPageName(request.getParameter("page"));
    switch (page){
            case "home":
                List<Testimonial> testimonialList;
                try {
                    testimonialList = testimonialService.getTestimonials(2);
                    request.setAttribute("testimonialList", testimonialList);
                } catch (SQLException e2) {
                    e2.printStackTrace();
                }

                break;
RequestDispatcher rd = getServletContext().getRequestDispatcher(views + getPageFilename(page));
        rd.forward(request, response);
    }

问题 是什么导致了NullPointerException。我假设这与数据源有关。我是否正确建立了与数据库的连接?

更新添加了`db.properties文件

#mysql DB properties
MYSQL_DB_DRIVER_CLASS=com.mysql.jdbc.Driver
MYSQL_DB_URL=jdbc:mysql://myhostname/
MYSQL_DB_USERNAME=username
MYSQL_DB_PASSWORD=password

【问题讨论】:

  • 你在哪里初始化rs
  • TestimonialService.java 的第 57 行是哪一行?
  • @juergend 在包含getTestimonials() 方法的类构造函数中。我初始化它并给它一个值null
  • 它返回 null 因为抛出了 IOException。您选择捕获此异常,将其打印到某个不被注意的地方,然后返回 null。将e.printStackTrace(); 替换为throw new IllegalStateException(e);,而不是得到一个模糊的空值,您将有一个明确的异常告诉您哪里出了问题。
  • 这是合适的位置之一,但您将无法使用 new FileInputStream("db.properties"); 从战争的 WEB-INF 目录中读取资源。这会在 JVM 的当前目录中查找文件,即执行启动 tomcat 的 java 命令的目录。如果你想从 WEB-INF 读取它,请使用docs.oracle.com/javaee/6/api/javax/servlet/…

标签: java mysql tomcat servlets datasource


【解决方案1】:
fis = new FileInputStream("db.properties");

这条线抛出了FileNotFoundException。您正在捕获异常并在 return mysqlDS; 中返回空值

所以DataSource dd为null,当你访问它时,会抛出一个空指针异常。

您需要确保 db.properties 可以从您的 java 程序中读取。使用完整路径或确保它是 jar 的一部分,类加载器可以在其中找到它。

【讨论】:

  • 我加了一张文件结构图,db.properties文件应该放在哪里?
猜你喜欢
  • 1970-01-01
  • 2013-12-01
  • 2018-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 2015-06-08
  • 1970-01-01
  • 2011-02-24
相关资源
最近更新 更多