Aplicaci贸n J2EE (Web, Ejb, Datasource)
Hola:
Estoy haciendo un programa en J2ee (soy un novato) y me tiraron a los leones de una...
Ahora estoy tratando de hacer una conexi贸n a la Base de Datos mediante un DataSource (creo q ya lo tengo configurado en el servidor WAS de IBM, lo prob茅 en el administrador de consola del servidor y me funciona).
La conexi贸n tiene que ser desde la capa EJB, utilizando JNDI para obtener el data source... tengo el siguiente c贸digo, pero no tengo que ponerlo en el EJB mismo, sino que, se recomienda tenerlo centralizado, implementando el patr贸n Service Locator.
------------------------------------------------------------------------------------------------------------------------------------
Connection connection = null;
Properties prop = new Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY, \\\"com.ibm.websphere.naming.WsnInitialContextFactory\\\");
InitialContext contexto = new InitialContext(prop);
try {
// suponiendo que en ejb-jar.xml esta declarado el resource-ref con
// el nombre dataSOURCE
DataSource origenGo = (DataSource) contexto.lookup(\\\"java:comp/env/dataSOURCE\\\");
connection = origenGo.getConnection();
} finally {
contexto.close();
}
--------------------------------------------------------------------------------------------------------------------------------------
Al ser la conexi贸n en la capa EJB... 驴que Beans se usa? y 驴como se hace la relaci贸n con el datasource?
Una vez hecha la conexi贸n en la capa EJB, 驴como hago referencia a esa conecci贸n desde la capa de presentaci贸n (una JSP por ejemplo) ?
Y lo otro que se me queda en el tintero, 驴en que parte se deja el c贸digo del \\\"service locator\\\"?, lo tengo y lo entiendo.... pero el problema es que no se si va en el EJB o en el modulo Web.
Si hay alguien de buena voluntad que me pueda ayudar, se lo agradecer铆a un mont贸n.
Estoy haciendo un programa en J2ee (soy un novato) y me tiraron a los leones de una...
Ahora estoy tratando de hacer una conexi贸n a la Base de Datos mediante un DataSource (creo q ya lo tengo configurado en el servidor WAS de IBM, lo prob茅 en el administrador de consola del servidor y me funciona).
La conexi贸n tiene que ser desde la capa EJB, utilizando JNDI para obtener el data source... tengo el siguiente c贸digo, pero no tengo que ponerlo en el EJB mismo, sino que, se recomienda tenerlo centralizado, implementando el patr贸n Service Locator.
------------------------------------------------------------------------------------------------------------------------------------
Connection connection = null;
Properties prop = new Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY, \\\"com.ibm.websphere.naming.WsnInitialContextFactory\\\");
InitialContext contexto = new InitialContext(prop);
try {
// suponiendo que en ejb-jar.xml esta declarado el resource-ref con
// el nombre dataSOURCE
DataSource origenGo = (DataSource) contexto.lookup(\\\"java:comp/env/dataSOURCE\\\");
connection = origenGo.getConnection();
} finally {
contexto.close();
}
--------------------------------------------------------------------------------------------------------------------------------------
Al ser la conexi贸n en la capa EJB... 驴que Beans se usa? y 驴como se hace la relaci贸n con el datasource?
Una vez hecha la conexi贸n en la capa EJB, 驴como hago referencia a esa conecci贸n desde la capa de presentaci贸n (una JSP por ejemplo) ?
Y lo otro que se me queda en el tintero, 驴en que parte se deja el c贸digo del \\\"service locator\\\"?, lo tengo y lo entiendo.... pero el problema es que no se si va en el EJB o en el modulo Web.
Si hay alguien de buena voluntad que me pueda ayudar, se lo agradecer铆a un mont贸n.
Que tal:
Pues en efecto te tiraron a la jaula de los Leones jajajaja, pero bueno con estas ondas te aseguro que vas a aprender bastante.
En primer lugar debes de implementar Service Locator de la siguiente manera (una posible solucion)
public class ServiceLocator {
private static ServiceLocator me;
InitialContext context = null;
private ServiceLocator()
throws ServiceLocatorException {
try {
context = new InitialContext();
} catch(NamingException ne) {
throw new ServiceLocatorException(...);
}
}
// Returns the instance of ServiceLocator class
public static ServiceLocator getInstance()
throws ServiceLocatorException {
if (me == null) {
me = new ServiceLocator();
}
return me;
}
//returns Object from JnDI
public Object getObject(String jndi) throws NamingException{
Object objref = context.lookup(name);
return objref;
}
// Returns the EJBHome object for requested service
// name. Throws ServiceLocatorException If Any Error
// occurs in lookup
public EJBHome getHome(String name, Class clazz)
throws ServiceLocatorException {
try {
Object objref = context.lookup(name);
EJBHome home = (EJBHome)
PortableRemoteObject.narrow(objref, clazz);
return home;
} catch(NamingException ex) {
throw new ServiceLocatorException(...);
}
}
}
hay que recordar que este patron es utilizado para localizar servicios, para quitarle abstraccion al uso de JNDI, por lo que lo recomendable es que no pases nombres JNDI, si no que los tengas definidos en una clase de servicios
public class ServiceLocator {
// singleton's private instance
private static ServiceLocator me;
static {
me = new ServiceLocator();
}
private ServiceLocator() {}
// returns the Service Locator instance
static public ServiceLocator getInstance() {
return me;
}
// Services Constants Inner Class - service objects
public class Services {
final public static int PROJECT = 0;
final public static int RESOURCE = 1;
}
// Project EJB related constants
final static Class PROJECT_CLASS = ProjectHome.class;
final static String PROJECT_NAME = "Project";
// Resource EJB related constants
final static Class RESOURCE_CLASS = ResourceHome.class;
final static String RESOURCE_NAME = "Resource";
// Returns the Class for the required service
static private Class getServiceClass(int service){
switch( service ) {
case Services.PROJECT:
return PROJECT_CLASS;
case Services.RESOURCE:
return RESOURCE_CLASS;
}
return null;
}
// returns the JNDI name for the required service
static private String getServiceName(int service){
switch( service ) {
case Services.PROJECT:
return PROJECT_NAME;
case Services.RESOURCE:
return RESOURCE_NAME;
}
return null;
}
/* gets the EJBHome for the given service using the
** JNDI name and the Class for the EJBHome
*/
public EJBHome getHome( int s )
throws ServiceLocatorException {
EJBHome home = null;
try {
Context initial = new InitialContext();
// Look up using the service name from
// defined constant
Object objref =
initial.lookup(getServiceName(s));
// Narrow using the EJBHome Class from
// defined constant
Object obj = PortableRemoteObject.narrow(
objref, getServiceClass(s));
home = (EJBHome)obj;
}
catch( NamingException ex ) {
throw new ServiceLocatorException(...);
}
catch( Exception ex ) {
throw new ServiceLocatorException(...);
}
return home;
}
}
El c贸digo de cliente para utilizar el Service Locator mediante est谩 estrateg铆a, se podr铆a parecer a esto:
public class ServiceLocatorTester {
public static void main( String[] args ) {
ServiceLocator serviceLocator =
ServiceLocator.getInstance();
try {
ProjectHome projectHome = (ProjectHome)
serviceLocator.getHome(
ServiceLocator.Services.PROJECT );
}
catch( ServiceException ex ) {
// client handles exception
System.out.println( ex.getMessage( ));
}
}
}
Ahora todas las conexiones a la base de datos, las debes de colocar en la capa de Negocios, nunca debes de utilizar estos objetos en la capa de presentacion ojo........
Despues de hacer esto te recomiendo que uses Business Delegate para quitar complejidad el uso de tus servicios, dentro de Business Delegate, vas a usar Service Locator para lozalizar tus servicios.
Ahora debemos tener en mente que la utilizacion de EJB 2.1 ya esta siendo sustituida por EJB 3.0 te pongo un ejemplo. de Bean de Session. con el cual creo servicios usando POJO's
//la interface remota
package com.sun.tutorial.javaee.ejb;
import java.math.BigDecimal;
import javax.ejb.Remote;
@Remote()
public interface Converter {
public BigDecimal dollarToYen(BigDecimal dollars);
public BigDecimal yenToEuro(BigDecimal yen);
}
//el bean de session
package com.sun.tutorial.javaee.ejb;
import java.math.BigDecimal;
import javax.ejb.*;
@Stateless()
public class ConverterBean implements Converter {
private BigDecimal yenRate = new BigDecimal("115.3100");
private BigDecimal euroRate = new BigDecimal("0.0071");
public BigDecimal dollarToYen(BigDecimal dollars) {
BigDecimal result = dollars.multiply(yenRate);
return result.setScale(2, BigDecimal.ROUND_UP);
}
public BigDecimal yenToEuro(BigDecimal yen) {
BigDecimal result = yen.multiply(euroRate);
return result.setScale(2, BigDecimal.ROUND_UP);
}
}
y la forma de usarlo
import java.math.BigDecimal;
import javax.ejb.EJB;
public class ConverterClient {
//con esto no es necesario una llamada usando
//JNDI
@EJB
private static Converter converter;
public ConverterClient(String[] args) {
}
public static void main(String[] args) {
ConverterClient client = new ConverterClient(args);
client.doConversion();
}
public void doConversion() {
try {
BigDecimal param = new BigDecimal("100.00");
BigDecimal yenAmount = converter.dollarToYen(param);
System.out.println("$" + param + " is " + yenAmount
+ " Yen.");
BigDecimal euroAmount = converter.yenToEuro(yenAmount);
System.out.println(yenAmount + " Yen is " + euroAmount
+ " Euro.");
System.exit(0);
} catch (Exception ex) {
System.err.println("Caught an unexpected exception!");
ex.printStackTrace();
}
}
}
Espero que te sirva la informaci贸n, cualquier duda por aca andamos....
Saludos comunidad Open Source.
Pues en efecto te tiraron a la jaula de los Leones jajajaja, pero bueno con estas ondas te aseguro que vas a aprender bastante.
En primer lugar debes de implementar Service Locator de la siguiente manera (una posible solucion)
public class ServiceLocator {
private static ServiceLocator me;
InitialContext context = null;
private ServiceLocator()
throws ServiceLocatorException {
try {
context = new InitialContext();
} catch(NamingException ne) {
throw new ServiceLocatorException(...);
}
}
// Returns the instance of ServiceLocator class
public static ServiceLocator getInstance()
throws ServiceLocatorException {
if (me == null) {
me = new ServiceLocator();
}
return me;
}
//returns Object from JnDI
public Object getObject(String jndi) throws NamingException{
Object objref = context.lookup(name);
return objref;
}
// Returns the EJBHome object for requested service
// name. Throws ServiceLocatorException If Any Error
// occurs in lookup
public EJBHome getHome(String name, Class clazz)
throws ServiceLocatorException {
try {
Object objref = context.lookup(name);
EJBHome home = (EJBHome)
PortableRemoteObject.narrow(objref, clazz);
return home;
} catch(NamingException ex) {
throw new ServiceLocatorException(...);
}
}
}
hay que recordar que este patron es utilizado para localizar servicios, para quitarle abstraccion al uso de JNDI, por lo que lo recomendable es que no pases nombres JNDI, si no que los tengas definidos en una clase de servicios
public class ServiceLocator {
// singleton's private instance
private static ServiceLocator me;
static {
me = new ServiceLocator();
}
private ServiceLocator() {}
// returns the Service Locator instance
static public ServiceLocator getInstance() {
return me;
}
// Services Constants Inner Class - service objects
public class Services {
final public static int PROJECT = 0;
final public static int RESOURCE = 1;
}
// Project EJB related constants
final static Class PROJECT_CLASS = ProjectHome.class;
final static String PROJECT_NAME = "Project";
// Resource EJB related constants
final static Class RESOURCE_CLASS = ResourceHome.class;
final static String RESOURCE_NAME = "Resource";
// Returns the Class for the required service
static private Class getServiceClass(int service){
switch( service ) {
case Services.PROJECT:
return PROJECT_CLASS;
case Services.RESOURCE:
return RESOURCE_CLASS;
}
return null;
}
// returns the JNDI name for the required service
static private String getServiceName(int service){
switch( service ) {
case Services.PROJECT:
return PROJECT_NAME;
case Services.RESOURCE:
return RESOURCE_NAME;
}
return null;
}
/* gets the EJBHome for the given service using the
** JNDI name and the Class for the EJBHome
*/
public EJBHome getHome( int s )
throws ServiceLocatorException {
EJBHome home = null;
try {
Context initial = new InitialContext();
// Look up using the service name from
// defined constant
Object objref =
initial.lookup(getServiceName(s));
// Narrow using the EJBHome Class from
// defined constant
Object obj = PortableRemoteObject.narrow(
objref, getServiceClass(s));
home = (EJBHome)obj;
}
catch( NamingException ex ) {
throw new ServiceLocatorException(...);
}
catch( Exception ex ) {
throw new ServiceLocatorException(...);
}
return home;
}
}
El c贸digo de cliente para utilizar el Service Locator mediante est谩 estrateg铆a, se podr铆a parecer a esto:
public class ServiceLocatorTester {
public static void main( String[] args ) {
ServiceLocator serviceLocator =
ServiceLocator.getInstance();
try {
ProjectHome projectHome = (ProjectHome)
serviceLocator.getHome(
ServiceLocator.Services.PROJECT );
}
catch( ServiceException ex ) {
// client handles exception
System.out.println( ex.getMessage( ));
}
}
}
Ahora todas las conexiones a la base de datos, las debes de colocar en la capa de Negocios, nunca debes de utilizar estos objetos en la capa de presentacion ojo........
Despues de hacer esto te recomiendo que uses Business Delegate para quitar complejidad el uso de tus servicios, dentro de Business Delegate, vas a usar Service Locator para lozalizar tus servicios.
Ahora debemos tener en mente que la utilizacion de EJB 2.1 ya esta siendo sustituida por EJB 3.0 te pongo un ejemplo. de Bean de Session. con el cual creo servicios usando POJO's
//la interface remota
package com.sun.tutorial.javaee.ejb;
import java.math.BigDecimal;
import javax.ejb.Remote;
@Remote()
public interface Converter {
public BigDecimal dollarToYen(BigDecimal dollars);
public BigDecimal yenToEuro(BigDecimal yen);
}
//el bean de session
package com.sun.tutorial.javaee.ejb;
import java.math.BigDecimal;
import javax.ejb.*;
@Stateless()
public class ConverterBean implements Converter {
private BigDecimal yenRate = new BigDecimal("115.3100");
private BigDecimal euroRate = new BigDecimal("0.0071");
public BigDecimal dollarToYen(BigDecimal dollars) {
BigDecimal result = dollars.multiply(yenRate);
return result.setScale(2, BigDecimal.ROUND_UP);
}
public BigDecimal yenToEuro(BigDecimal yen) {
BigDecimal result = yen.multiply(euroRate);
return result.setScale(2, BigDecimal.ROUND_UP);
}
}
y la forma de usarlo
import java.math.BigDecimal;
import javax.ejb.EJB;
public class ConverterClient {
//con esto no es necesario una llamada usando
//JNDI
@EJB
private static Converter converter;
public ConverterClient(String[] args) {
}
public static void main(String[] args) {
ConverterClient client = new ConverterClient(args);
client.doConversion();
}
public void doConversion() {
try {
BigDecimal param = new BigDecimal("100.00");
BigDecimal yenAmount = converter.dollarToYen(param);
System.out.println("$" + param + " is " + yenAmount
+ " Yen.");
BigDecimal euroAmount = converter.yenToEuro(yenAmount);
System.out.println(yenAmount + " Yen is " + euroAmount
+ " Euro.");
System.exit(0);
} catch (Exception ex) {
System.err.println("Caught an unexpected exception!");
ex.printStackTrace();
}
}
}
Espero que te sirva la informaci贸n, cualquier duda por aca andamos....
Saludos comunidad Open Source.
Hola:
Agradezco mucho tu respuesta... voy a trabajar con lo que me has enviado mas lo que he encontrado por mi cuenta.
De una cosa estoy seguro... cuando tenga listo esto, lo publicar茅 con lujo y detalle para que lo ocupe alguien que lo pueda necesitar.
Agradecido y recordando que cualquier informaci贸n extra es valiosa, se despide.
Leonardo Sandoval
Viva la comunidad Open Source
Agradezco mucho tu respuesta... voy a trabajar con lo que me has enviado mas lo que he encontrado por mi cuenta.
De una cosa estoy seguro... cuando tenga listo esto, lo publicar茅 con lujo y detalle para que lo ocupe alguien que lo pueda necesitar.
Agradecido y recordando que cualquier informaci贸n extra es valiosa, se despide.
Leonardo Sandoval
Viva la comunidad Open Source
