javaweb使用JDNI读取数据源出现的一些问题,求助!

以下是我的实验目的、思路、步骤。
目的:使用JDNI读取sql数据库表格中的记录。
思路:在同一个java包下创建一个java主类和三个普通类(实现连接数据源操作类,读取查询操作类,关闭资源操作类),预期在配置的conf/context.xml无误和程序无误的情况下应该能实现实验目的。不幸的是运行主类后出现如下错误异常

javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
	at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350)
	at javax.naming.InitialContext.lookup(InitialContext.java:417)
	at test.shujuyuan.getConnection(shujuyuan.java:17)
	at test.jdbc.main(jdbc.java:8)
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
	at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350)
	at javax.naming.InitialContext.lookup(InitialContext.java:417)
	at test.shujuyuan.getConnection(shujuyuan.java:17)
	at test.check.show(check.java:17)
	at test.jdbc.main(jdbc.java:11)
Exception in thread "main" java.lang.NullPointerException
	at test.check.show(check.java:19)
	at test.jdbc.main(jdbc.java:11)

源代码附上:

主类:

package test;

public class jdbc {

	public static void main(String[] args) {

		shujuyuan sjy = new shujuyuan();
		sjy.getConnection();// 获取连接

		check ch = new check();
		ch.show(); // 执行查询

		closeresource cr = new closeresource();
		cr.close(); // 关闭资源
	}
}

连接类:

package test;

import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class shujuyuan {
	Connection con;

	public Connection getConnection() {

		try {
			Context cxt = new InitialContext();
			DataSource ds = (DataSource) cxt.lookup("java:comp/env/jdbczjp");
			try {
				con = ds.getConnection();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return con;
	}
	// 使用这个类,调用类里面的方法返回一个con连接值
}

查询展示类:

package test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class check {

	public void show() {

		Statement stmt;// 接口,负责处理sql语句
		ResultSet rs;// 结果处理
		shujuyuan sjy = new shujuyuan();
		Connection con = sjy.getConnection();
		try {
			stmt = con.createStatement();// 获取connection产生的接口对象
			String sql = "select * from ms";// sql选择语句
			rs = stmt.executeQuery(sql);// 获取sql语句的处理结果
			while (rs.next()) {
				int id = rs.getInt("id");
				String sname = rs.getString("sname");
				int age = rs.getInt("age");
				String sex = rs.getString("sex");
				int score = rs.getInt("score");
				String hobby = rs.getString("hobby");
				System.out.println(id + "\t" + sname + "\t" + age + "\t" + sex
						+ "\t" + score + "\t" + hobby);
				// 处理结果集
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

关闭资源类:

package test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class closeresource {
	Statement stmt;// 接口,负责处理sql语句
	ResultSet rs;// 结果处理
	Connection con;

	public void close() {
		try {
			if (rs != null) {
				rs.close();
			}
			if (stmt != null) {
				stmt.close();
			}
			if (con != null) {
				con.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

猜测应该是从JNDI获取连接异常,导致Connection对象是null。然后你用这个null对象去执行操作,就导致了空指针异常。

我有两点不怎么确定:
1、我的context/xml配置内容是否正确。
2、代码疏漏问题。
我在jsp页面显示

        <%  
		shujuyuan sjy = new shujuyuan();
		 Connection con = sjy.getConnection();
	%>
	<%=con%>时的确显示为null.

看看你的context.xml配置。

我给你看一个,我以前配置好的Demo吧

context.xml

<Context>
	<Resource 
		name="jdbc/dataSource"							
		type="com.alibaba.druid.pool.DruidDataSource"
		factory="org.apacahe.naming.factory.BeanFactory"
		<!-- 
			以上三个,为必配的资源 
			下面的都是属于资源(DruidDataSource)的参数
		-->
		url="jdbc:mysql://localhost:3306/kevinblandy?useUnicode=true&characterEncoding=utf8"
		driverClassName="com.mysql.cj.jdbc.Driver"
		username="root"
		password="root"
		maxActive="1000"/>
</Context>

数据源获取

Context iniCtx = new InitialContext();
DataSource dataSource = (DataSource)iniCtx.lookup("java:comp/env/jdbc/dataSource");
<Context>
<Resource name="jdbczjp"
auth="Container"
type="javax.sql.DataSource" 
maxActive="100"
maxldle="30" 
maxWait="10000" 
username="root" 
password="123456"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8"/>
</Context>

可以确定账号密码 没得问题,我前面用另一种方式获取sql连接成功实现查询操作了,其他地方的配置我不太懂,不敢定断。

  1. factory 属性应该是必填的,工厂类
  2. 你写的驱动程序是过时的,要换
  3. type应该是指定实现类,而不是接口

你可以参照我上面的回复,也就是那个正确的配置,改改看。

改正后是这样:

<Resource 
name="jdbczjp"
auth="Container" 
type="com.alibaba.druid.pool.DruidDataSource"
factory="org.apacahe.naming.factory.BeanFactory"
maxActive="100"
maxldle="30" 
maxWait="10000" 
username="root" 
password="123456"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8"/>

不知道哪里有问题。

你用的是数据源是什么?你要把com.alibaba.druid.pool.DruidDataSource换成你的数据源实现啊。

1 个赞

代码也需要修改吗?

public Connection getConnection() {

		try {
			Context cxt = new InitialContext();
			DataSource ds = (DataSource) cxt.lookup("java:comp/env/jdbczjp");


			try {
				con = ds.getConnection();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return con;
	}

我不太清楚在哪里修改。