Pages

2014-08-15

Java EE: Sending messages to a message topic/Receiving messages from a message topic

Sending messages to a JMS topic is very similar to sending messages to a queue; simply inject the required resources and make some simple JMS API calls. The following example illustrates how to send messages to a message topic:

import javax.annotation.Resource;
import javax.jms.ConnectionFactory;
import javax.jms.JMSContext;
import javax.jms.JMSProducer;
import javax.jms.Topic;

public class MessageSender {

@Resource(mappedName = "jms/GlassFishBookConnectionFactory")
private static ConnectionFactory connectionFactory;
@Resource(mappedName = "jms/GlassFishBookTopic")
private static Topic topic;

public void produceMessages() {
   JMSContext jmsContext = connectionFactory.createContext();
   JMSProducer jmsProducer = jmsContext.createProducer();
   String msg1 = "Testing, 1, 2, 3. Can you hear me?";
   String msg2 = "Do you copy?";
   String msg3 = "Good bye!";
   System.out.println("Sending the following message: " + msg1);
   jmsProducer.send(topic, msg1);
   System.out.println("Sending the following message: " + msg2);
   jmsProducer.send(topic, msg2);
   System.out.println("Sending the following message: " + msg3);
   jmsProducer.send(topic, msg3);
}

Just as sending messages to a message topic is nearly identical to sending messages  receiving messages from a message topic is nearly identical to receiving messages from a message queue, as can be seen in the following example:


import javax.annotation.Resource;

import javax.jms.ConnectionFactory;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.Topic;

public class MessageReceiver {
@Resource(mappedName = "jms/GlassFishBookConnectionFactory")
private static ConnectionFactory connectionFactory;
@Resource(mappedName = "jms/GlassFishBookTopic")
private static Topic topic;
public void getMessages() {
   String message;
   boolean goodByeReceived = false;
   JMSContext jmsContext = connectionFactory.createContext();
   JMSConsumer jMSConsumer = jmsContext.createConsumer(topic);
   System.out.println("Waiting for messages...");
   while (!goodByeReceived) {
        message = jMSConsumer.receiveBody(String.class);
        if (message != null) {
           System.out.print("Received the following message: ");
           System.out.println(message);
           System.out.println();
           if (message.equals("Good bye!")) {
                    goodByeReceived = true;
           }
        }
    }
}

Java EE: Browsing message queues without removing messages

JMS provides a way to browse message queues without actually removing the messages from the queue. The following example illustrates how to do this:

import java.util.Enumeration;
import javax.annotation.Resource;
import javax.jms.ConnectionFactory;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.TextMessage;

public class MessageQueueBrowser {
@Resource(mappedName = "jms/GlassFishBookConnectionFactory")
private static ConnectionFactory connectionFactory;
@Resource(mappedName = "jms/GlassFishBookQueue")
private static Queue queue;
public void browseMessages() {
   try {
       Enumeration messageEnumeration;
       TextMessage textMessage;
       JMSContext jmsContext = connectionFactory.createContext();
       QueueBrowser browser = jmsContext.createBrowser(queue);
       messageEnumeration = browser.getEnumeration();
       if (messageEnumeration != null) {
           if (!messageEnumeration.hasMoreElements()) {
                System.out.println("There are no messages " + "in the queue.");
       } else {
                System.out.println("The following messages are " + "in the queue");
                while (messageEnumeration.hasMoreElements()) {
                          textMessage = (TextMessage)
                          messageEnumeration.nextElement();
                          System.out.println(textMessage.getText());
                }
       }
     }
     } catch (JMSException e) {
         e.printStackTrace();
     }
}

2014-08-14

Java EE: Asynchronously receiving messages from a message queue

The JMSConsumer.receiveBody() method has a disadvantage: it blocks execution until a message is received from the queue. We can prevent our JMS consumer code from blocking execution by receiving messages asynchronously via an implementation of the javax.jms.MessageListener interface.

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class ExampleMessageListener implements MessageListener {
@Override
public void onMessage(Message message) {
   TextMessage textMessage = (TextMessage) message;
   try {
      System.out.print("Received the following message: ");
      System.out.println(textMessage.getText());
      System.out.println();
   } catch (JMSException e) {
     e.printStackTrace();
}
}
}

Our main code can now delegate message retrieval to our custom MessageListener implementation:
jMSConsumer.setMessageListener(new ExampleMessageListener());

Java EE: Retrieving messages from a message queue

import javax.annotation.Resource;
import javax.jms.ConnectionFactory;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.Queue;

public class MessageReceiver {

public void getMessages() {
   String message;
   boolean goodByeReceived = false;
   JMSContext jmsContext = connectionFactory.createContext();
   JMSConsumer jMSConsumer = jmsContext.createConsumer(queue);
   System.out.println("Waiting for messages...");
   while (!goodByeReceived) {
         message = jMSConsumer.receiveBody(String.class);
         if (message != null) {
             System.out.print("Received the following message: ");
             System.out.println(message);
             System.out.println();
             if (message.equals("Good bye!")) {
                goodByeReceived = true;
             }
         }
    }
}

Java EE: Sending messages to a message queue

Sending messages to a JMS queue consists of injecting a few resources to our code and making a few simple JMS API calls. The following example illustrates how to add messages to a message queue:

import javax.annotation.Resource;
import javax.jms.ConnectionFactory;
import javax.jms.JMSContext;
import javax.jms.JMSProducer;
import javax.jms.Queue;

public class MessageSender {
@Resource(mappedName = "jms/GlassFishBookConnectionFactory")
private static ConnectionFactory connectionFactory;

@Resource(mappedName = "jms/GlassFishBookQueue")
private static Queue queue;

public void produceMessages() {
JMSContext jmsContext = connectionFactory.createContext();
JMSProducer jmsProducer = jmsContext.createProducer();
String msg1 = "Testing, 1, 2, 3. Can you hear me?";
String msg2 = "Do you copy?";
String msg3 = "Good bye!";
System.out.println("Sending the following message: "
+ msg1);
jmsProducer.send(queue, msg1);
System.out.println("Sending the following message: "
+ msg2);
jmsProducer.send(queue, msg2);
System.out.println("Sending the following message: "
+ msg3);
jmsProducer.send(queue, msg3);
}
}

Java EE: Parsing JSON data with the Streaming API

In the last article, we saw how to generate JSON data from our Java code with the Streaming API. In this section, we will see how we can read and parse the existing JSON data we receive from a stream. The following code sample illustrates how to do this:

import javax.json.Json;
import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParser.Event;
@Named
@SessionScoped
public class JsonpBean implements Serializable {
   private String jsonStr;
   @Inject private Customer customer;
   public void parseJson() {
      StringReaderstringReader = new StringReader(jsonStr);
      JsonParserjsonParser = Json.createParser(stringReader);
      Map<String, String> keyValueMap = new HashMap<>();
      String key = null;
      String value = null;
      while (jsonParser.hasNext()) {
            JsonParser.Event event = jsonParser.next();
            if (event.equals(Event.KEY_NAME)) {
                  key = jsonParser.getString();
            } else if (event.equals(Event.VALUE_STRING)) {
                  value = jsonParser.getString();
           }
           keyValueMap.put(key, value);
       }
       customer.setFirstName(keyValueMap.get("firstName"));
       customer.setLastName(keyValueMap.get("lastName"));
       customer.setEmail(keyValueMap.get("email"));
  }
}

Java EE: Generating JSON data with the Streaming API

The JSON-P Streaming API allows the sequential reading of a JSON object from a stream (a subclass of java.io.OutputStream, or a subclass of java.io.Writer). It is faster and more memory efficient than the Model API. However, the tradeoff is that it is more limited, since the JSON data needs to be read sequentially and we cannot access specific JSON properties directly, the way the Model API allows.

The JSON Streaming API has a JsonGenerator class that we can use to generate JSON data and write it to a stream. This class has several overloaded write() methods which can be used to add properties and their corresponding values to the generated JSON data.

import javax.json.Json;
import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParser.Event;
@Named
@SessionScoped
public class JsonpBean implements Serializable {
   private String jsonStr;
   @Inject private Customer customer;
   public String buildJson() {
      StringWriter stringWriter = new StringWriter();
      try (JsonGenerator jsonGenerator = Json.createGenerator(stringWriter)) {
         jsonGenerator.writeStartObject(). write("firstName", "ATHIMNI"). write("lastName", "Mohamed").write("email", "m.athimni@example.com").writeEnd();
   return  stringWriter.toString();
   }
}

Java EE: Parsing JSON data with the Model API

In the last article, we saw how to generate JSON data from our Java code with the Model API. In this section, we will see how we can read and parse the existing JSON data. The following code sample illustrates how to do this:

importimportjavax.json.Json;
importimportjavax.json.JsonObject;
importimportjavax.json.JsonReader;
importimportjavax.json.JsonWriter;

@Named
@SessionScoped
public class JsonpBean implements Serializable {
   private String jsonStr;
   @Inject private Customer customer;

public void parseJson() {
   JsonObjectjsonObject;
   try (JsonReader jsonReader = Json.createReader( new StringReader(jsonStr))) {
      jsonObject = jsonReader.readObject();
   }
   customer.setFirstName(jsonObject.getString("firstName"));
   customer.setLastName(jsonObject.getString("lastName"));
   customer.setEmail(jsonObject.getString("email"));
}
}

Java EE: Generating JSON data with the Model API

At the heart of the JSON-P Model API is the JsonObjectBuilder class. This class has several overloaded add() methods that can be used to add properties and their corresponding values to the generated JSON data. The following code sample illustrates how to generate JSON data using the Model API:

importimportjavax.inject.Named;
importimportjavax.json.Json;
importimportjavax.json.JsonObject;
importimportjavax.json.JsonReader;
importimportjavax.json.JsonWriter;

@Named
@SessionScoped
public class JsonpBean implements Serializable{
private String jsonStr;
@Inject
private Customer customer;

public String buildJson() {
JsonObjectBuilderjsonObjectBuilder =Json.createObjectBuilder();
JsonObjectjsonObject = jsonObjectBuilder.add("firstName", "ATHIMNI").add("lastName", "Mohamed").add("email", "m.athimni@example.com").build();

StringWriter stringWriter = new StringWriter();
try (JsonWriter jsonWriter = Json.createWriter(stringWriter))
{
   jsonWriter.writeObject(jsonObject);
}
return stringWriter.toString();
}