<document>
  <header>
    <product>resin</product>
    <title>Hessian with Dependency Injection</title>
    <description>
      <p>Using Hessian with Dependency Injection pattern
creates services which are simpler, protocol-independent and more easily
tested.  The Dependency Injection pattern (aka inversion of control)
gives Resin the responsibility of configuring and assembling
the service, protocol, and client.</p>
    </description>
    <type>tutorial</type>
    <tutorial-startpage>client/greeting</tutorial-startpage>
  </header>

  <body>
    <summary/>

<section title="Files in this tutorial">
<deftable>
<tr><td><viewfile-link file="WEB-INF/classes/example/GreetingAPI.java"/>
    <td>Interface for the greeting service.
<tr><td><viewfile-link file="WEB-INF/classes/example/GreetingImpl.java"/>
    <td>The service implementation as a Java object
<tr><td><viewfile-link file="WEB-INF/resin-web.xml"/>
    <td>Configures the environment
<tr><td><viewfile-link file="WEB-INF/classes/example/GreetingClientServlet.java"/>
    <td>Client Servlet
</deftable>
</section>

<section title="Service Implementation">

<example title="GreetingAPI.java">
package example;

public interface GreetingAPI {
  public String hello();
}
</example>

<section title="Service Implementation">

<p>The Greeting implementation is a plain Java class that implements
the MatchService API.  Making the service a plain class offers a number of advantages:</p>

<ul>
<li><b>Simplicity:</b> It can concentrate on its business logic because it doesn't need to implement any protocol-dependent code.
<li><b>Independence:</b> It can be reused more easily because it isn't tied to a distributed framework (e.g. in contrast to EJB).
<li><b>Testability:</b> It is more easily tested since the test harness doesn't need to implement the protocol or its stubs.  The harness can just test the service as a plain old Java object.
</ul>

<example title="GreetingImpl.java">
package example;

public class GreetingImpl implements GreetingAPI {
  private String _greeting = "Hello, world";

  public void setGreeting(String greeting)
  {
    _greeting = greeting;
  }

  public String greeting()
  {
    return _greeting;
  }
}
</example>

</section>

<section title="Configuration using Dependency Injection">

<example title="resin-web.xml">
&lt;resource jndi-name="service/greeting"
          type="example.GreetingImpl">
  &lt;init>
    &lt;greeting>Hello, web.xml&lt;/greeting>
  &lt;/init>
&lt;/resource>

&lt;servlet url-pattern="/hessian/greeting"
         servlet-class="com.caucho.hessian.server.HessianServlet">
  &lt;init>
    &lt;home>\${jndi("service/greeting")}&lt;/home>
    &lt;home-api>example.GreetingAPI&lt;/home-api>
  &lt;/init>
&lt;/servlet>
</example>

</section>

</section>

<section title="Client">

<p>Configuring the client servlet with Dependency Injection
allows for a simpler and more general client.  The following client
can use any proxy/stub which implements the GreetingAPI without change,
for example:</p>

<ul>
<li>Hessian proxy
<li>Burlap proxy
<li>EJB local object stub
<li>JMX proxy
<li>Java bean instance
</ul>

<p>Using the Dependency Injection patter, the servlet doesn't care
how the proxy is implemented, or how the greeting service is
discovered.</p>

<example title="GreetingClientServlet.java">
public class GreetingClientServlet extends GenericServlet {
  private String _name = "generic";
  private GreetingAPI _greeting;

  public void setName(String name)
  {
    _name = name;
  }

  public void setGreeting(GreetingAPI greeting)
  {
    _greeting = greeting;
  }

  public void service(ServletRequest req, ServletResponse res)
    throws IOException, ServletException
  {
    PrintWriter out = res.getWriter();

    out.println(_name + ": " + _greeting.greeting());
  }
}
</example>

<section title="Hessian Client using Dependency Injection">

<p>The following example stores a &lt;reference>
to the Hessian proxy in JNDI for the service.  The servlet configuration
looks up the Hessian proxy in JNDI.</p> 

<example title="resin-web.xml">
&lt;reference jndi-name="client/greeting"
           factory="com.caucho.hessian.client.HessianProxyFactory">
  &lt;init-param url="\${app.getURL()}/hessian/greeting"/>
  &lt;init-param type="example.GreetingAPI"/>
&lt;/reference>

&lt;servlet-mapping url-pattern="/client/greeting"
                 servlet-class="example.GreetingClientServlet">
  &lt;init>
    &lt;name>Hessian Client&lt;/name>
    &lt;greeting>\${jndi("client/greeting")}&lt;/greeting>
  &lt;/init>
&lt;/servlet-mapping>
</example>

</section>

<section title="JMX Configuration">

<p>The following JMX configuration shows the flexibility of
the Dependency Injection pattern.  With no changes to either the
Greeting service or its client, the Greeting service can change to
a JMX bean used by and the client to use a JMX proxy.</p>

<example title="resin-web.xml">
&lt;resource mbean-name="type=Greeting"
          mbean-interface="example.GreetingAPI"
          type="example.GreetingImpl">
  &lt;init>
    &lt;greeting>Hello, web.xml&lt;/greeting>
  &lt;/init>
&lt;/resource>

&lt;servlet-mapping url-pattern="/client/greeting"
                 servlet-class="example.GreetingClientServlet">
  &lt;init>
    &lt;name>JMX Client&lt;/name>
    &lt;greeting>\${jndi("mbean:type=Greeting")}&lt;/greeting>
  &lt;/init>
&lt;/servlet-mapping>
</example>

</section>

</section>

  </body>
</document>
