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();
}

2014-06-14

Java EE (JSF): Internationalization and localization

Configuring locales:

The first step toward supporting multiple languages is to tell your JSF application which locales it should support. You specify the supported locales with the <locale-config> element in a Faces configuration file, under the <application> node:

<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>en</supported-locale>
<supported-locale>es</supported-locale>
</locale-config>
<message-bundle>CustomMessages</message-bundle>
</application>
The letters “en” and “es” stand for English and Spanish, respectively. So this tells our application to support both English and Spanish, and to use English as the default.

Creating resource bundles:

Once you’ve configured your JSF application to support different locales, you have to place locale-specific versions of your application’s text strings in resource bundles. Resource bundles aren’t a JSF feature—they’re a fundamental part of the way Java handles internationalization and localization.

LocalizaitonResources_en.properties:
numberOfVisits=You have visited us {0} time(s), {1}. Rock on!
toggleLocale=Translate to Spanish
helloImage=../images/hello.gif
After you have created a localized properties filelanguage), you must convert it to use Unicode characters. This can be done with the native2ascii tool included with the Java Development Kit (JDK). 

Using resource bundles with components:

Using a resource bundle in a JSF application is as simple as using a value-binding expression. All you have to do is load the proper resource bundle and make it accessible in an application scope. For JSP, there’s a JSF core tag, <f:loadBundle>, that loads the bundle and stores it in the request scope automatically.Here’s how
you use it:
<f:loadBundle basename="LocalizationResources" var="bundle"/>
The basename attribute specifies the name of the resource bundle, prefixed by its location in your classpath. Because our bundles were placed in WEB-INF/classes, no prefix is needed. However, if we had nested them deeper, like in the WEB-INF/classes/org/jia directory, the basename would be "org.jia.LocalizationResources".

We can access value of the key numberOfVisits, with the value-binding expression "#{bundle.halloween}".

2014-06-13

Java EE (JSF): Initializing List and Array properties for Managed Beans

If you have a property that is an array or a List, you can initialize it with default values. If the property is set to null, the facility will create a new List or array and initialize it for you. If it’s non-null, the facility will simply add any values you define to the existing collection.

Instead of specifying a single value for the property, you specify multiple values. You can configure a List or array property by nesting <value> or <null-value> elements inside a <list-entries> element, which is a child of the <managed-property> element.

Let’s say our UserBean class also has a favoriteSites property, which is a List of Strings representing the user’s favorite sites. If we wanted to provide a default list of values for the favoriteSites property, we could define it like so:

<managed-bean><managed-bean-name>user</managed-bean-name><managed-bean-class>org.jia.examples.UserBean</managed-bean-class><managed-bean-scope>request</managed-bean-scope>...<managed-property><property-name>favoriteSites</property-name><list-entries><value>http://www.jsfcentral.com</value><value>http://www.theserverside.com</value><value>http://www.ibm.com/developerworks/</value><value>http://otn.oracle.com</value><value>http://www.java.net</value><value>http://www.manning.com</value></list-entries></managed-property>...</managed-bean>

In the previous example, all values were stored as String objects, which is the default. If you want all of the values to be converted to a specific type, you can use the <value-class> attribute. Here’s a List property whose values are all Integers:

<managed-bean>...<managed-property><property-name>favoriteNumbers</property-name><list-entries><value-class>java.lang.Integer</value-class><value>31415</value><value>278</value><value>304</value><value>18</value><value>811</value><value>914</value></list-entries></managed-property>...</managed-bean>