Java Tutorial - Java Scipt : Servlet JMS Clients

Java Tutorial - Java Scipt :

Servlet JMS Clients

Servlets can use JMS messaging with pretty much the same syntax as the standalone JMS clients do. Unlike standalone clients, servlets cannot consume messages asynchronously. For this reason, servlet clients should only be used as producers.

The most noteworthy change is that the construction InitialContext doesn’t require additional parameters. This is so because the J2EE container that manages the servlet will provide the proper values by default. In fact, you should avoid passing any parameters in, because this subverts the role of the application server. Here’s a sample from servlet code that uses JMS:

public void doGet( HttpServletRequest request,
HttpServletResponse response )
throws IOException, ServletException {
String s = “”;

TopicConnection connection = null;
TopicSession session = null;
try {
// --- Create various JMS resources to use testTopic. ---
Context context = new InitialContext();
TopicConnectionFactory factory = (TopicConnectionFactory)
context.lookup( “java:/XAConnectionFactory” );
connection = factory.createTopicConnection();
session = connection.createTopicSession(
true, Session.AUTO_ACKNOWLEDGE );
Topic topic = (Topic)
context.lookup( “java:comp/env/jms/testTopic” );
TopicPublisher publisher = session.createPublisher( topic );
// --- Publish a trivial text message. ---
TextMessage message = session.createTextMessage();
message.setText( “” + new Date().getTime() );
publisher.publish( message );
session.commit();
s = “Published “ + message;
}
catch( Exception e ) {
s = s + e;
e.printStackTrace();
}
response.getWriter().println( s );
System.out.println( s );
}

You should add references in the web.xml descriptor for any external resources that are used so that your servlet code won’t be dependent on the JNDI naming. By isolating those mappings into descriptor files, we can move beyond different J2EE application servers or make changes in the JNDI naming scheme without breaking things. Here’s an excerpt from the web.xml file that declares the local reference, jms/testTopic, which we used from the
java:comp/env/ JDNI space:

<resource-ref >
<description><![CDATA[TestTopic resource reference]]></description>
<res-ref-name>jms/testTopic</res-ref-name>
<res-type>javax.jms.Topic</res-type>
<res-auth>Container</res-auth>
</resource-ref>

 Don’t forget that order matters within the XML descriptor files. Be sure to add these entries at the right location.

Now, we need to define the actual mapping for our application server. In the case of JBoss, that would be in the jboss-web.xml file that resides at the same directory level as the web.xml file. This is the application-server-specific
counterpart to web.xml. You’ll see this pattern quite often in J2EE descriptors.

Here’s our complete jboss-web.xml file:

<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE jboss-web PUBLIC
“-//JBoss//DTD Web Application 2.3//EN”
“http://www.jboss.org/j2ee/dtd/jboss-web_3_0.dtd”>

<jboss-web>
<context-root>/myweb</context-root>

<!— Resource references —>
<resource-ref>
<res-ref-name>jms/testTopic</res-ref-name>
<jndi-name>topic/testTopic</jndi-name>
</resource-ref>

<!— EJB References —>

</jboss-web>

 For quick-and-dirty development in JBoss, you can skip all the descriptor hoops and just refer to the JNDI name you know that the queue or topic will be bound under (for example, “topic/testTopic” ). Not a great idea from a software engineering perspective, but great for quick prototyping.