各种应用访问jboss5.0管理数据源方式

    
  上篇博客详细介绍了jboss5.0配置数据源,这篇博客讨论关于如何访问这个数据源。

  如何获得这个数据源,其实总结而来,就两种,一是自己手写查找;另一个是使用注解依赖注入,由容器来查找。
  就如spring来管理action时,可以自己new action,也可以通过spring来注入。

  首先:手动查找相应的JNDI
 第一步:按照上篇博客配置了相应的数据源。
  注意:需要在jboss-5.1.0\server\default\lib添加相应的数据库驱动包,jboss不像weblogic,weblogic可以不添加数据库驱动包,因为默认自带了部分数据库驱动包。
  
  第二步:启动jboss服务,或者启动eclispe中的jboss服务器,就会发现jndi已经绑定:
    
  Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=firstds' to JNDI name 'java:firstds'

  第三步:直接通过InitialContext来查找JNDI名称。
 一般情况我们知道,查找JNDI时,需要在JNDI名称前加上java:/
  代码如下:   
package com.datasource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.annotation.Resource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

//测试jboss管理数据源
public class TestDS { 
     public void test()throws Exception{
          Context ctx=new InitialContext();
          DataSource ds=(DataSource)ctx.lookup("java:/firstds");
    
          //获取数据库连接
          Connection conn=ds.getConnection();
          String sql="select * from test";
          PreparedStatement pst=conn.prepareStatement(sql);
          ResultSet rs=pst.executeQuery();
          while(rs.next()){
               System.out.print("测试通过。。。");
          }
          rs.close();
          pst.close();
          conn.close();
     }

     public static void main(String[] args) throws Exception{
      TestDS ts=new TestDS();
      ts.test();
}
}

   这段是测试代码,主要测试数据源是否可连接。
   
   第四步:测试第三步的代码,若出现以下问题:
       Exception in thread "main" 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:645)
     at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288 )
     at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
     at javax.naming.InitialContext.lookup(InitialContext.java:392 )
     at com.datasource.TestDS.main( TestDS.java:16)

     则需要指明java.naming.factory.initial等信息,可以直接在src下引入 jndi.properties 文件:   
 java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost
java.naming.factory.url.pkgs=org.jboss.naming

     也可以在代码中:
     
     //得到一个JNDI初始化上下文–‡
       Properties props= new Properties();
       props.setProperty( "java.naming.factory.initial",  "org.jnp.interfaces.NamingContextFactory" );
       props.setProperty( "java.naming.provider.url", "localhost:1099");
       props.setProperty( "java.naming.factory.url.pkgs", "org.jboss.naming");
       InitialContext ctx= new InitialContext(props);

    但是引入后,还继续报错,错误如下:  
    Exception in thread "main" javax.naming.NameNotFoundException: firstds not bound
     at org.jnp.server.NamingServer.getBinding(NamingServer.java:771 )
     at org.jnp.server.NamingServer.getBinding(NamingServer.java:779 )
     at org.jnp.server.NamingServer.getObject(NamingServer.java:785 )
     at org.jnp.server.NamingServer.lookup(NamingServer.java:443 )
     at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:726 )
     at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:686 )
     at javax.naming.InitialContext.lookup(InitialContext.java:392 )
     at com.datasource.TestDS.main( TestDS.java:16)

   第二步已经启动服务,显示已经绑定了JDNI,但是客户端访问时,还是出现没有绑定的错误。
   把JNDI名称改成如下: DataSource ds=(DataSource)ctx.lookup("firstds");
   启动服务后,依然是服务显示绑定,但是客户端访问时提示未绑定。
   
   上网查了好长的资料,发现一篇文章解释了问题的来源以及解决方案:
    
<use-java-context> - A boolean indicating if the jndi-name should be prefixed with java: which causes the DataSource to only be accessible from within the jboss server vm. The default is true.

Configuring a DataSource for remote usage
As of jboss-4.0.0 there is support for accessing a DataSource from a remote client. The one change that is necessary for the client to be able to lookup the DataSource from JNDI is to specify use-java-context=false as shown here:

<datasources>  <local-tx-datasource>    <jndi-name>GenericDS</jndi-name>    <use-java-context>false</use-java-context>    <connection-url>...</connection-url>...
This results in the DataSource being bound under the JNDI name "GenericDS" instead of the default of "java:/GenericDS" which restricts the lookup to the same VM as the jboss server.
 
   当你指定<use-java-context>的值为false时,你就可以在jboss运行的VM外的VM上查找到这个DataSource.
   这个属性默认.为true  即,默认情况下你是不可以在JBOSS的VM外来查找这个数据源. 
   
   上一篇博客中,在可视化界面新建并且jboss自动生成的**-ds.xml中的user-java-context标签默认为true。
   
   那如何在jbossvm外访问jboss数据源?
   首先把user-java-context标签更改为false;然后把 java:/ 去掉。如下: DataSource ds=(DataSource)ctx.lookup("firstds");
    
   若是在jbossvm内访问呢?默认是在jboss进程中访问,则可以使用上述方式
DataSource ds=(DataSource)ctx.lookup("firstds");把user-java-context标签为false。
当然也可以:
DataSource ds=(DataSource)ctx.lookup("java:/firstds");默认为true,把user-java-context标签为true或者删除此标签。

   在jboss5.0提供的数据源模板中,没有此标签。可以参考上篇博客中数据源模板。
   
   比如:界面jsp中:  
  <%@ page language ="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
  
<%@ page import ="java.sql.*,javax.naming.*,javax.sql.*" %>

<%
Context ctx=new InitialContext();
//jboss中实际JNDI名字必须在配置的JNDI之前加上java:/前缀
DataSource ds=(DataSource)ctx.lookup("java:/firstds");
//获取数据库连接
Connection conn=ds.getConnection();
String sql="select * from test";
PreparedStatement pst=conn.prepareStatement(sql);
ResultSet rs=pst.executeQuery();
while(rs.next()){
     out.print("测试通过。。。");
}
rs.close();
pst.close();
conn.close();
%>
<html>
<head>
<meta http-equiv= "Content-Type" content ="text/html; charset=UTF-8">
<title> Insert title here</ title>
</head>
<body>
</body>
</html>

  其中界面中调用时,可以不用jndi.properties文件。jboss自动默认初始化。
  
  至于上述提到jboss5.0 服务器vm内或vm外,如何判断呢?我自己判断如下:在eclispe中运行程序时,
  比如:用jsp,肯定使用jboss来运行。但是main方法,肯定是运行java application。因此两个不同的vm,当然eclispe中也可以观察出:
  

  第二种:使用依赖注入方式。
  依赖注入方式,J2EE提供了EJB组件注入,和资源的注入Resource
  依赖注入,在sessionBean中的可以使用Resource注入。
      //使用数据源注入方式
       @Resource (mappedName=  "java:/ firstds " )
      private  DataSource  ds ;

 但是在java 客户端则使用这种方式,则不可以。
 即使我更改上述user-java-context标签,更改mappedName="java:/firstds" 或mappedName="firstds"。
 
 若继续使用依赖注入,则可以使用spring的注入方式。
 
 package com.datasource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.sql.DataSource;

//测试jboss管理数据源
public class TestDSpring {
     //java客户端则不可以使用resource注解

     DataSource ds;
     
     public DataSource getDs() {
            return ds;
     }

     public void setDs(DataSource ds) {
            this. ds = ds;
     }

     public void test()throws Exception{
            //Context ctx =new InitialContext();
            //DataSource ds =(DataSource)ctx.lookup("firstds");
     
            //获取数据库连接
           Connection conn= ds.getConnection();
           String sql= "select * from test";
           PreparedStatement pst=conn.prepareStatement(sql);
           ResultSet rs=pst.executeQuery();
            while(rs.next()){
                System. out.print( "测试通过。。。" );
           }
           rs.close();
           pst.close();
           conn.close();
     }
}

  搭建spring的环境,不再讲解,则spring配置文件如下:
  
       <bean name ="testDS"
            class= "com.datasource.TestDSpring"
            scope= "prototype">
            <property name ="ds" ref="ds"></ property>
     </bean >
     
     <bean name ="ds"  class= "org.springframework.jndi.JndiObjectFactoryBean" >
       <property name ="jndiName" value="firstds"></ property>
     </bean >

  其中value="firstds"还是java:/firstds,还是依赖配置文件中的标签,上述已经讲解。

  客户端测试如下:
  package com.datasource;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
     public static void main(String[] args) throws Exception {
           AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-beans.xml" );
        System. out.println( "--------");
        TestDSpring ps = (TestDSpring)ctx.getBean( "testDS");
        ps.test();

     }
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>