Mostrando entradas con la etiqueta J2EE. Mostrar todas las entradas
Mostrando entradas con la etiqueta J2EE. Mostrar todas las entradas

jueves, 15 de noviembre de 2012

Configuración DATA SOURCE TOMCAT 7 - ORACLE DATA SOURCE


  • DATA SOURCE

La configuración de un Data Source para tomcat es muy sencillo se requiere seguir los siguientes pasos los cuales fueron extraidos de la página oficial de tomcat: configuración Data Source y la configuracion del Context.xml.

1.Archivo Context: lo primero que se tiene que hacer es configurar el Context para esto tenemos 2 opciones:


a. Configuración Context en el war: crear un archivo Context.xml en la aplicación en la carpeta META-INF el cual debe tener la siguiente estructura (para este ejemplo realice las pruebas con Oracle):


WEB-INF/web.xml
esto si se quiere trabajar la configuración a nivel del war.

b. Configuración Context Tomcat: si se quiere trabajar con un solo archivo de configuración a nivel de tomcat ingresar la misma configuración en el archivo Context.xml que se encuentra en la ruta tomcat/conf si se quiere agregar mas conexiones agregar un nuevo algo así:

WEB-INF/web.xml
2. Archivo web.xml: en el archivo web.xml de la aplicación agregar:


Descripcion conexion jdbc/ds1 javax.sql.DataSource Container
3. Utilizando el DS: en la aplicación hacemos llamado al ds con el siguiente código:


Context ctx = new InitialContext(); Context envctx = (Context) ctx.lookup("java:/comp/env"); DataSource dataSource = (DataSource) envctx.lookup("jdbc/ds1"); Connection conn = dataSource.getConnection();


  • ORACLE DATA SOURCE

Si vas trabajar con tipos de datos propios de oracle tendrias que cambiar tu configuración y trabajar con ORACLE DATA SOURCE, por ejemplo en mi caso con datos del tipo "OracleTypes.CURSOR, BLOB etc." para eso se tiene que reemplazar el siguiente código en el Contex.mxl:




despues se debe cambiar en el web.xml del proyecto:

Descripcion conexion jdbc/ds1 oracle.jdbc.pool.OracleDataSource Container

y por último en el código:

Context ctx = new InitialContext(); Context envctx = (Context) ctx.lookup("java:/comp/env"); OracleDataSource dataSource = (OracleDataSource) envctx.lookup("jdbc/ds1"); Connection conn = dataSource.getConnection();

Buenos después de tiempo publico un nuevo post espero les sea util. adeu.

viernes, 28 de agosto de 2009

Captcha Java JSP - J2EE

JSP que genera el codigo Captcha, que le he puesto el nombre "cap3.jsp"

no olvidar importar

@ page import="java.util.*"
@ page import="java.io.*"
@ page import="javax.servlet.*"
@ page import="javax.servlet.http.*"
@ page import="java.awt.*"
@ page import="java.awt.image.*"
@ page import="javax.imageio.*"
@ page import="java.awt.geom.*"

Codigo jsp


response.setContentType("image/jpg");

try {

Color backgroundColor = Color.orange;
Color borderColor = Color.red;
Color textColor = Color.white;
Color circleColor = new Color(160,160,160);
Font textFont = new Font("Arial", Font.PLAIN, 24);
int charsToPrint = 6;
int width = request.getParameter("width") != null ? Integer.parseInt(request.getParameter("width")) : 150;
int height = request.getParameter("height") != null ? Integer.parseInt(request.getParameter("height")) : 40;
int circlesToDraw = 4;
float horizMargin = 20.0f;
float imageQuality = 0.95f; // max is 1.0 (this is for jpeg)
double rotationRange = 0.7; // this is radians
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics2D g = (Graphics2D) bufferedImage.getGraphics();

//Draw an oval
g.setColor(Color.gray);
g.fillRect(0, 0, width, height);

// lets make some noisey circles
g.setColor(circleColor);
for ( int i = 0; i < circlesToDraw; i++ ) {
int circleRadius = (int) (Math.random() * height / 2.0);
int circleX = (int) (Math.random() * width - circleRadius);
int circleY = (int) (Math.random() * height - circleRadius);
g.drawOval(circleX, circleY, circleRadius * 2, circleRadius * 2);
}

g.setColor(textColor);
g.setFont(textFont);

FontMetrics fontMetrics = g.getFontMetrics();
int maxAdvance = fontMetrics.getMaxAdvance();
int fontHeight = fontMetrics.getHeight();

// i removed 1 and l and i because there are confusing to users...
// Z, z, and N also get confusing when rotated
// 0, O, and o are also confusing...
// lowercase G looks a lot like a 9 so i killed it
// this should ideally be done for every language...
// i like controlling the characters though because it helps prevent confusion
String elegibleChars = "ABCDEFGHJKLMPQRSTUVWXYabcdefhjkmnpqrstuvwxy23456789";
char[] chars = elegibleChars.toCharArray();

float spaceForLetters = -horizMargin * 2 + width;
float spacePerChar = spaceForLetters / (charsToPrint - 1.0f);

AffineTransform transform = g.getTransform();

StringBuffer finalString = new StringBuffer();

for ( int i = 0; i < charsToPrint; i++ ) {
double randomValue = Math.random();
int randomIndex = (int) Math.round(randomValue * (chars.length - 1));
char characterToShow = chars[randomIndex];
finalString.append(characterToShow);

// this is a separate canvas used for the character so that
// we can rotate it independently
int charImageWidth = maxAdvance * 2;
int charImageHeight = fontHeight * 2;
int charWidth = fontMetrics.charWidth(characterToShow);
int charDim = Math.max(maxAdvance, fontHeight);
int halfCharDim = (int) (charDim / 2);

BufferedImage charImage = new BufferedImage(charDim, charDim, BufferedImage.TYPE_INT_ARGB);
Graphics2D charGraphics = charImage.createGraphics();
charGraphics.translate(halfCharDim, halfCharDim);
double angle = (Math.random() - 0.5) * rotationRange;
charGraphics.transform(AffineTransform.getRotateInstance(angle));
charGraphics.translate(-halfCharDim,-halfCharDim);
charGraphics.setColor(textColor);
charGraphics.setFont(textFont);

int charX = (int) (0.5 * charDim - 0.5 * charWidth);
charGraphics.drawString("" + characterToShow, charX,
(int) ((charDim - fontMetrics.getAscent())
/ 2 + fontMetrics.getAscent()));

float x = horizMargin + spacePerChar * (i) - charDim / 2.0f;
int y = (int) ((height - charDim) / 2);
//System.out.println("x=" + x + " height=" + height + " charDim=" + charDim + " y=" + y + " advance=" + maxAdvance + " fontHeight=" + fontHeight + " ascent=" + fontMetrics.getAscent());
g.drawImage(charImage, (int) x, y, charDim, charDim, null, null);

charGraphics.dispose();
}

//Write the image as a jpg
Iterator iter = ImageIO.getImageWritersByFormatName("JPG");
if( iter.hasNext() ) {
ImageWriter writer = (ImageWriter)iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(imageQuality);
writer.setOutput(ImageIO.createImageOutputStream(response.getOutputStream()));
IIOImage imageIO = new IIOImage(bufferedImage, null, null);
writer.write(null, imageIO, iwp);
} else {
throw new RuntimeException("no encoder found for jsp");
}

// let's stick the final string in the session
System.out.println("finalString.toString() :"+finalString.toString());
request.getSession().setAttribute("captcha", finalString.toString());

g.dispose();
} catch (IOException ioe) {
throw new RuntimeException("Unable to build image" , ioe);
}


Ahora vamos a mostrar la imagen generada en otro JSP llamado "index.jsp" para validar el valor de la imagen con el que ha sido ingresado en el caja de texto implementamos un scriptlet en el JSP (index.jsp) algo como esto.

< %

String msg="";
String secHash ="";
String originalHash="";
String seccode = request.getParameter ("seccode");
System.out.println("Valor caja texto : "+seccode);
if(!(seccode == null || seccode.equals("null"))){
originalHash=(String)session.getAttribute("captcha");
System.out.println("Valor de captcha sesion : "+originalHash);
secHash = seccode;

if(originalHash.equals(secHash)){
msg="Correcto ";
}else{
msg="Error ";
}
}
% >


Agregamos un form con la caja de texto y una etiqueta img





  <%=msg%>




Probando el Captcha
Resultado que se muestra en el JSP "index.jsp"

lunes, 24 de agosto de 2009

Expresiones Regulares en Java



//Ejemplo de Validadores de Correo y CIF

//metodo para validar correo
public boolean validaCorreo(String c){
//asignamos la expresion
Pattern p = Pattern.compile("^[a-zA-Z0-9_-]{2,15}@[a-zA-Z0-9_-]{2,15}.[a-zA-Z]{2,4}(.[a-zA-Z]{2,4})?$");
//comparamos con nuestro valor
Matcher m = p.matcher(c);
//si el correo es correcto devuelve TRUE o de lo contrario FALSE
return m.matches();
}

public boolean validaCif(String cif){
Pattern p2 = Pattern.compile("^[a-zA-Z]{1}[0-9]{8}$");
Matcher m2 = p2.matcher(cif);
return m2.matches();
}

Mayor informacion:

http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html

martes, 21 de abril de 2009

Tutorial, Manual JAVA J2EE y mas...

Muy completo vale la pena revisarlo.


Temas

- Java Programming (with Passion!)

- Performance, Debugging, Testing, Monitoring, and Management (with Passion!)
Advanced Java Progamming (with Passion!) - work in progress

- Java EE Programming (with Passion!)

- Ajax Programming (with Passion!)

- Web Services Programming (with Passion!)

- Identity Manager (with Passion!)

- Java FX Programming (with Passion!)

- mas....

http://www.javapassion.com/

martes, 7 de abril de 2009

Patron Singleton - Implementación

En ocasiones necesitamos instanciar una clase solo una vez, la solución es hacer que sea la propia clase la responsable de controlar la existencia de una única instancia. Existe un patrón de diseño clásico que dicta este comportamiento: el singleton o instancia única.


Estructura, qué es un singleton

Con un diagrama UML, un singleton es algo tan simple como lo siguiente:





Podemos observar dos características básicas:

Restricción de acceso al constructor...
Con esto conseguimos que sea imposible crear nuevas instancias.Solo la propia clase puede crear la instancia.
Mecanismo de acceso a la instancia...
El acceso a la instancia única se hace a través de un único punto bien definido, que es gestionado por la propia clase y que puede ser accedido desde cualquier parte del código – en principio -


Parece sencillo. Más adelante veremos posibles extensiones que podemos aplicar al patrón inicial.


Implementación

Ahora que sabemos como es, vamos a intentar llevarlo al código de varias maneras distintas. 1. Instanciación bajo demanda

Lo que vamos a intentar en primer lugar es coger el diseño UML propuesto y llevarlo a Java directamente. Tenemos el código siguiente:


public class Singleton {

static private Singleton singleton = null;

private Singleton() { }

static public Singleton getSingleton() {

if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}

/*
* Metodos del singleton.
*/

public String metodo() {
return "Singleton instanciado bajo demanda";
}

}



Esta implementación se caracteriza porque nuestra instancia única se crea cuando se usa por primera vez – bajo demanda – gracias a una sentencia condicional. En el siguiente punto eliminaremos esto, no por ser incorrecto, sino porque en general no es necesario.

Para utilizar nuestro Singleton solo tenemos que solicitar la instancia única del mismo. Habitualmente se hace de dos formas diferentes, la primera se usa en llamadas puntuales.


Singleton.getsingleton().metodo();



La segunda se usa cuando vamos a invocar nuestro Singleton varias veces, evitando llamadas innecesarias a métodos. Este tipo de singleton es un objeto como otro cualquiera, así que puede ser referenciado sin problemas.


Singleton s = Singleton.getSingleton();
s.metodo();



2. Instanciación automática


Como ya dije, la condición del método singleton() puede ser eliminada. Dicha condición se va a evaluar a cierto siempre salvo la primera vez. Además, el cargador de clases de Java, cuando referenciamos una clase no cargada anteriormente, se ocupa de cogerla de disco y cargarla en memoria inicializando sus miembros static.

Por tanto el siguiente código actúa exactamente igual que el caso 1, creando la instancia en la primera invocación pero eliminando la condición.


public class Singleton {

static private Singleton singleton = new Singleton();

private Singleton() { }

static public Singleton getSingleton() {
return singleton;
}

/*
* Metodos del singleton.
*/

public String metodo() {
return "Singleton ya instanciado";
}

}



Eliminar una condición puede ser una mejora pequeña o grande. Como siempre la optimización debe hacerse por las partes del código que se ejecutan extensivamente.

La manera de acceder al Singleton es la misma que en el caso 1, por supuesto.

3. No hay instancia


Java nos permite trabajar con clases sin necesidad de instanciarlas – posibilidad que usamos en los casos anteriores para acceder al Singleton-. Esta nueva implementación conserva la idea pero no su estructura, ya que aquí realmente no hay una instancia. El Singleton es una clase con métodos y atributos estáticos y nunca llega a existir un objeto.


public class Singleton {

static {
/*
* Inicializacion del singleton
*/
}

private Singleton() { }

/*
* Metodos del singleton.
*/

public static String metodo() {
return "Singleton estatico";
}

}



Con esa implementación, no podemos guardar referencias al objeto como en los casos anteriores – porque el objeto no existe – así que las invocaciones a métodos serán todas del tipo:


Singleton.metodo();



Una desventaja evidente es la necesidad de definir todos los métodos y atributos como static. Unas líneas más abajo comentaremos una posible extension del patrón básico para la cual esta implementación no es útil - a la hora de crear jerarquías de singletons -.


¿Qué usar?... En el fondo es una cuestión de estilo, gusto o de necesidades. Las soluciones propuestas son validas en muchos ámbitos.


Alguna extensión

El singleton, puede extenderse. Puede resultar interesante entre otras:

Que haya un número variable de instancias, seguimos controlando la cantidad, pero esta es mayor que uno.
Extender el singleton, siendo la superclase la que decida que instancia de una subclase debe ser devuelta, como puede verse en el diagrama.





Controlando la concurrencia

Hemos encontrado un mecanismo para tener una única instancia de un objeto y acceder a ella. Ahora bien, qué pasa en una aplicación multihilo, donde varios threads acceden simultáneamente al mismo espacio de memoria.

Posiblemente podremos cometer errores debido a inconsistencias de datos – dirty reads, escrituras fantasma, etc - . Por ello es necesario controlar el acceso concurrente, sincronizando los threads en ejecución.

La sincronización de threads en Java es capítulo aparte y por eso no nos extenderemos más. Únicamente sincronizaremos un Singleton y veremos como actúa. Este Singleton serializa las lecturas y escrituras de una variable. Para mostrar el bloqueo, asumiremos que la escritura tarda unos segundos – durmiendo al thread que escriba – y que no queremos que durante este proceso pueda leerse el valor.


public class Singleton {

static int valor;

static {
valor = 0;
}

private Singleton() { }

public static synchronized String getValor() {
return Integer.toString(valor);
}

public static synchronized void setValor(int nuevoValor) {

System.out.println(Thread.currentThread().getName() + " toma el bloqueo");
valor = nuevoValor;
try {
Thread.sleep(2000);
} catch (InterruptedException ie) { }

System.out.println(Thread.currentThread().getName() + " suelta el bloqueo");
}
}



Ahora generaremos dos hilos uno cambiará el valor y el otro intentará leer.


public class Main {

public static void main(String[] args) {

Thread t = new Thread() {
public void run() {
Singleton.setValor(25);
}
};
t.start();

t = new Thread() {
public void run() {
System.out.println(this.getName() + " intentando leer valor");
System.out.println(this.getName() + " leido valor " + Singleton.getValor());
}
};
t.start();
}
}



Si ejecutamos obtenemos la siguiente salida:


Thread-0 toma el bloqueo
Thread-1 intentando leer valor
Thread-0 suelta el bloqueo
Thread-1 leido valor 25




Esta idea, quizás, no parece tener mucho sentido con una variable entera - a no ser que sea el balance de una cuenta corriente o algo parecido- . Pero si el obtener y el fijar implicasen cambios estructurales en una lista enlazada, por ejemplo, sin proteger el acceso concurrente podemos llegar a tener inconsistencias estructurales en la misma.

Se debe tener cuidado al serializar, pues se degrada el rendimiento. Debe buscarse el máximo paralelismo con la mínima serialización. Si llegamos al punto en que no hay trabajo en paralelo, es mejor hacer que la aplicación sea monothread.


El cargador de clases y la mentira a medias

Es ahora cuando después de explicar todo esto exponemos la verdad: los singletons en Java no existen... Tras el shock inicial, pasemos a la explicación.

Antes mencioné a grandes rasgos como funciona un cargador de clases. Quedó claro que nuestra clase Singleton se encargaba de mantener una única instancia. Sin embargo, quién dice que solo existe un cargador de clases.

De existir varios cargadores de clases, podría existir un singleton diferente en cada uno pero único en el contexto de ese cargador. Cada cargador es independiente del resto.

El lector no debería preocuparse realmente. Todo es cuestión de ser cuidadosos. Si estamos seguros de que solo hay un cargador de clases – como en una aplicación standalone común – trabajamos como hasta ahora.

Si existen varios cargadores de clases pueden suceder dos cosas. Si nuestro Singleton se usa solo para lectura de datos, no hay problema. Si lo usamos para escritura de datos debemos tener en cuenta que se pueden producir inconsistencias. Montar un “protocolo de coherencia entre singletons” es inviable – a la par que absurdo -. Lo normal en estos casos es centralizar la escritura, por ejemplo en una base de datos.

Este enfoque es habitual en aplicaciones web; entornos donde suele haber múltiples cargadores de clases. Puede haber casos donde un servidor web nos de alguna alternativa. Por ejemplo, Jakarta Tomcat proporciona una manera de compartir clases entre cargadores, sin embargo, estas soluciones son desaconsejables, pues nada nos asegura que en el futuro tengamos que cambiar nuestro entorno de ejecución, invalidando estas “peculiares” soluciones.

viernes, 20 de agosto de 2004

Metodo Recursivo - Listado

Aca el ejemplo que he usado para un listado u otros usos q desees darle.

El siguiente metodo te sirve para listar un arbol y todos sus hijos, en primer lugar creamos un metodo recursivo.

donde "hijos" es la lista inicial de la BD que se obtiene a partir del ID del padre.
AllHijos es la lista donde se van a ir almacenando todos los hijos que tenga.
los listados van a ser del Tipo ActividadDsp (Bean).

luego se itera y se vuelve a llamar al mismo metodo con el ID de los hijos obtenidos
y todos se van añadiendo a la lista AllHijos