He de confesar que soy un enamorado de las aplicaciones web y viendo el rumbo que están tomando los servicios web hoy en día voy a explicar lo más detallado posible como creanos nuestro propio servicio web, también crearemos un cliente para podernos conectar, todo ello en Java.
Intentaré reunir todo en dos artículos, este primero que tratará de crear el servicio web y el segundo que tratará del cliente para conectarnos, para desarrollarlo utilizaré el Jdeveloper 10g (según las diferentes versiones el proceso puede variar en algunos pasos) que es gratuito y la base de datos Oracle.
El servicio web que voy a desarrollar consistirá en una especie de tablón de anuncios, donde la gente se pueda registrar, enviar mensajes, recibir mensajes…
Lo primero que tenemos que hacer es crearnos una aplicación. Con el botón derecho sobre el Arbol de aplicaciones y pulsamos sobre nueva aplicación, nos aparecerá el cuadro siguiente donde elegiremos nuestro nombre y ubicación.

No será necesario elegir ningún template específico, vamos a crear algo corriente, como si fuera una clase normal y no un servicio web.
Lo siguiente será crearnos un proyecto asociado a esta aplicación, para ello botón derecho sobre la aplicación creada y damos a nuevo proyecto.
Al igual que antes rellenamos el cuadro con el nombre del proyecto y su ubicación.
Ahora nos crearemos una clase, botón derecho en el proyecto y pulsamos sobre new.
Y dentro del cuadro que se ha abierto, cogeremos Java class, asignandole después un nombre.
Las demás opciones del siguiente cuadro las dejamos comoe stán por defecto.
Supongo que la gente interesada en esto ya sabe java asi que no andaré explicando lo que hace cada función, creo que es bastante fácil tal cual lo he programado.
Lo primero es crearnos nuestra base de datos, desde jdeveloper tenemos la posibilidad de creanos la conexión con ella, una vez hecho, tendremos que crearnos dos tablas, USUARIOS y SW.MENSAJES.
Empezaré por crear una clase para conectar con Oracle, la llamaré ServicioWebBD, mediante ella realizaré todas las conexiones e implementaré en ella todas las funciones que vaya a desarrollar mi servicio web.
package AQUI.mypackage;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Calendar;
import java.util.StringTokenizer;
public class ServicioWebBD {
private Statement statement;
private Connection connection;
public ServicioWebBD() throws ClassNotFoundException, SQLException {
Class.forName("oracle.jdbc.OracleDriver");
connection = DriverManager.getConnection("url base de datos","username","password");
connection.setAutoCommit(true);
statement = connection.createStatement();
}
public boolean BDlogin(String nombre, String contraseña) throws SQLException {
PreparedStatement psLogin = connection.prepareStatement(Constants.SQL_LOGIN);
psLogin.clearParameters();
psLogin.setString(1,nombre);
psLogin.setString(2,contraseña);
ResultSet rs = psLogin.executeQuery();
if(rs.next()){
return true;
}
else{
return false;
}
}
public boolean BDregistro(String nombre, String contraseña) {
try {
PreparedStatement psRegistro = connection.prepareStatement(Constants.SQL_REGISTRO);
psRegistro.clearParameters();
psRegistro.setString(1,nombre);
psRegistro.setString(2,contraseña);
psRegistro.execute();
return true;
}
catch (SQLException e) { }
return false;
}
public boolean BDnuevoMensaje(String mensaje, String destinatario,String remitente,String confirmacion) {
java.util.Calendar fecha = java.util.Calendar.getInstance();
String fechaSMS = fecha.get(Calendar.DATE) + "/"
+ fecha.get(Calendar.MONTH) + "/"
+ fecha.get(Calendar.YEAR) + " a las "
+ fecha.get(Calendar.HOUR_OF_DAY) + ":"
+ fecha.get(java.util.Calendar.MINUTE);
try {
PreparedStatement psMensaje = connection.prepareStatement(Constants.SQL_NUEVO_MENSAJE);
psMensaje.clearParameters();
psMensaje.setString(1,mensaje);
psMensaje.setString(2,destinatario);
psMensaje.setString(3,fechaSMS);
psMensaje.setString(5,remitente);
psMensaje.setString(4,"NO");
psMensaje.setString(6,confirmacion);
psMensaje.execute();
return true;
}
catch (SQLException e) { }
return false;
}
public String BDrecibirMensajes(String destinatario) throws SQLException,
ClassNotFoundException {
PreparedStatement psRecibirMensaje = connection.prepareStatement(Constants.SQL_SELECT_RECIBIR_MENSAJES);
String mensajes = "";
int numMensajes=1;
psRecibirMensaje.clearParameters();
psRecibirMensaje.setString(1,destinatario);
ResultSet rs = psRecibirMensaje.executeQuery();
if(rs.next()){
do{
String mensaje = rs.getString(1);
String remitente = rs.getString(2);
String fechaMensaje = rs.getString(3);
String confirmacion = rs.getString(4);
mensajes += "Mensaje número: "+numMensajes+" \nRecibido de: "+remitente+", el día: "+fechaMensaje+" \n"+mensaje+" \n\n";
PreparedStatement psMensajeLeido = connection.prepareStatement(Constants.SQL_MENSAJE_LEIDO);
psMensajeLeido.clearParameters();
psMensajeLeido.setString(1,mensaje);
psMensajeLeido.setString(2,remitente);
psMensajeLeido.executeUpdate();
if(confirmacion.equals("si")){
ServicioWebBD swbd = new ServicioWebBD();
swbd.BDnuevoMensaje("Confirmación de lectura del mensaje: "+mensaje+"",remitente,destinatario,"no");
}
numMensajes++;
}while(rs.next());
return mensajes;
}
return mensajes;
}
public String BDrecibirMensajesAntiguos(String destinatario) throws SQLException,
ClassNotFoundException {
PreparedStatement psRecibirMensaje = connection.prepareStatement(Constants.SQL_SELECT_RECIBIR_MENSAJES_ANTIGUOS);
String mensajes = "";
int numMensajes=1;
psRecibirMensaje.clearParameters();
psRecibirMensaje.setString(1,destinatario);
ResultSet rs = psRecibirMensaje.executeQuery();
if(rs.next()){
do{
String mensaje = rs.getString(1);
String remitente = rs.getString(2);
String fechaMensaje = rs.getString(3);
String confirmacion = rs.getString(4);
mensajes += "Mensaje número: "+numMensajes+" Recibido de "+remitente+" el día "+fechaMensaje+" \n"+mensaje+" \n\n";
numMensajes++;
}while(rs.next());
return mensajes;
}
return mensajes;
}
public String BDrecibirMensajesAutor(String nombre,String autor) throws SQLException,
ClassNotFoundException {
PreparedStatement psRecibirMensaje = connection.prepareStatement(Constants.SQL_SELECT_RECIBIR_MENSAJES_AUTOR);
String mensajes = "";
int numMensajes=1;
psRecibirMensaje.clearParameters();
psRecibirMensaje.setString(1,autor);
psRecibirMensaje.setString(2,nombre);
ResultSet rs = psRecibirMensaje.executeQuery();
if(rs.next()){
do{
String mensaje = rs.getString(1);
String remitente = rs.getString(2);
String fechaMensaje = rs.getString(3);
mensajes += "Mensaje número: "+numMensajes+" \nRecibido de: "+remitente+", el día: "+fechaMensaje+" \n"+mensaje+" \n\n";
numMensajes++;
}while(rs.next());
return mensajes;
}
return mensajes;
}
public String BDbuscarMensajes(String nombre,String buscar) throws SQLException,
ClassNotFoundException {
PreparedStatement psRecibirMensaje = connection.prepareStatement(Constants.SQL_SELECT_BUSCAR_MENSAJES);
String mensajes = "Mensajes encontrados\n\n";
int numMensajes=1;
psRecibirMensaje.clearParameters();
psRecibirMensaje.setString(1,nombre);
ResultSet rs = psRecibirMensaje.executeQuery();
if(rs.next()){
do{
String mensaje = rs.getString(1);
String remitente = rs.getString(2);
String fechaMensaje = rs.getString(3);
StringTokenizer st = new StringTokenizer(mensaje, " ");
String palabra= st.nextToken();
while( st.hasMoreElements() ){
if(palabra.equals(buscar)){
mensajes += "Mensaje número: "+numMensajes+" \nRecibido de: "+remitente+", el día: "+fechaMensaje+" \n"+mensaje+" \n\n";
numMensajes++;
}
palabra= st.nextToken();
}
}while(rs.next());
return mensajes;
}
return mensajes;
}
public String BDrecibirUsuarios() throws SQLException,
ClassNotFoundException {
Statement recibirUsuarios = connection.createStatement();
String usuarios = "Usuarios disponibles en el sistema de mensajes\n\n";
ResultSet rs = recibirUsuarios.executeQuery(Constants.SQL_SELECT_USUARIOS);
if(rs.next()){
do{
String usuario = rs.getString(1);
usuarios += "- "+usuario+"\n";
}while(rs.next());
return usuarios;
}
return usuarios;
}
}
Al mismo tiempo que he ido desarrollando esta clase iba colocando todas las consultas SQL en una clase aparte, Constants.
En esta clase también podremos colocar como constantes los datos de acceso a nuestra BD en vez de ponerlos en ServicioWebBD pero eso ya queda a gusto de cada uno.
package AQUI.mypackage;
public class Constants {
public static final String SQL_LOGIN = "SELECT * FROM USUARIOS WHERE NOMBRE = ? AND CONTRASEÑA = ?";
public static final String SQL_REGISTRO = "INSERT INTO USUARIOS (NOMBRE, CONTRASEÑA) VALUES(?,?)";
public static final String SQL_NUEVO_MENSAJE = "INSERT INTO SW_MENSAJES (MENSAJE,DESTINATARIO,FECHA,ESTADO,REMITENTE,CONFIRMACION) VALUES(?,?,?,?,?,?)";
public static final String SQL_SELECT_RECIBIR_MENSAJES = "SELECT M.MENSAJE, M.REMITENTE, M.FECHA, M.CONFIRMACION" +
" FROM SW_MENSAJES M WHERE M.ESTADO = 'NO' AND M.DESTINATARIO = ?";
public static final String SQL_SELECT_RECIBIR_MENSAJES_ANTIGUOS = "SELECT M.MENSAJE, M.REMITENTE, M.FECHA, M.CONFIRMACION" +
" FROM SW_MENSAJES M WHERE M.DESTINATARIO = ?";
public static final String SQL_SELECT_RECIBIR_MENSAJES_AUTOR = "SELECT M.MENSAJE, M.REMITENTE, M.FECHA" +
" FROM SW_MENSAJES M WHERE M.REMITENTE = ? AND M.DESTINATARIO = ?";
public static final String SQL_SELECT_USUARIOS = "SELECT U.NOMBRE FROM USUARIOS U";
public static final String SQL_SELECT_BUSCAR_MENSAJES = "SELECT M.MENSAJE, M.REMITENTE, M.FECHA" +
" FROM SW_MENSAJES M WHERE M.DESTINATARIO = ?";
public static final String SQL_SELECT_RECIBIR_MENSAJES_FECHA = "SELECT M.MENSAJE, M.REMITENTE, M.FECHA, M.CONFIRMACION" +
" FROM SW_MENSAJES M WHERE M.ESTADO = 'NO' AND M.DESTINATARIO = ? " +
" AND M.FECHA = ?";
public static final String SQL_MENSAJE_LEIDO = "UPDATE SW_MENSAJES M SET M.ESTADO ='SI' WHERE M.MENSAJE = ? AND M.REMITENTE = ?";
public Constants() {
}
}
Ahora nos toca realizar la “interfaz” del servicio web, es decir, aqui implementaremos las funciones que estarán disponibles en cualquier cliente de este servicio.
El tema de la seguridad, será tratado aquí, antes de llamar a ninguna función de ServicioWebBD comprobaremos que el usuario y la contraseña son correctos.
Este código puede ser bastante más optimizado pero para lo que nos interesa nos vale de esta manera, el caso es entender como funciona un servicio web j2ee.
Generamos una nueva clase llamada: ServicioWebForo.
package AQUI.mypackage;
import java.sql.SQLException;
import java.util.Calendar;
public class ServicioWebForo {
public ServicioWebForo() {
}
public boolean login(String nombre,String contraseña)
throws ClassNotFoundException, SQLException {
ServicioWebBD swbd = new ServicioWebBD();
boolean login = swbd.BDlogin(nombre,contraseña);
return login;
}
public boolean registro(String nombre,String contraseña1,String contraseña2)
throws ClassNotFoundException, SQLException {
ServicioWebBD swbd = new ServicioWebBD();
boolean registro;
if(contraseña1.equals(contraseña2)){
registro = swbd.BDregistro(nombre,contraseña1);
}
else return false;
return registro;
}
public boolean nuevoMensaje(String mensaje, String nombre, String contraseña, String destinatario,String confirmacion) throws ClassNotFoundException,
SQLException {
if(login(nombre,contraseña)){
ServicioWebBD swbd = new ServicioWebBD();
swbd.BDnuevoMensaje(mensaje,destinatario,nombre,confirmacion);
return true;
}
else { return false;}
}
public String recibirMensaje(String nombre, String contraseña) throws ClassNotFoundException,
SQLException {
if(login(nombre,contraseña)){
ServicioWebBD swbd = new ServicioWebBD();
String nmensaje = swbd.BDrecibirMensajes(nombre);
return nmensaje;
}
else { return "Error al intentar loguearse en el sistema";}
}
public String recibirMensajesAutor(String nombre, String contraseña, String autor) throws ClassNotFoundException,
SQLException {
if(login(nombre,contraseña)){
ServicioWebBD swbd = new ServicioWebBD();
String nmensaje = swbd.BDrecibirMensajesAutor(nombre,autor);
return nmensaje;
}
else { return "Error al intentar loguearse en el sistema";}
}
public String recibirUsuarios(String nombre, String contraseña) throws ClassNotFoundException,
SQLException {
if(login(nombre,contraseña)){
ServicioWebBD swbd = new ServicioWebBD();
String nmensaje = swbd.BDrecibirUsuarios();
return nmensaje;
}
else { return "Error al intentar loguearse en el sistema";}
}
public String buscarMensajes(String nombre, String contraseña,String busqueda) throws ClassNotFoundException,
SQLException {
if(login(nombre,contraseña)){
ServicioWebBD swbd = new ServicioWebBD();
String nmensaje = swbd.BDbuscarMensajes(nombre,busqueda);
return nmensaje;
}
else { return "Error al intentar loguearse en el sistema";}
}
}
Sería conveniente probar que todas los métodos funcionan correctamente desde otra clase ya que una vez implementado el servicio web, cualquier fallo será mas dificil de encontrar.
Una vez que estemos totalmente seguros de que funciona a la perfección vamos a ServicioWebForo, lo seleccionamos en el arbol de directorios, pulsamos botón derecho y seleccionamos “Create J2EE Web Service”.
Como podemos observar nos ha creado varios documentos nuevos en nuestro proyecto, sobretodo MywebService1 (o el nombre que le hallamos dado), este fichero será el que tendremos que arrancar para hacer funcionar nuestro servicio web.
Lo seleccionamos, pulsamos botón derecho y “run”, el jdeveloper tiene su propio servidor web asi que no necesitaremos Tomcat para poder probar nuestro servicio web.
Si no nos carga la web automaticamente, dentro de la consola de compilación del jdeveloper nos habrá puesto la url para acceder, en mi caso es esta: http://zeus:8990/ServicioWebForo-ServicioWebForo-context-root/MyWebService1SoapHttpPort en cada uno dependerá del nombre de su ordenador y del puerto al que haya accedido el developer.
Si entramos en la url y somos capaces de ver todas las funciones que hemos implementado significará que nuestro servicio opera perfectamente.
Enhorabuena, ya tienes tu primer servicio web en java funcionando ;=)