What Is Jetty

What Is Jetty

Externalizing the Configuration: XML-driven Config File

While its API is straightforward and clean, the sample's direct calls to the Jetty API leave configuration -- port numbers, context paths, servlet class names -- buried in code. Jetty provides an XML-based configuration as an alternative, such that you can externalize all of this information and keep your code clean.



The XML configuration is based on Java's Reflection API. Classes in the java.lang.reflect represent Java methods and classes, such that you can instantiate objects and invoke their methods based on their names and argument types. Behind the scenes, Jetty's XML config parser translates the XML elements and attributes into Reflection calls.

This excerpt from the Step2Driver sample class is a revamped version of Step1Driver. As far as configuration is concerned, there's just enough Jetty-related code to load the file.

URL serviceConfig = /* load XML file */ ;

   // can use an InputStream or URL



XmlConfiguration serverFactory =

   new XmlConfiguration( serviceConfig ) ;



                        

Server service =

   (Server) serverFactory.newInstance() ;

This admittedly doesn't save much code compared to the trivial example in Step1Driver. Then again, this is as much code as Step2Driver will ever need, even as you add more servlets or web apps. Directly calling methods on Service and context objects is a case of diminishing returns as the configuration grows more complex.

Listing 1 is the XML file loaded by Step2Driver. The toplevel <Configure> element's class attribute (marker 1) specifies which class to instantiate. Here it's a Jetty Server object.

<!-- 1 -->

<Configure class="org.mortbay.jetty.Server">



  <!-- 2 -->

  <Call name="addListener">

    <Arg>

      <!-- 3 -->

      <New

         class="org.mortbay.http.SocketListener">



        <!-- 4 -->

        <Set name="Host">



          <!-- 5 -->

          <SystemProperty

             name="service.listen.host"

             default="localhost"

          />



        </Set>



        <Set name="Port">

          <SystemProperty

             name="service.listen.port"

             default="7501"

          />

        </Set>



      </New>

    </Arg>

  </Call>





  <Call name="getContext">



    <Arg>/embed</Arg>





    <!--

    call methods on the return value of

    Server.getContext()

    -->



    <!-- 6 -->

    <Call name="addServlet">



      <!-- servlet name -->

      <Arg>"Simple"</Arg>



      <!-- URL pattern -->

      <Arg>/TryThis/*</Arg>



      <!-- servlet class -->

      <Arg>sample.SimpleServlet</Arg>



    </Call>



  </Call>



</Configure>

The child <Call> elements represent method invocations on the Server object defined in the parent element. The call to addListener(), at marker (2), itself has child <Arg> elements that specify method arguments. Here I could have passed the string value for the listen address, but addListener() is overloaded to take a SocketListener object. For the sake of demonstration I call the <New> element to instantiate a new SocketListener at market (3). Markers 2 and 3 are the XML equivalent of calling

server.addListener(

   new SocketListener( ... )

) ;

in code.

To configure the SocketListener itself, you could use a <Call> element to invoke its setHost() method. Since this method follows JavaBean naming and signature conventions, the sample code instead uses the <Set> element (4) as a shortcut. Behind the scenes, Jetty prepends "set" to the value of the name attribute to determine the method name to invoke (here, setHost()).

setHost()'s arguments aren't explicitly listed here. Instead, the <SystemProperty> element (5) accepts the name of the system property from which to fetch the values, here service.listen.host and service.listen.port. In case these system properties are not defined, the <SystemProperty> element also lets you specify a default value using the default attribute. Together, markers 4 and 5 are the same as calling:

   socketListener.setHost(

      System.getProperty(

         "service.listen.host" ,

         "localhost"

      )

  ) ;

Finally, note the <Call> elements inside the <Call> to getContext() (6). The inner <Call> is invoked on the value returned by the outer <Call>. Here, then, addServlet() is called on the context object returned by getContext():

server.getContext().addServlet( ... ) ;

Kudos to the Jetty team for taking the XML configuration one step farther: notice that all Jetty-specific calls in Listing 1 are element or attribute values, not names. This means the XML configuration can be used with any classes, even non-Jetty classes. Depending on how your app is written, you could configure it all through Jetty's XML config.

Prev  [1] [2] [3] [4] Next

Close    To Top
  • Prev Article-Java:
  • Next Article-Java:
  • Now: Tutorial for Web and Software Design > Java > Java Servlets > Java Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction