Recipe 25.2 Accessing the Tomcat JNDI Resource from a Servlet


Problem

You want to access a JNDI object with a servlet using Tomcat's JNDI implementation.

Solution

Use the javax.naming classes in the servlet's init( ) method to look up a JNDI object. Then use the object in a service method like doGet( ) .

Discussion

A servlet can access a JavaBean as a JNDI registered resource after you have:

  1. Developed the JavaBean class and stored it in WEB-INF/classes or in a JAR in WEB-INF/lib .

  2. Changed the server configuration file and web.xml as described in Recipe 25.1, in order to bind the object to the Tomcat JNDI tree.

Example 25-4 creates a javax.naming.InitialContext in its init( ) method, then looks up a JavaBean: com.jspservletcookbook.StockPriceBean . This bean is bound to the JNDI implementation under the name "bean/pricebean." The init( ) method is called only when the servlet container creates a servlet instance, so the servlet has access to one instance of StockPriceBean .

Example 25-4. Using a Tomcat JNDI object from a servlet
 package com.jspservletcookbook;     import java.io.IOException;   import java.io.PrintWriter;  import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException;  import javax.servlet.*; import javax.servlet.http.*;  public class BeanServlet extends HttpServlet {     private StockPriceBean spbean;  public void init( ) throws ServletException {  Context env = null;  try{  env = (Context) new InitialContext( ).lookup("java:comp/env");           spbean = (StockPriceBean) env.lookup("bean/pricebean");                         //close the InitialContext, unless the code will use it for           //another look up           env.close( );  if (spbean == null)               throw new ServletException(               "bean/pricebean is an unknown JNDI object");                     } catch (NamingException ne) {                     try{ env.close( );} catch (NamingException nex) { }                        throw new ServletException(ne);       }//try          }//init        public void doGet(HttpServletRequest request,      HttpServletResponse response)     throws ServletException, java.io.IOException {            //set the MIME type of the response, "text/html"       response.setContentType("text/html");            //use a PrintWriter to send text data to the client        java.io.PrintWriter out = response.getWriter( );            //Begin assembling the HTML content       out.println("<html><head>");            out.println("<title>Stock Price Fetcher</title></head><body>");       out.println("<h2>Please submit a valid stock symbol</h2>");  //make sure method="POST" so that the servlet service method       //calls doPost in the response to this form submit       out.println(         "<form method=\"POST\" action =\"" + request.getContextPath( ) +             "/namingbean\" >");  out.println("<table border=\"0\"><tr><td valign=\"top\">");       out.println("Stock symbol: </td>  <td valign=\"top\">");       out.println("<input type=\"text\" name=\"symbol\" size=\"10\">");       out.println("</td></tr><tr><td valign=\"top\">");       out.println(       "<input type=\"submit\" value=\"Submit Info\"></td></tr>");       out.println("</table></form>");       out.println("</body></html>");      } //doGet         public void doPost(HttpServletRequest request,      HttpServletResponse response)     throws java.io.IOException{  String symbol;//this will hold the stock symbol       float price = 0f;            symbol = request.getParameter("symbol");  boolean isValid = (symbol == null  symbol.length( ) < 1) ?       false : true;       //set the MIME type of the response, "text/html"       response.setContentType("text/html");            //use a PrintWriter send text data to the client        java.io.PrintWriter out = response.getWriter( );            //Begin assembling the HTML content       out.println("<html><head>");       out.println("<title>Latest stock value</title></head><body>");            if ((! isValid)  spbean == null){           out.println(           "<h2>Sorry, the stock symbol parameter was either "+           "empty or null</h2>");                } else {  out.println("<h2>Here is the latest value of "+ symbol +"</h2>");           spbean.setSymbol(symbol);           price = spbean.getLatestPrice( );           out.println( (price==0?             "The symbol is probably invalid." : ""+price) );  }       out.println("</body></html>");   }//doPost }//BeanServlet 

Example 25-4 calls close( ) on the InitialContext to free up any resources this object is using, since the code does not use it again to initiate a lookup. Then the servlet uses the bean object to access a live stock quote in its doGet( ) method. The servlet first calls the bean's setter method setSymbol( ) to notify the bean about which stock symbol it is looking up.

Example 25-5 shows the bean that Tomcat has stored as a JNDI object (it's the same bean used in Example 25-4). Chapter 26 explains this bean, which "scrapes" a stock price off of a web page. Chapter 26 covers the bean's details; the methods this chapter's servlet uses are setSymbol( ) and getLatestPrice( ) . The bean handles all the details of downloading the stock price.

Example 25-5. The bean that is stored as a JNDI object
 package com.jspservletcookbook;   import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.MalformedURLException;  import javax.swing.text.html.HTMLEditorKit.ParserCallback; import javax.swing.text.MutableAttributeSet; import javax.swing.text.html.parser.ParserDelegator; public class StockPriceBean {  private static final String urlBase =         "http://finance.yahoo.com/q?d=t&s=";     private BufferedReader webPageStream = null;     private URL stockSite = null;     private ParserDelegator htmlParser = null;     private MyParserCallback callback = null;     private String htmlText = "";     private String symbol = "";     private float stockVal = 0f;  public StockPriceBean( ) {}//no-arguments constructor for the bean        public void setSymbol(String symbol){       this.symbol = symbol;   }        public String getSymbol( ){       return symbol;     } //Inner class provides the callback    class MyParserCallback extends ParserCallback {  private boolean lastTradeFlag = false;     private boolean boldFlag = false;   public MyParserCallback( ){       if (stockVal != 0)           stockVal = 0f;   }            public void handleStartTag(javax.swing.text.html.HTML.Tag t,     MutableAttributeSet a,int pos) {         if (lastTradeFlag && (t == javax.swing.text.html.HTML.Tag.B )){             boldFlag = true;         }   }//handleStartTag   public void handleText(char[] data,int pos){       htmlText  = new String(data);       if (htmlText.indexOf("No such ticker symbol.") != -1){           throw new IllegalStateException(               "Invalid ticker symbol in handleText( ) method.");       }  else if (htmlText.equals("Last Trade:")){           lastTradeFlag = true;        } else if (boldFlag){  try{                stockVal = new Float(htmlText).floatValue( );             } catch (NumberFormatException ne) {                                      try{                     //tease out any commas in the number using NumberFormat                     java.text.NumberFormat nf = java.text.NumberFormat.                     getInstance( );                     Double f = (Double) nf.parse(htmlText);                     stockVal =  (float) f.doubleValue( );                 } catch (java.text.ParseException pe){                     throw new IllegalStateException(                       "The extracted text " + htmlText +                          " cannot be parsed as a number!");                 }//inner try            }//outer try  lastTradeFlag = false;             boldFlag = false;                     }//if   } //handleText  }//MyParserCallback   public float getLatestPrice( ) throws IOException,MalformedURLException {  stockSite = new URL(urlBase + symbol);       webPageStream = new BufferedReader(new InputStreamReader(stockSite.        openStream( )));       htmlParser = new ParserDelegator( );       callback = new MyParserCallback( );//ParserCallback  synchronized(htmlParser){           htmlParser.parse(webPageStream,callback,true);       }//sychronized  //reset symbol       setSymbol("");       return stockVal;   }//getLatestPrice }//StockPriceBean 

The ParserDelegator.parse( ) method is synchronized and therefore designed to only allow one thread at a time to parse the web page and pull out the stock quote.


Figure 25-1 shows the web page form generated by the servlet's doGet( ) method. The user enters a stock symbol into this form, then submits the form to the servlet's doPost( ) method.

Figure 25-1. Enter a stock symbol for a live stock price
figs/jsjc_2501.gif

Figure 25-2 shows the stock information that the JNDI object found for the servlet.

Figure 25-2. The servlet's doPost( ) method generates a live stock quote using a JNDI object
figs/jsjc_2502.gif

See Also

Recipe 25.1 on configuring a JNDI object with Tomcat; Recipe 25.3 on accessing the Tomcat JNDI object from a JSP; Chapter 21 on accessing DataSources with JNDI; Chapter 26 on harvesting web information.



Java Servlet & JSP Cookbook
Java Servlet & JSP Cookbook
ISBN: 0596005725
EAN: 2147483647
Year: 2004
Pages: 326

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net