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

来源:互联网 发布:淘宝企业店铺品牌授权 编辑:程序博客网 时间:2024/06/05 12:50
    
  上篇博客详细介绍了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.NamingContextFactoryjava.naming.provider.url=localhostjava.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();     }}


原创粉丝点击