Diferencia entre revisiones de «JMS con Spring Roo»
(Página creada con 'Con el uso de JMS podemos hacer asincrónica la ocurrencia de un determinado evento. Entonces, tomamos el Ejemplo de proyecto web ABM con Spring Roo y hacemos que una v…') |
(→Alternativa 1: Agregar la lógica en el controller) |
||
(No se muestran 20 ediciones intermedias de 2 usuarios) | |||
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 == |
− | == Alternativa 2: | + | 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> | ||
+ | field jms template --class com.dosideas.roo.unpackage.UnaClase --fieldName jmsTemplate | ||
+ | </code> | ||
+ | |||
+ | Para crear un listener que consuma los mensajes de la queue: | ||
+ | <code> | ||
+ | jms listener class --class com.dosideas.roo.unpackage.UnaClaseListener --destinationName unNombreJndi --destinationType QUEUE | ||
+ | </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. | ||
+ | |||
+ | === Paso 1: Crear una queue === | ||
+ | |||
+ | * Ejecutamos el comando JMS de Spring Roo para crear una cola en memoria: | ||
+ | <code> | ||
+ | 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 | ||
+ | </code> | ||
+ | |||
+ | * 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]] | ||
+ | |||
+ | === Paso 2: Agregar lógica de envío de mensajes === | ||
+ | ==== Alternativa 1: Agregar la lógica en el controller ==== | ||
+ | |||
+ | * Comentamos la anotacion en el aspecto de la entidad: | ||
+ | <code> | ||
+ | privileged aspect PedidoController_Roo_Controller { | ||
+ | |||
+ | //@RequestMapping(value = "/pedido", method = RequestMethod.POST) | ||
+ | public String PedidoController.create | ||
+ | </code> | ||
+ | |||
+ | 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> | ||
+ | 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> | ||
+ | |||
+ | * Ejecutamos el comando de Spring Roo para crear el template en PedidoController: | ||
+ | |||
+ | <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> | ||
+ | |||
+ | * En el controller, agregamos el uso de la mensajería -sendMessage-: | ||
+ | |||
+ | <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); | ||
+ | sendMessage("Pedido Enviado:" + pedido); | ||
+ | return resultado; | ||
+ | } | ||
+ | |||
+ | public void sendMessage(Object messageObject) { | ||
+ | jmsTemplate.convertAndSend(messageObject); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== Alternativa 2: Agregar la lógica en la entidad ==== | ||
+ | |||
+ | * 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> | ||
+ | field jms template --class com.dosideas.roo.oracle.business.JmsQueueSenderBoImpl --fieldName jmsTemplate | ||
+ | </code> | ||
+ | |||
+ | La clase queda entonces así: | ||
+ | |||
+ | <code> | ||
+ | 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); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | * 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> | ||
+ | @Autowired | ||
+ | private transient JmsQueueSenderBoImpl senderBoImpl; | ||
+ | |||
+ | @PostPersist | ||
+ | public void crear() { | ||
+ | senderBoImpl.sendMessage("Pedido Enviado:" + this); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | === Paso 3: Crear un consumidor de los mensajes de la queue === | ||
+ | * Ejecutamos el comando de Spring Roo para crear una clase listener que consuma los mensajes: | ||
+ | |||
+ | <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> | ||
+ | |||
+ | * Ejecutamos la aplicación, creamos un pedido y vemos el siguiente mensaje en consola: | ||
+ | |||
+ | <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> | ||
− | |||
== Ver tambien == | == Ver tambien == | ||
+ | |||
* [[Spring Roo]] | * [[Spring Roo]] | ||
[[Category: Spring Framework]] | [[Category: Spring Framework]] |
Revisión actual del 21:21 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.
Paso 1: Crear una queue
- 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]
Paso 2: Agregar lógica de envío de mensajes
Alternativa 1: Agregar la lógica en el controller
- 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); }
}
Alternativa 2: Agregar la lógica en la entidad
- 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); }
Paso 3: Crear un consumidor de los mensajes de la queue
- 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
- 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