Angular 6 + SpringBoot RestAPIs + ActiveMQ Producer/Consumer example

In the tutorial, we show how to Producer/Consumer data from ActiveMQ with Angular 6 & SpringBoot RestAPIs.

Related posts:
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

Related Pages:

Technologies

  • Java 1.8
  • Maven 3.3.9
  • Spring Tool Suite – Version 3.9.4.RELEASE
  • Spring Boot: 2.0.3.RELEASE
  • ActiveMQ
  • Angular 6

Overview

We create a Spring JMS ActiveMQ with JMS Producer & JMS Consumer as below:

Angular-6-Spring-Boot-RestAPI-ActiveMQ-Producer-Consumer +springboot-project-structure

Angular-6-Spring-Boot-RestAPI-ActiveMQ-Producer-Consumer + activemq-producer-consumer

Then expose RestAPIs to POST/GET data to/from ActiveMQ:

  • @PostMapping(value="/api/task")
  • @GetMapping(value="/api/tasks")

Use Angular Client to submit/get data from ActiveMQ via above RestAPI:

Angular-6-Spring-Boot-RestAPI-ActiveMQ-Producer-Consumer +add-new-task

Angular-6-Spring-Boot-RestAPI-ActiveMQ-Producer-Consumer +processing-all-task

ActiveMQ state:

Angular-6-Spring-Boot-RestAPI-ActiveMQ-Producer-Consumer + activemq-state

Practice

SpringBoot Backend

Setup SpringBoot project

Use SpringToolSuite to create a SpringBoot project with below dependencies:

<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.ozenero.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.ozenero.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.ozenero.activemq.model;

import java.util.ArrayList;
import java.util.List;

public class MessageStorage {
	private List tasks = new ArrayList();
	
	public void add(Task task) {
		tasks.add(task);
	}
	
	public void clear() {
		tasks.clear();
	}
	
	public List getAll(){
		return tasks;
	}
}

Create a bean for MessageStorage ->


package com.ozenero.activemq.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.ozenero.activemq.model.MessageStorage;

@Configuration
public class BeanConfiguration {

  @Bean
  public MessageStorage customerStorage() {
    return new MessageStorage();
  }
}

JMS Producer

JmsProducer send messages to ActiveMQ ->


package com.ozenero.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.ozenero.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.ozenero.activemq.jms.consumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import com.ozenero.activemq.model.MessageStorage;
import com.ozenero.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.ozenero.activemq.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
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.ozenero.activemq.jms.producer.JmsProducer;
import com.ozenero.activemq.model.MessageStorage;
import com.ozenero.activemq.model.Task;

@CrossOrigin(origins = "http://localhost:4200")
@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 getAll(){
		List tasks = new ArrayList(taskStorage.getAll());
		taskStorage.clear();
		return tasks;
	}
}

Angular Frontend

Setup Angular Project

Setup guide:

  • Create Angular project with commandline: ng new angular6-client
  • Generate Task model with commandline ng generate class Task
  • Generate TaskService with commandline ng generate service Task
  • Generate TaskComponent with commandline ng generate component Task

Then install Bootstrap by commandline ->

>npm install bootstrap jquery --save

Configure installed Bootstrap & JQuery in angular.json file ->


...
 
"styles": [
  "src/styles.css",
  "node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
  "node_modules/jquery/dist/jquery.min.js",
  "node_modules/bootstrap/dist/js/bootstrap.min.js"
]
 
...

Data Model

Task ->


export class Task {
    id: number;
    name: string;
}

Implement HttpClient Service

TaskService ->


import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Task } from './task';
 
const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
 
@Injectable({
  providedIn: 'root'
})
export class   {
  constructor( 
    private http: HttpClient
  ) { }
 
  getTasks (): Observable {
    return this.http.get("http://localhost:8080/api/tasks")
  }
  
  addTask (task: Task): Observable {
    return this.http.post("http://localhost:8080/api/task", task, httpOptions);
  }
}

Implement ActiveMQ Component

activemq-task.component.html ->

<div [hidden]="submitted">
    <h3>Add Task</h3>
    <form #addTaskForm="ngForm">

      <div class="form-group">
        <label for="id">Id</label>
        <input type="number" class="form-control" id="id" 
        placeholder="Enter Id"
        required
        [(ngModel)]="task.id" name="id" #id="ngModel">
        <div [hidden]="id.valid || id.pristine"
              class="alert alert-danger">
            Id is required
        </div>
      </div>
 
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name" placeholder="Enter Task Name" 
        required
        [(ngModel)]="task.name" name="name" #name="ngModel">
        <div [hidden]="name.valid || name.pristine"
             class="alert alert-danger">
            Name is required
        </div>
      </div>  
      <button class="btn btn-dark" (click)="addTask()" [disabled]="!addTaskForm.form.valid">Add Task</button>
    </form>
</div>
 
<div [hidden]="!submitted">
  <p>Submitted Successfully! -> <span class="badge badge-dark">Task's Info -> Id: {{task.id}}, Name: {{task.name}}</span></p>
	<div class="btn-group btn-group-sm">
    <button class="btn btn-secondary" (click)="newTask(); addTaskForm.reset();">New Task</button>
    <button class="btn btn-secondary" (click)="processTasks();">Process Tasks</button>
  </div>
  <div [hidden]="!processing">
      <br>
      <h5>Processing</h5>
      <ul>
        <li *ngFor="let task of tasks">
          Task id = {{task.id}}, name = {{task.name}}
        </li>
      </ul>
  </div>
</div>

activemq-task.component.ts ->


import { Component, OnInit } from '@angular/core';
import { Task } from '../task';
import { TaskService } from '../task.service';

@Component({
  selector: 'app-activemq-task',
  templateUrl: './activemq-task.component.html',
  styleUrls: ['./activemq-task.component.css']
})
export class ActivemqTaskComponent{

  task = new Task();
  tasks: Task[];
  submitted = false;
  processing = false;

  constructor(private taskService: TaskService) { }

  newTask(): void {
    this.submitted = false;
    this.processing = false;
    this.task = new Task();
  }
 
  addTask() {
    this.submitted = true;
    this.taskService.addTask(this.task)
    .subscribe();
  }

  processTasks(){
    this.processing = true;
    return this.taskService.getTasks()
                .subscribe(
                  tasks => {
                    console.log(tasks);
                    this.tasks = tasks;
                  }
                );
  }
}

– Create style file assets/forms.css ->


.ng-valid[required], .ng-valid.required  {
    border-left: 5px solid rgba(32, 77, 32, 0.623);
}
 
.ng-invalid:not(form)  {
    border-left: 5px solid rgb(148, 27, 27);
}

– Add above style file assets/forms.css to index.html file ->

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Angular6Client</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="stylesheet" href="assets/forms.css">
</head>
<body>
  <app-root></app-root>
</body>
</html>

– Add app-activemq-task selector to app.component.html file ->

<div class="container">
  <div class="row">
    <div class="col-sm-4"> 
      <app-activemq-task></app-activemq-task>
   </div>
  </div>
</div>

Run & Check Results

– Build & Run SpringBoot project with commandlines {mvn clean install, mvn spring-boot:run}.
– Run the Angular project as commandline: ng serve

Add Task ->

Angular-6-Spring-Boot-RestAPI-ActiveMQ-Producer-Consumer +add-new-task

Angular-6-Spring-Boot-RestAPI-ActiveMQ-Producer-Consumer +submit-successfully

Get Tasks ->

Angular-6-Spring-Boot-RestAPI-ActiveMQ-Producer-Consumer +processing-all-task

ActiveMQ state ->

Angular-6-Spring-Boot-RestAPI-ActiveMQ-Producer-Consumer + activemq-state

SourceCode

SpringBootRestAPIsActiveMQ
Angular6-Client

86 thoughts on “Angular 6 + SpringBoot RestAPIs + ActiveMQ Producer/Consumer example”

  1. Thanks for discussing your ideas on this blog. Furthermore, a fable regarding the lenders intentions if talking about property foreclosures is that the standard bank will not getreceive my repayments. There is a degree of time which the bank is going to take payments in some places. If you are as well deep within the hole, they’ll commonly call that you pay the actual payment completely. However, that doesn’t mean that they will not take any sort of payments at all. In case you and the financial institution can be capable to work anything out, this foreclosure practice may halt. However, when you continue to neglect payments underneath the new strategy, the foreclosures process can just pick up exactly where it was left off.

  2. 850602 814134An fascinating discussion may be valued at comment. I do believe that you just write read far more about this subject, it may not often be a taboo subject but normally persons are too few to dicuss on such topics. To a higher. Cheers 665748

  3. I’m not sure where you’re getting your information, but good topic. I needs to spend some time learning more or understanding more. Thanks for excellent info I was looking for this information for my mission.

  4. Thanks so much for giving everyone an exceptionally special possiblity to read articles and blog posts from this website. It really is so awesome plus full of a great time for me personally and my office acquaintances to search the blog the equivalent of thrice a week to read through the new issues you will have. Of course, I’m usually happy with all the great creative ideas you give. Selected 1 tips on this page are in fact the simplest we’ve ever had.

  5. Good web site! I truly love how it is easy on my eyes and the data are well written. I’m wondering how I might be notified whenever a new post has been made. I’ve subscribed to your RSS which must do the trick! Have a great day!

  6. Have you ever considered publishing an e-book or guest authoring on other sites? I have a blog centered on the same subjects you discuss and would love to have you share some stories/information. I know my visitors would appreciate your work. If you are even remotely interested, feel free to shoot me an email.

  7. After study a few of the blog posts on your website now, and I truly like your way of blogging. I bookmarked it to my bookmark website list and will be checking back soon. Pls check out my web site as well and let me know what you think.

  8. You’re so interesting! I do not believe I’ve truly read something like that before. So wonderful to discover somebody with some genuine thoughts on this topic. Seriously.. thanks for starting this up. This website is one thing that is needed on the web, someone with a little originality!

  9. After study some of the web sites on your web site now, and i really much like your technique of blogging. I bookmarked it to my bookmark web site list and will also be checking back soon. Pls look into my web site likewise and make me aware what you think.

  10. Ok oui et pas vraiment. Assurément parce que il se peut qu’on rencontre certaines sources qui probablement citent de semblables cote. Non car il ne suffit pas de copier ce qu’on peut lire avec plusieurs site web autres avant de le transposer tant clairement

  11. My partner and I absolutely love your blog and find many of your post’s to be what precisely I’m looking for. Do you offer guest writers to write content to suit your needs? I wouldn’t mind writing a post or elaborating on most of the subjects you write about here. Again, awesome site!

  12. I found your weblog website on google and check a number of of your early posts. Proceed to keep up the very good operate. I just further up your RSS feed to my MSN News Reader. Looking for forward to reading extra from you later on!…

  13. Awesome blog! Is your theme custom made or did you download it from somewhere? A design like yours with a few simple adjustements would really make my blog shine. Please let me know where you got your theme. Many thanks

  14. Hello I am so glad I found your blog page, I really found you by error, while I was browsing on Digg for something else, Anyways I am here now and would just like to say thank you for a incredible post and a all round thrilling blog (I also love the theme/design), I don’t have time to go through it all at the moment but I have book-marked it and also added in your RSS feeds, so when I have time I will be back to read much more, Please do keep up the fantastic work.

  15. I haven¦t checked in here for a while because I thought it was getting boring, but the last few posts are great quality so I guess I¦ll add you back to my daily bloglist. You deserve it my friend 🙂

  16. Hi there, You have done an excellent job. I will definitely digg it and in my opinion recommend to my friends. I am confident they will be benefited from this web site.

  17. Thanks for another informative site. Where else could I get that kind of info written in such an ideal way? I’ve a project that I am just now working on, and I’ve been on the look out for such info.

  18. naturally like your website but you need to take a look at the spelling on quite a few of your posts. Several of them are rife with spelling problems and I in finding it very troublesome to inform the reality then again I will definitely come again again.

  19. You can certainly see your skills in the paintings you write. The sector hopes for more passionate writers such as you who aren’t afraid to mention how they believe. Always follow your heart. “If you feel yourself falling, let go and glide.” by Steffen Francisco.

  20. I do believe all of the ideas you’ve introduced in your post. They are really convincing and will definitely work. Nonetheless, the posts are too short for newbies. May you please prolong them a little from next time? Thanks for the post.

  21. hello!,I love your writing so so much! proportion we communicate more about your article on AOL? I require an expert on this house to solve my problem. May be that’s you! Looking forward to see you.

  22. Nearly all of whatever you point out is astonishingly precise and that makes me ponder the reason why I hadn’t looked at this in this light previously. Your article truly did turn the light on for me as far as this particular subject matter goes. But there is 1 point I am not necessarily too comfortable with so whilst I try to reconcile that with the actual core idea of your point, allow me see what the rest of your readers have to say.Well done.

  23. Wow that was unusual. I just wrote an very long comment but after I clicked submit my comment didn’t show up. Grrrr… well I’m not writing all that over again. Anyway, just wanted to say excellent blog!

  24. I just could not depart your website before suggesting that I extremely enjoyed the standard information a person provide for your visitors? Is gonna be back often to check up on new posts

  25. Can I just say what a reduction to search out someone who really knows what theyre talking about on the internet. You undoubtedly know how to carry an issue to light and make it important. Extra people need to learn this and understand this facet of the story. I cant imagine youre no more well-liked since you definitely have the gift.

  26. In the grand pattern of things you actually secure an A with regard to effort. Where you misplaced me was in all the specifics. You know, it is said, details make or break the argument.. And that couldn’t be much more correct at this point. Having said that, allow me inform you precisely what did deliver the results. Your writing is certainly quite persuasive and this is probably why I am taking an effort to opine. I do not make it a regular habit of doing that. Second, whilst I can easily notice a leaps in reason you make, I am not convinced of exactly how you appear to unite your ideas that produce the actual final result. For the moment I will, no doubt subscribe to your point but trust in the near future you actually connect the dots better.

  27. I’m amazed, I must say. Rarely do I come across a blog that’s both educative and amusing, and let me tell you, you have hit the nail on the head. The problem is an issue that too few people are speaking intelligently about. I’m very happy I stumbled across this in my hunt for something concerning this.

  28. Wonderful blog! I found it while browsing on Yahoo News. Do you have any suggestions on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Thanks

  29. An interesting discussion is worth comment. I think that you should write more on this topic, it might not be a taboo subject but generally people are not enough to speak on such topics. To the next. Cheers

  30. I have been absent for a while, but now I remember why I used to love this web site. Thanks , I will try and check back more frequently. How frequently you update your site?

  31. I like what you guys are up also. Such smart work and reporting! Keep up the excellent works guys I have incorporated you guys to my blogroll. I think it will improve the value of my website 🙂

  32. 127900 906591There is an ending. Just remember that I meant for this to be an art game. I do feel like I spent an inordinate amount of time on the more traditional gameplay elements, which may make the meaning with the game a bit unclear. Should you mess around with it though, youll find it. 956367

  33. I love your blog.. very nice colors & theme. Did you design this website yourself or did you hire someone to do it for you? Plz answer back as I’m looking to construct my own blog and would like to find out where u got this from. thanks a lot

  34. I?¦ve been exploring for a bit for any high quality articles or blog posts on this kind of house . Exploring in Yahoo I finally stumbled upon this site. Studying this information So i am happy to convey that I’ve an incredibly excellent uncanny feeling I found out exactly what I needed. I most indisputably will make certain to do not omit this website and give it a glance on a relentless basis.

  35. I’m extremely impressed with your writing talents as smartly as with the structure on your blog. Is that this a paid subject matter or did you modify it your self? Anyway stay up the nice quality writing, it抯 rare to look a great weblog like this one these days..

  36. I have been surfing online greater than three hours these days, yet I by no means found any fascinating article like yours. It?¦s pretty price enough for me. In my view, if all website owners and bloggers made just right content as you did, the internet will likely be a lot more helpful than ever before.

  37. Please let me know if you’re looking for a article author for your site. You have some really good posts and I feel I would be a good asset. If you ever want to take some of the load off, I’d love to write some content for your blog in exchange for a link back to mine. Please blast me an e-mail if interested. Kudos!

  38. Heya i am for the first time here. I found this board and I find It really helpful & it helped me out a lot. I hope to offer something back and help others like you helped me.

Leave a Reply

Your email address will not be published. Required fields are marked *