Diferencia entre revisiones de «JMS con Spring Roo»
Línea 1: | Línea 1: | ||
Con el uso de [[JMS]] podemos hacer asincrónica la ocurrencia de un determinado evento. | Con el uso de [[JMS]] podemos hacer asincrónica la ocurrencia de un determinado evento. | ||
− | |||
− | == | + | == Comandos Roo para JMS == |
+ | |||
+ | Para crear una cola en memoria: | ||
+ | <code> | ||
+ | jms setup --provider ACTIVEMQ_IN_MEMORY --destinationType QUEUE --destinationName unNombreJndi | ||
+ | </code> | ||
− | |||
+ | Para crear un jmsTemplate que encole mensajes en la queue creada anteriormente: | ||
<code> | <code> | ||
− | + | field jms template --class com.dosideas.roo.unpackage.UnaClase --fieldName jmsTemplate | |
− | |||
− | |||
− | |||
</code> | </code> | ||
− | |||
+ | Para crear un listener que consuma los mensajes de la queue: | ||
<code> | <code> | ||
− | + | jms listener class --class com.dosideas.roo.unpackage.UnaClaseListener --destinationName unNombreJndi --destinationType QUEUE | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</code> | </code> | ||
+ | |||
+ | == Integrando el envío de mensajes JMS a una aplicación Roo == | ||
+ | |||
+ | Tomamos el [[Ejemplo de proyecto web ABM con Spring Roo]] y hacemos que una vez creado un nuevo pedido de pizza, se envíe un mensaje a la consola del servidor. Esto último de manera asincrónica. | ||
+ | |||
+ | |||
+ | === Alternativa 1: Agregar la lógica de envío de mensajes en el controller === | ||
* Ejecutamos el comando JMS de Spring Roo para crear una cola en memoria: | * Ejecutamos el comando JMS de Spring Roo para crear una cola en memoria: | ||
− | |||
<code> | <code> | ||
jms setup --provider ACTIVEMQ_IN_MEMORY --destinationType QUEUE --destinationName dosIdeasQueue | jms setup --provider ACTIVEMQ_IN_MEMORY --destinationType QUEUE --destinationName dosIdeasQueue | ||
Línea 41: | Línea 41: | ||
</code> | </code> | ||
− | * Modificamos la configuración de | + | * Modificamos la configuración de namespaces de MQ. En el archivo applicationContext-jms.xml sacamos la versión del xsd de activemq, quedando http://activemq.apache.org/schema/core/activemq-core.xsd. Para que no muestre el error desde el IDE ver [[http://www.bigsoft.co.uk/blog/index.php/2009/02/01/invalid-activemq-schema-name-space como modificar las preferencias de Eclipse]] |
− | |||
− | |||
+ | * Comentamos la anotacion en el aspecto de la entidad: | ||
<code> | <code> | ||
− | + | privileged aspect PedidoController_Roo_Controller { | |
− | + | ||
− | + | //@RequestMapping(value = "/pedido", method = RequestMethod.POST) | |
− | + | public String PedidoController.create | |
</code> | </code> | ||
− | Cada vez que se ejecuta un comando, Spring Roo re-escribe | + | Cada vez que se ejecuta un comando, Spring Roo re-escribe esta anotación en el aspecto, por lo que deberá ser comentada nuevamente. De lo contrario queda anotado en el aspecto y en el controller de la entidad el mismo path y al crear un pedido en runtime, da error. |
− | + | * Agregamos un método "crear" en el Controller para crear el pedido y donde vamos a inyectar el uso de mensajeria para mandar el aviso: | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<code> | <code> | ||
− | + | public class PedidoController { | |
− | + | @RequestMapping(value = "/pedido", method = RequestMethod.POST) | |
− | + | public String crear(@Valid Pedido pedido, BindingResult result, ModelMap modelMap) { | |
− | + | System.out.println("Estoy en PedidoController - crear"); | |
+ | String resultado = create(pedido, result, modelMap); | ||
+ | return resultado; | ||
+ | } | ||
+ | } | ||
</code> | </code> | ||
− | * | + | * Ejecutamos el comando de Spring Roo para crear el template en PedidoController: |
<code> | <code> | ||
− | + | field jms template --class com.dosideas.roo.oracle.web.PedidoController --fieldName jmsTemplate | |
− | + | Managed SRC_MAIN_JAVA\com\dosideas\roo\oracle\web\PedidoController.java | |
− | + | Managed SRC_MAIN_JAVA\com\dosideas\roo\oracle\web\PedidoController.java | |
− | + | Managed SRC_MAIN_JAVA\com\dosideas\roo\oracle\web\PedidoController_Roo_Controller.aj | |
− | |||
− | |||
</code> | </code> | ||
Línea 98: | Línea 93: | ||
</code> | </code> | ||
− | * Ejecutamos | + | * Ejecutamos el comando de Spring Roo para crear una clase listener que consuma los mensajes: |
<code> | <code> | ||
− | + | jms listener class --class com.dosideas.roo.oracle.jms.JmsQueueListener --destinationName dosIdeasQueue --destinationType QUEUE | |
+ | Created SRC_MAIN_JAVA\com\dosideas\roo\oracle\jms | ||
+ | Created SRC_MAIN_JAVA\com\dosideas\roo\oracle\jms\JmsQueueListener.java | ||
+ | Managed SRC_MAIN_RESOURCES\META-INF\spring\applicationContext-jms.xml | ||
</code> | </code> | ||
− | + | * En el onMessage, escribimos el mensaje recibido: | |
− | + | <code> | |
+ | public class JmsQueueListener { | ||
− | + | public void onMessage(Object message) { | |
− | + | System.out.println("Pedido recibido por JMS: " + message); | |
− | + | } | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</code> | </code> | ||
− | |||
− | * Ejecutamos el | + | * Ejecutamos la aplicación, creamos un pedido y vemos el siguiente mensaje en consola: |
<code> | <code> | ||
− | + | Pedido Enviado:Id: 1, Version: 0, Nombre: aa, Direccion: aa, Importe: 11.0, FechaEntrega: Tue Jul 27 00:00:00 VET 2010, Pizzas: 0 | |
− | |||
− | |||
− | |||
</code> | </code> | ||
− | * | + | === Alternativa 2: Utilizar una anotacion === |
+ | |||
+ | * Los primeros 2 puntos son iguales a la alternativa 1. | ||
+ | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | * Agregamos una capa de negocio para la funcionalidad que agregamos: Creamos una clase JmsQueueSenderBoImpl anotada con @Service y le creamos un atributo template de envío de mensajes con el comando de roo ya mencionado: | ||
<code> | <code> | ||
− | + | field jms template --class com.dosideas.roo.oracle.business.JmsQueueSenderBoImpl --fieldName jmsTemplate | |
− | |||
− | |||
− | |||
− | |||
− | |||
</code> | </code> | ||
− | + | La clase queda entonces así: | |
<code> | <code> | ||
Línea 171: | Línea 152: | ||
</code> | </code> | ||
− | * En la entidad Pedido.java, agregamos el uso de un servicio anotado en la clase de negocio: | + | * En la entidad Pedido.java, agregamos el uso de un servicio anotado en la clase de negocio: Usamos la anotación Jpa @PostPersist para indicar que primero debe persistir la entidad y luego realizar el envío del mensaje. |
<code> | <code> | ||
Línea 181: | Línea 162: | ||
senderBoImpl.sendMessage("Pedido Enviado:" + this); | senderBoImpl.sendMessage("Pedido Enviado:" + this); | ||
} | } | ||
+ | </code> | ||
+ | |||
+ | * Ejecutamos el comando de Spring Roo para crear una clase listener: | ||
+ | |||
+ | <code> | ||
+ | jms listener class --class com.dosideas.roo.oracle.jms.JmsQueueListener --destinationName dosIdeasQueue --destinationType QUEUE | ||
+ | </code> | ||
+ | |||
+ | * En el onMessage, escribimos el mensaje que recibimos: | ||
+ | <code> | ||
+ | public class JmsQueueListener { | ||
+ | |||
+ | public void onMessage(Object message) { | ||
+ | System.out.println("Pedido recibido por JMS: " + message); | ||
+ | } | ||
+ | } | ||
</code> | </code> | ||
Revisión del 21:09 28 jul 2010
Con el uso de JMS podemos hacer asincrónica la ocurrencia de un determinado evento.
Contenido
Comandos Roo para JMS
Para crear una cola en memoria:
jms setup --provider ACTIVEMQ_IN_MEMORY --destinationType QUEUE --destinationName unNombreJndi
Para crear un jmsTemplate que encole mensajes en la queue creada anteriormente:
field jms template --class com.dosideas.roo.unpackage.UnaClase --fieldName jmsTemplate
Para crear un listener que consuma los mensajes de la queue:
jms listener class --class com.dosideas.roo.unpackage.UnaClaseListener --destinationName unNombreJndi --destinationType QUEUE
Integrando el envío de mensajes JMS a una aplicación Roo
Tomamos el Ejemplo de proyecto web ABM con Spring Roo y hacemos que una vez creado un nuevo pedido de pizza, se envíe un mensaje a la consola del servidor. Esto último de manera asincrónica.
Alternativa 1: Agregar la lógica de envío de mensajes en el controller
- Ejecutamos el comando JMS de Spring Roo para crear una cola en memoria:
jms setup --provider ACTIVEMQ_IN_MEMORY --destinationType QUEUE --destinationName dosIdeasQueue
Created SRC_MAIN_RESOURCES\META-INF\spring\applicationContext-jms.xml
Managed SRC_MAIN_RESOURCES\META-INF\spring\applicationContext-jms.xml
Managed ROOT\pom.xml
Managed ROOT\pom.xml
Managed ROOT\pom.xml
Managed ROOT\pom.xml
Managed ROOT\pom.xml
Managed ROOT\pom.xml
- Modificamos la configuración de namespaces de MQ. En el archivo applicationContext-jms.xml sacamos la versión del xsd de activemq, quedando http://activemq.apache.org/schema/core/activemq-core.xsd. Para que no muestre el error desde el IDE ver [como modificar las preferencias de Eclipse]
- Comentamos la anotacion en el aspecto de la entidad:
privileged aspect PedidoController_Roo_Controller {
//@RequestMapping(value = "/pedido", method = RequestMethod.POST) public String PedidoController.create
Cada vez que se ejecuta un comando, Spring Roo re-escribe esta anotación en el aspecto, por lo que deberá ser comentada nuevamente. De lo contrario queda anotado en el aspecto y en el controller de la entidad el mismo path y al crear un pedido en runtime, da error.
- Agregamos un método "crear" en el Controller para crear el pedido y donde vamos a inyectar el uso de mensajeria para mandar el aviso:
public class PedidoController {
@RequestMapping(value = "/pedido", method = RequestMethod.POST) public String crear(@Valid Pedido pedido, BindingResult result, ModelMap modelMap) { System.out.println("Estoy en PedidoController - crear"); String resultado = create(pedido, result, modelMap); return resultado; }
}
- Ejecutamos el comando de Spring Roo para crear el template en PedidoController:
field jms template --class com.dosideas.roo.oracle.web.PedidoController --fieldName jmsTemplate
Managed SRC_MAIN_JAVA\com\dosideas\roo\oracle\web\PedidoController.java
Managed SRC_MAIN_JAVA\com\dosideas\roo\oracle\web\PedidoController.java
Managed SRC_MAIN_JAVA\com\dosideas\roo\oracle\web\PedidoController_Roo_Controller.aj
- En el controller, agregamos el uso de la mensajería -sendMessage-:
public class PedidoController {
@RequestMapping(value = "/pedido", method = RequestMethod.POST) public String crear(@Valid Pedido pedido, BindingResult result, ModelMap modelMap) { System.out.println("Estoy en PedidoController - crear"); String resultado = create(pedido, result, modelMap); sendMessage("Pedido Enviado:" + pedido); return resultado; }
public void sendMessage(Object messageObject) { jmsTemplate.convertAndSend(messageObject); }
}
- Ejecutamos el comando de Spring Roo para crear una clase listener que consuma los mensajes:
jms listener class --class com.dosideas.roo.oracle.jms.JmsQueueListener --destinationName dosIdeasQueue --destinationType QUEUE
Created SRC_MAIN_JAVA\com\dosideas\roo\oracle\jms
Created SRC_MAIN_JAVA\com\dosideas\roo\oracle\jms\JmsQueueListener.java
Managed SRC_MAIN_RESOURCES\META-INF\spring\applicationContext-jms.xml
- En el onMessage, escribimos el mensaje recibido:
public class JmsQueueListener {
public void onMessage(Object message) { System.out.println("Pedido recibido por JMS: " + message); }
}
- Ejecutamos la aplicación, creamos un pedido y vemos el siguiente mensaje en consola:
Pedido Enviado:Id: 1, Version: 0, Nombre: aa, Direccion: aa, Importe: 11.0, FechaEntrega: Tue Jul 27 00:00:00 VET 2010, Pizzas: 0
Alternativa 2: Utilizar una anotacion
- Los primeros 2 puntos son iguales a la alternativa 1.
- Agregamos una capa de negocio para la funcionalidad que agregamos: Creamos una clase JmsQueueSenderBoImpl anotada con @Service y le creamos un atributo template de envío de mensajes con el comando de roo ya mencionado:
field jms template --class com.dosideas.roo.oracle.business.JmsQueueSenderBoImpl --fieldName jmsTemplate
La clase queda entonces así:
package com.dosideas.roo.oracle.business;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Service;
@Service public class JmsQueueSenderBoImpl {
@Autowired private transient JmsTemplate jmsTemplate;
public void sendMessage(Object messageObject) { jmsTemplate.convertAndSend(messageObject); }
}
- En la entidad Pedido.java, agregamos el uso de un servicio anotado en la clase de negocio: Usamos la anotación Jpa @PostPersist para indicar que primero debe persistir la entidad y luego realizar el envío del mensaje.
@Autowired private transient JmsQueueSenderBoImpl senderBoImpl; @PostPersist public void crear() { senderBoImpl.sendMessage("Pedido Enviado:" + this); }
- Ejecutamos el comando de Spring Roo para crear una clase listener:
jms listener class --class com.dosideas.roo.oracle.jms.JmsQueueListener --destinationName dosIdeasQueue --destinationType QUEUE
- En el onMessage, escribimos el mensaje que recibimos:
public class JmsQueueListener {
public void onMessage(Object message) { System.out.println("Pedido recibido por JMS: " + message); }
}
- Ejecutamos la aplicación, creamos un pedido y vemos el siguiente mensaje en consola:
Pedido Enviado:Id: 1, Version: 0, Nombre: aa, Direccion: aa, Importe: 11.0, FechaEntrega: Tue Jul 27 00:00:00 VET 2010, Pizzas: 0