<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>
    <localtoc/>

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

<s1 title="Service Implementation">

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

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

<s2 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>
<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>
<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.
</li>
</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>

</s2>

<s2 title="Configuring the Service">

<p>URL-based services can use the servlet configuration to define the
service.  The service class can use
<a href="../../doc/resin-ioc.xtp">Resin IoC</a> to inject its
own dependencies.</p>

<example title="resin-web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin">

  &lt;servlet-mapping url-pattern="/hessian/greeting"
                   servlet-class="example.GreetingImpl">
    &lt;protocol type="hessian"/>
    
    &lt;init>
      &lt;greeting>Hello from resin-web.xml&lt;/greeting>
    &lt;/init>
  &lt;/servlet-mapping>

&lt;/web-app>
</example>

</s2>

</s1>

<s1 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>
  <li>Burlap proxy</li>
  <li>EJB local object stub</li>
  <li>JMX proxy</li>
  <li>Java bean instance</li>
</ul>

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

<example title="GreetingClientServlet.java">
import javax.webbeans.In;

public class GreetingClientServlet extends GenericServlet {
  @In private GreetingAPI _greeting;

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

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

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

<p>The following code defines the client in the resin.web.xml.
The servlet defined above will inject the <code>GreetingAPI</code>
directly with the WebBeans <code>@In</code> annotation.  Because the
<code>GreetingAPI</code> is unique, there's no need to give it a name.</p>

<example title="resin-web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin">

  &lt;web-service-client class="example.GreetingAPI"
                      url="hessian:${webApp.url}/hessian/greeting"/>

  &lt;servlet-mapping url-pattern="/client/greeting"
                   servlet-class="example.GreetingClientServlet"/>

&lt;/web-app>
</example>

</s2>
<!--
<s2 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"&gt;
  &lt;init&gt;
    &lt;greeting&gt;Hello, web.xml&lt;/greeting&gt;
  &lt;/init&gt;
&lt;/resource&gt;

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

</s2>
-->
</s1>

  </body>
</document>