cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF Documentation > Simple Frontend
Date Mon, 11 Oct 2010 02:42:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/1/_/styles/combined.css?spaceKey=CXF20DOC&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Simple+Frontend">Simple
Frontend</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~bimargulies@gmail.com">Benson
Margulies</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        Fix thinko<br />
    </div>
        <br/>
                         <h4>Changes (5)</h4>
                                 
    
<div id="page-diffs">
            <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >The typical pattern of a web service
is to define a Service Endpoint Interface and then create a class that implements that interface.
When you own both ends of the process, you can simply use the SEI in both the server and the
client. <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The
problem has to do with a quirk of Java reflection. If a program uses Java reflection to examine
a function in a class, the Java Language Specification _requires_ the system to provide the
parameter names from the source. However, if a program uses reflection to look at an *interface*,
the specification _does not require_ parameter names. In practical terms, the usual Java compilers
preserve interface parameter names _only_ when compiling with debug information. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The
problem has to do with a quirk of Java reflection. If a program uses Java reflection to examine
a concrete method of a class, the Java Language Specification _requires_ the system to provide
the parameter names from the source. However, if a program uses reflection to look at an *abstract
method*, the specification _does not require_ parameter names.  <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">This
leads to the following trap: If you turn debug information on and off when compiling the SEI,
you will *change the WSDL model*. Incompatibly. If the server and client disagree on the compilation
options, they can fail to communicate. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">This
leads to ugly parameters named {{arg0}}, {{arg1}}, ... Further, if you forget to specify the
SEI when creating a service, and only provide the SEB, Simple will see your concrete methods
and assign actual parameter names. If you client uses the SEI, they won&#39;t communicate.
<br></td></tr>
            <tr><td class="diff-unchanged" > <br>Thus, while JAX-WS {{@WebParam}}
annotations may seem noisy and inconvenient, they are, in fact, ensuring that your service
has a consistent contract. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >If you choose to use the Simple
front end, you will need to use {{parameter}} elements in a {{.aegis.xml}} file to specify
the parameter <span class="diff-changed-words">names<span class="diff-added-chars"style="background-color:
#dfd;"> or be sure to provide the SEI to the {{ServerFactoryBean}}</span>.</span>
<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h2. Simple and Data Bindings
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>CXF provides the 'simple' frontend to map Java APIs to and from WSDL models
for web services. The simple front end is much like <a href="/confluence/display/CXF20DOC/JAX-WS"
title="JAX-WS">JAX&#45;WS</a>, however, where JAX-WS uses Java annotations to
specify detailed configuration (and, indeed, requires a few), Simple is willing to map a 'naked'
interface or class to a service, and respects some configuration options from .aegis.xml files
shared with the Aegis data binding.</p>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>Most Applications Should
Use JAX-WS</b><br />The JAX-WS frontend is far more flexible than the Simple frontend.
There are only two reasons to select Simple over JAX-WS:
<ol>
	<li>You must avoid the use of Java annotations. JAX-WS requires them, Simple does not.</li>
	<li>You want to have the absolutely smallest possible collection of additional dependencies.
JAX-WS has more dependencies than Simple.</li>
</ol>


<p>Other than these items, Simple has no advantages over JAX-WS. The implementation
classes of JAX-WS in CXF are all subclasses of the implementation classes of Simple. In a
'simple' case, very nearly identical things happen in the Simple front end as in JAX-WS. CXF's
extensions to JAX-WS, on the other hand, make it very 'simple' to use.</p></td></tr></table></div>
<h2><a name="SimpleFrontend-SimplePitfall%3AUnreliableParameterNames"></a>Simple
Pitfall: Unreliable Parameter Names</h2>

<p>The following pitfall exists, in fact, for both Simple and JAX-WS, but it is much
easier to avoid it with JAX-WS.</p>

<p>The typical pattern of a web service is to define a Service Endpoint Interface and
then create a class that implements that interface. When you own both ends of the process,
you can simply use the SEI in both the server and the client.</p>

<p>The problem has to do with a quirk of Java reflection. If a program uses Java reflection
to examine a concrete method of a class, the Java Language Specification <em>requires</em>
the system to provide the parameter names from the source. However, if a program uses reflection
to look at an <b>abstract method</b>, the specification <em>does not require</em>
parameter names. </p>

<p>This leads to ugly parameters named <tt>arg0</tt>, <tt>arg1</tt>,
... Further, if you forget to specify the SEI when creating a service, and only provide the
SEB, Simple will see your concrete methods and assign actual parameter names. If you client
uses the SEI, they won't communicate.</p>

<p>Thus, while JAX-WS <tt>@WebParam</tt> annotations may seem noisy and
inconvenient, they are, in fact, ensuring that your service has a consistent contract.</p>

<p>If you choose to use the Simple front end, you will need to use <tt>parameter</tt>
elements in a <tt>.aegis.xml</tt> file to specify the parameter names or be sure
to provide the SEI to the <tt>ServerFactoryBean</tt>.  </p>

<h2><a name="SimpleFrontend-SimpleandDataBindings"></a>Simple and Data Bindings</h2>

<p>By default CXF uses the JAXB databinding. This is a historical default, but often
not what you will want, both due to the pitfall described above and the JAX-B issue described
at the bottom of this page. If you choose to use the Simple front end, we recommend that you
use <a href="/confluence/display/CXF20DOC/Aegis+%282.1%29" title="Aegis (2.1)">the Aegis
databinding</a>.</p>

<h2><a name="SimpleFrontend-ServerFactoryBeanMakingaServiceEndpoint"></a>ServerFactoryBean
&#8211; Making a Service Endpoint</h2>
<p>The ServerFactoryBean produces a Server instance for you. It requires a service class
and an address to publish the service on. By creating a Server you'll have started your service
and made it available to the outside world.</p>

<p>First you'll want to create your service class:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-keyword">interface</span>
HelloWorld {
  <span class="code-object">String</span> sayHi(<span class="code-object">String</span>
text);
}
</pre>
</div></div>
<p>This does not have to be an interface, but we're going to use an interface for this
example because</p>
<ol>
	<li>It is good to separate out your service contract (your interface) from your implementation</li>
	<li>This allows us to easily create a Java Proxy client</li>
</ol>


<p>We'll also need an implementation class:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class HelloWorldImpl <span class="code-keyword">implements</span>
HelloWorld {
  <span class="code-keyword">public</span> <span class="code-object">String</span>
sayHi(<span class="code-object">String</span> text) {
    <span class="code-keyword">return</span> <span class="code-quote">"Hello
"</span> + text;
  }
}
</pre>
</div></div>

<p>And now we'll want to create a Server from this</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> org.apache.cxf.frontend.ServerFactoryBean;
...

<span class="code-comment">// Create our service implementation
</span>HelloWorldImpl helloWorldImpl = <span class="code-keyword">new</span>
HelloWorldImpl();

<span class="code-comment">// Create our Server
</span>ServerFactoryBean svrFactory = <span class="code-keyword">new</span>
ServerFactoryBean();
svrFactory.setServiceClass(HelloWorld.class);
svrFactory.setAddress(<span class="code-quote">"http:<span class="code-comment">//localhost:9000/Hello"</span>);
</span>svrFactory.setServiceBean(helloWorldImpl);
svrFactory.create();
</pre>
</div></div>

<p>Your service is now started! You can access the wsdl at "<a href="http://localhost:9000/Hello?wsdl"
class="external-link" rel="nofollow">http://localhost:9000/Hello?wsdl</a>".</p>

<h2><a name="SimpleFrontend-ClientProxyFactoryBeanMakingaClientProxy"></a>ClientProxyFactoryBean
&#8211; Making a Client Proxy</h2>
<p>You'll also want to create a client for your service. CXF includes a ClientProxyFactoryBean
which will create a Java proxy for you from your interface which will invoke the service.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> demo.hw.server.HelloWorld;
<span class="code-keyword">import</span> org.apache.cxf.frontend.ClientProxyFactoryBean;
...

ClientProxyFactoryBean factory = <span class="code-keyword">new</span> ClientProxyFactoryBean();
factory.setServiceClass(HelloWorld.class);
factory.setAddress(<span class="code-quote">"http:<span class="code-comment">//localhost:9000/Hello"</span>);
</span>HelloWorld client = (HelloWorld) factory.create();
</pre>
</div></div>

<p>You simply need to set your service class and your service's URL on the bean. Calling
create() will then create a proxy for you based on your interface.</p>

<h2><a name="SimpleFrontend-ConfigurewithSpring"></a>Configure with Spring
</h2>

<p>The XML configuration for do-it-yourself Spring beans and cxf.xml or cxf-servlet.xml
are all very similiar. <br/>
The simple front-end does not have its own extension, so you don't need any extra imports
if are setting up your<br/>
own application context.</p>

<p>Here's an example cxf-servlet.xml with simple front end endpoint configuration. If
you use your own application context, you'll need to import the soap extension and http servlet
extension. </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;beans xmlns=<span class="code-quote">"http://www.springframework.org/schema/beans"</span>
      <span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
      <span class="code-keyword">xmlns:simple</span>=<span class="code-quote">"http://cxf.apache.org/simple"</span>
      <span class="code-keyword">xmlns:soap</span>=<span class="code-quote">"http://cxf.apache.org/bindings/soap"</span>
      xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd"&gt;

  <span class="code-tag">&lt;simple:server id=<span class="code-quote">"pojoservice"</span>
serviceClass=<span class="code-quote">"demo.hw.server.HelloWorld"</span> address=<span
class="code-quote">"/hello_world"</span>&gt;</span>
  	<span class="code-tag">&lt;simple:serviceBean&gt;</span>
  		<span class="code-tag">&lt;bean class=<span class="code-quote">"demo.hw.server.HelloWorldImpl"</span>
/&gt;</span>
  	<span class="code-tag">&lt;/simple:serviceBean&gt;</span>
  <span class="code-tag">&lt;/simple:server&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>

<h2><a name="SimpleFrontend-DeployingSimpleFrontEndservicetoacontainer"></a>Deploying
Simple FrontEnd service to a container</h2>
<p>If you are looking to deploy the service  to a container follow the steps in "Transports-&gt;HTTP
Transport -&gt; Servlet Transport" section from the Table of contents. Add the xml content
from the above section "Configure cxf-servlet.xml". Name your configuration file as say services.xml.
Do not name it as cxf-servlet.xml.<br/>
You need to add the import statements from the sample configuration file in  "Transports-&gt;HTTP
Transport -&gt; Servlet Transport"</p>

<h2><a name="SimpleFrontend-WellKnownIssue"></a>Well-Known Issue</h2>
<div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/forbidden.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td>There is a known issue
for the JAXB data binding with POJO, please see Dan Kulp's comment in <a href="https://issues.apache.org/jira/browse/CXF-897"
class="external-link" rel="nofollow">https://issues.apache.org/jira/browse/CXF-897</a>
.<br/>
If you want to use JAXB binding you should use the <a href="/confluence/display/CXF20DOC/JAX-WS"
title="JAX-WS">JAX&#45;WS</a> Frontend. Mixing Simple Frontend and JAXB binding
leads to problems. The article <a href="/confluence/display/CXF20DOC/A+simple+JAX-WS+service"
title="A simple JAX-WS service">A simple JAX&#45;WS service</a> shows a code
first JAX-WS service that is almost as easy to use as the Simple Frontend.</td></tr></table></div>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Simple+Frontend">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=49556&revisedVersion=20&originalVersion=19">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Simple+Frontend?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message