miércoles, 24 de julio de 2013

Cómo implementar un API REST en Java/JEE

by Guido García on 31/07/2011
Me pidieron consejo hace unos días sobre este tema.  Personalmente, a día de hoy sólo recomiendo estas opciones, muy parecidas y que se basan en anotar las clases Java:
  • El especificación JAX-RS, incluida de serie en Java EE 6. Hay varias implementaciones, entre otras Jersey, Restlet o Resteasy. Esta última es la que utiliza JBoss y que he utilizado sin problemas también con JBoss 5.1.
@Path("/product/{id}")
public class ProductResource {

    @GET
    public String get(@PathParam("id") String id) {
        return ...;
    }
}












  • Spring MVC. Imagino que acabará convergiendo con JAX-RS ya que no tiene demasiado sentido mantener sus propias anotaciones. Yo he sido bastante fan de Spring, al que pronto dedicaré una serie de artículos completos. Fui reacio un tiempo por la documentación oficial, excesivamente dura para un novato, pero siempre han ido un paso por delante, son más ágiles que las JSR, que en ocasiones acaban pariendo clones de Spring (por ejemplo el JSR 330 para la inyección de dependencias).
@Controller
public class ProductResource {
    @RequestMapping(value="/product/{id}", method=RequestMethod.GET)
    public Product get(@PathVariable int id) {
        return ...;
    }
}
  • Para proyectos muy simples en los que no se quiera incluir ninguna dependencia, la esperada especificación de Servlets 3.0/JSR 315 (también de serie en JEE6 e implementada en Tomcat 7, Jetty 7, Glassfish 3, etc) incluye la anotación @WebServlet.  No la he utilizado nunca para estos fines, pero con algo más de esfuerzo de desarrollo en el procesamiento de las peticiones, podría valer.

@WebServlet(urlPatterns={"/product/*"}
public class ProductResource extends HttpServlet {
    public void service(ServletRequest req, ServletResponse res)
            throws IOException, ServletException {
        // Esta parte sería más fea
        // Parsear la URL para extraer parámetros...
    }
}

Mi consejo

Es difícil decantarse porque las diferencias acaban siendo sutiles. Dejo algunas consideraciones que se podrían tener en cuenta:
  • Spring mola. Si ya utilizáis o conocéis Spring, usad Spring MVC, corre en un simple Tomcat sin más. Podréis aprovechar otras de sus deliciosas ventajas (inyección de dependencias, validaciones, etc).
  • Si ya usáis un servidor de aplicaciones JEE6 (p.e. JBoss) usad JAX-RS. Si estáis usando Netbeans también es un punto a favor de JAX-RS porque viene bien integrado.
  • Si no queréis utilizar un servidor de aplicaciones JEE6, usad Spring. Si queréis hacer algo simple (p.e. un piloto o una aplicación que va a recibir poca carga), utilizad Restlet que tiene una extensión para JAX-RS  y corre como una aplicación Java, sin necesidad de ningún tipo de servidor web o de aplicaciones.
Espero vuestros comentarios, aunque sea para contar lo fácil que sería todo esto con Ruby on Rails.
Disclaimer: Todos los extractos de código del artículo están escritos sin probar.

jueves, 18 de julio de 2013

No se puede acceder a una vista en la base de datos MySQL debido al error: "'view_name' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them"

Síntomas

El mismo usuario de la base de datos no puede utilizar una vista creada en una base de datos MySQL alojada. Se obtiene el siguiente error:
CREATE VIEW temp_view as
    SELECT * from TEMP_TABLE1;

SELECT * FROM temp_view; 
ERROR 1356 (HY000): View 'db1004420_test_customer.temp_view' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them

Resolución

Especifique de forma explícita que debe usarse el modelo de seguridad INVOKER mientras se ejecute la vista tal y como puede verse a continuación:
CREATE  SQL SECURITY INVOKER VIEW temp_view as
    SELECT * from TEMP_TABLE1; 

martes, 9 de julio de 2013

JPA Modificar conexion Hibernate por codigo (persistense.xml)


Map addedOrOverridenProperties = new HashMap();

// Let's suppose we are using Hibernate as JPA provider
addedOrOverridenProperties.put("hibernate.show_sql", true);
addedOrOverridenProperties.put("hibernate.connection.url", Configuracion.getProperty("Bd_PcsCsv_Str"));
addedOrOverridenProperties.put("hibernate.connection.username", Configuracion.getProperty("Bd_PcsCsv_Usr"));
addedOrOverridenProperties.put("hibernate.connection.password", Configuracion.getProperty("Bd_PcsCsv_Pas"));

Persistence.createEntityManagerFactory([PERSISTENCE_UNIT_NAME], addedOrOverridenProperties); 

lunes, 8 de julio de 2013

Maven - slf4j con log4j

En pom.xml

<project>
...
<dependencies>
...
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-log4j12</artifactId>
   <version>1.7.7</version>
  </dependency>
...
</dependencies>
...
</project>

Solo es necesaria esta dependencia, internamente carga las dependencias que necesita.
En la clase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public static Logger logger = LoggerFactory.getLogger(Clase.class); 

Mysql - Duplicar una base de datos

Desde cmd, ir a la carpeta bin donde esta instalado el mysql y ejecutar los sgtes comandos
  1. mysqldump -u nombre_usuario -p --routines  nombre_base_original > nombre_fichero_volcado
  2. Para cargar se utiliza el comando mysql
    mysql
    -u nombre_usuario -p nombre_base_copia <  nombre_fichero_volcado

viernes, 5 de julio de 2013

Servlet como demonio (con Timer)

Se supone que esta trabajando en un proyecto tipo WEB.
Desde MyEclipse crear un nuevo Servlet, este creara la estructura necesaria para el ej.

 Agregar en el init() del servlet

// definir como variable estatica
public static Timer timer = new Timer(true);

 /**
  * Initialization of the servlet. 

  *
  * @throws ServletException
  *             if an error occurs
  */
 public void init() throws ServletException {

  TimerTask timerTask = new TimerTask() {
   @Override
   public void run() {
    // Aqui todo el codigo
    System.out.println("Probando timer");
   }
  }; // schedule del timer cada 10 segundos en este caso
  timer.schedule(timerTask, 0, 10000);
 }

En el web.XML

Agregar a la línea del servelt:


  Chequeo de Bd para eliminar timeout
  CheckBD
  CheckBD
  cl.intelidata.servlet.CheckBD
  1
 

 Si trabaja con maven agregar la sgte dependencia..

   <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.4</version>
      <scope>compile</scope>
    </dependency>

Ulilizando myeclipse como ide.
Mas info de servlet en: http://chuwiki.chuidiang.org/index.php?title=Servlet_y_Maven