In the tutorial, we show how to Producer/Consumer data from ActiveMQ with JQuery & SpringBoot RestAPIs.
Related posts:
– How to integrate JQuery Ajax POST/GET & Spring MVC | Spring Boot
– ActiveMQ Producer/Consumer + SpringBoot RestAPIs example
– RabbitMq – How to create Spring RabbitMq Publish/Subcribe pattern with SpringBoot
– How to use Spring Kafka JsonSerializer (JsonDeserializer) to produce/consume Java Object messages
Contents
Technologies
- Java 1.8
- Maven 3.3.9
- Spring Tool Suite – Version 3.9.4.RELEASE
- Spring Boot: 2.0.3.RELEASE
- ActiveMQ
- JQuery
Overview
We create a Spring JMS ActiveMQ with JMS Producer & JMS Consumer as below:
Then expose RestAPIs to POST/GET data to/from ActiveMQ:
@PostMapping(value="/api/task")
@GetMapping(value="/api/tasks")
Use JQuery Client to submit/get data from ActiveMQ via above RestAPI:
ActiveMQ state:
Practice
Backend
Setup SpringBoot project
Use SpringToolSuite to create a SpringBoot project with below dependencies:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-broker</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> |
ActiveMQ Connection Factory
ActiveMqConnectionFactoryConfig
->
package com.grokonez.activemq.config; import javax.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.JmsListenerContainerFactory; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.support.converter.MappingJackson2MessageConverter; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessageType; @Configuration public class ActiveMqConnectionFactoryConfig { @Value("${gkz.activemq.broker.url}") String brokerUrl; @Value("${gkz.activemq.borker.username}") String userName; @Value("${gkz.activemq.borker.password}") String password; /* * Initial ConnectionFactory */ @Bean public ConnectionFactory connectionFactory(){ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); connectionFactory.setBrokerURL(brokerUrl); connectionFactory.setUserName(userName); connectionFactory.setPassword(password); return connectionFactory; } @Bean // Serialize message content to json using TextMessage public MessageConverter jacksonJmsMessageConverter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setTargetType(MessageType.TEXT); converter.setTypeIdPropertyName("_type"); return converter; } /* * Used for Receiving Message */ @Bean public JmsListenerContainerFactory<?> jsaFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setMessageConverter(jacksonJmsMessageConverter()); configurer.configure(factory, connectionFactory); return factory; } /* * Used for Sending Messages. */ @Bean public JmsTemplate jmsTemplate(){ JmsTemplate template = new JmsTemplate(); template.setMessageConverter(jacksonJmsMessageConverter()); template.setConnectionFactory(connectionFactory()); return template; } } |
Add ActiveMQ configuration in application.properties
->
gkz.activemq.broker.url=tcp://localhost:61616 gkz.activemq.borker.username=admin gkz.activemq.borker.password=admin gkz.activemq.queue=gkz-queue |
Data Model
– Create Task model ->
package com.grokonez.activemq.model; public class Task { private Long id; private String name; public Task(){ } public Task(Long id, String name){ this.id = id; this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
– Create MessageStorage
to storage Task
list ->
package com.grokonez.activemq.model; import java.util.ArrayList; import java.util.List; public class MessageStorage { private List<Task> tasks = new ArrayList<Task>(); public void add(Task task) { tasks.add(task); } public void clear() { tasks.clear(); } public List<Task> getAll(){ return tasks; } } |
Create a bean for MessageStorage
->
package com.grokonez.activemq.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.grokonez.activemq.model.MessageStorage; @Configuration public class BeanConfiguration { @Bean public MessageStorage customerStorage() { return new MessageStorage(); } } |
JMS Producer
JmsProducer
send messages to ActiveMQ ->
package com.grokonez.activemq.jms.producer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Component; import com.grokonez.activemq.model.Task; @Component public class JmsProducer { @Autowired JmsTemplate jmsTemplate; @Value("${gkz.activemq.queue}") String queue; public void send(Task task){ jmsTemplate.convertAndSend(queue, task); } } |
JMS Consumer
JmsConsumer
recieves messages from ActiveMQ ->
package com.grokonez.activemq.jms.consumer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; import com.grokonez.activemq.model.MessageStorage; import com.grokonez.activemq.model.Task; @Component public class JmsConsumer { @Autowired private MessageStorage taskStorage; @JmsListener(destination = "${gkz.activemq.queue}", containerFactory="jsaFactory") public void receive(Task task){ taskStorage.add(task); } } |
Rest APIs
RestAPI
->
package com.grokonez.activemq.controller; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.grokonez.activemq.jms.producer.JmsProducer; import com.grokonez.activemq.model.MessageStorage; import com.grokonez.activemq.model.Task; @RestController public class RestAPIs { @Autowired JmsProducer jmsProducer; @Autowired private MessageStorage taskStorage; @PostMapping(value="/api/task") public Task postCustomer(@RequestBody Task task){ jmsProducer.send(task); return task; } @GetMapping(value="/api/tasks") public List<Task> getAll(){ List<Task> tasks = new ArrayList<Task>(taskStorage.getAll()); taskStorage.clear(); return tasks; } } |
Frontend
Index.html
/src/main/resources/templates/index.html
->
<!DOCTYPE HTML> <html> <head> <title>JQuery + SpringBoot + ActiveMQ Example</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script> <script src="/js/postrequest.js"></script> <script src="/js/getrequest.js"></script> </head> <body> <div class="container, col-sm-4" > <h3>Task Form</h3> <div> <form id="taskForm"> <div class="form-group"> <label for="id">Id:</label> <input type="text" class="form-control" id="id" placeholder="Enter Id" name="id"> </div> <div class="form-group"> <label for="name">Name:</label> <input type="text" class="form-control" id="name" placeholder="Enter Name" name="name"> </div> <button type="submit" class="btn btn-dark">Submit Task</button> </form> </div> <br> <div id="postResultDiv"> </div> <div> <button id="getAllTasks" type="button" class="btn btn-dark">Process Tasks</button> <div id="getResultDiv"> <br> <ul> </ul> </div> </div> </div> </body> </html> |
Post/Get Ajax JQuery
resources/static/js/postrequest.js
->
$( document ).ready(function() { // SUBMIT FORM $("#taskForm").submit(function(event) { // Prevent the form from submitting via the browser. event.preventDefault(); ajaxPost(); }); function ajaxPost(){ // PREPARE FORM DATA var formData = { id : $("#id").val(), name : $("#name").val() } // DO POST $.ajax({ type : "POST", contentType : "application/json", url : window.location + "api/task", data : JSON.stringify(formData), dataType : 'json', success : function(result) { $("#postResultDiv").html("<p style='padding-left:20px'>" + "Post Successfully! <br>" + "---> Task's Info: id = " + result.id + ", name = " + result.name + "</p>"); console.log(result); }, error : function(e) { alert("Error!") console.log("ERROR: ", e); } }); // Reset FormData after Posting resetData(); } function resetData(){ $("#id").val(""); $("#name").val(""); } }) |
resources/static/js/getrequest.js
->
$( document ).ready(function() { // GET REQUEST $("#getAllTasks").click(function(event){ event.preventDefault(); ajaxGet(); }); // DO GET function ajaxGet(){ $.ajax({ type : "GET", url : window.location + "api/tasks", success: function(result){ $('#getResultDiv ul').empty(); $.each(result, function(i, task){ var task = "Task -> id = " + task.id + ", name = " + task.name + "<br>"; $('#getResultDiv ul').append("<li>" + task + "</li>"); }); console.log("Success: ", result); }, error : function(e) { $("#getResultDiv").html("<strong>Error</strong>"); console.log("ERROR: ", e); } }); } }) |