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 > JAX-RS and JAX-WS
Date Mon, 03 Jan 2011 17:13: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/JAX-RS+and+JAX-WS">JAX-RS
and JAX-WS</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~sergey_beryozkin">Sergey
Beryozkin</a>
    </h4>
        <br/>
                         <h4>Changes (1)</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" >Note that CXF Continuations API is
supported for both JAXWS and JAXRS services. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h1.
Sharing CXF DataBindings <br> <br>JAX-WS and JAX-RS endpoints can be configured
to share a single CXF DataBinding instance for reading/writing the data. <br>Please
see the [CXF DataBindings|https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Data+Bindings#JAX-RSDataBindings-CXFDataBindingsasJAXRSproviders]
section for more information. <br> <br>h1. Sharing JAX-RS Providers <br>
<br>JAX-WS and JAX-RS endpoints can be configured to share a single JAX-RS provider
instance for reading/writing the data. <br>Please see the [JAX-RS DataBinding|https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Data+Bindings#JAX-RSDataBindings-JAXRSDataBinding]
for more information. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h1. Dealing with contexts <br>
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <span style="font-size:2em;font-weight:bold"> JAX-RS and JAX-WS </span>

<div>
<ul>
    <li><a href='#JAX-RSandJAX-WS-JAXRSandJAXWS'>JAX-RS and JAX-WS</a></li>
    <li><a href='#JAX-RSandJAX-WS-SharingCXFDataBindings'>Sharing CXF DataBindings</a></li>
    <li><a href='#JAX-RSandJAX-WS-SharingJAXRSProviders'>Sharing JAX-RS Providers</a></li>
    <li><a href='#JAX-RSandJAX-WS-Dealingwithcontexts'>Dealing with contexts</a></li>
    <li><a href='#JAX-RSandJAX-WS-Applyingexternalusermodels'>Applying external
user models</a></li>
</ul></div>


<h1><a name="JAX-RSandJAX-WS-JAXRSandJAXWS"></a>JAX-RS and JAX-WS</h1>

<p>Here's a beans.xml showing how to have a single service class supporting both SOAP
and REST-based invocations at the same time with the help of JAX-WS and JAX-RS : </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;?xml version=<span class="code-quote">"1.0"</span>
encoding=<span class="code-quote">"UTF-8"</span>?&gt;</span>
&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:jaxrs</span>=<span class="code-quote">"http://cxf.apache.org/jaxrs"</span>
  <span class="code-keyword">xmlns:jaxws</span>=<span class="code-quote">"http://cxf.apache.org/jaxws"</span>
  xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd"&gt;

  <span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf.xml"</span>
/&gt;</span>
  <span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"</span>
/&gt;</span>
  <span class="code-tag">&lt;import resource=<span class="code-quote">"classpath:META-INF/cxf/cxf-servlet.xml"</span>
/&gt;</span>

  <span class="code-tag"><span class="code-comment">&lt;!-- JAX-RS --&gt;</span></span>
  <span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService"</span>
address=<span class="code-quote">"/"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"customerService"</span>
/&gt;</span>
    <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>
  <span class="code-tag">&lt;/jaxrs:server&gt;</span>

  <span class="code-tag"><span class="code-comment">&lt;!-- JAX-WS --&gt;</span></span>
  &lt;jaxws:endpoint implementor=<span class="code-quote">"#customerService"</span>
    address=<span class="code-quote">"/CustomerWorld"</span> wsdlLocation=<span
class="code-quote">"..."</span>/&gt;
  
  <span class="code-tag">&lt;bean id=<span class="code-quote">"customerService"</span>
class=<span class="code-quote">"demo.jaxrs.server.CustomerService"</span> /&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>

<p>Either contract-first or Java-first approach can be used for JAX-WS. JAX-RS annotations
can be added to the existing service class. Some custom providers may need to be created,
depending on the complexity of the method signatures.</p>

<p>When a WSDL-first approach is used then a document-literal-wrapped style may or may
not be a good fit as the code generator unwraps all the types into a signature, for example
:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class CustomerService {
   <span class="code-keyword">public</span> void doIt(<span class="code-object">String</span>
a, <span class="code-object">String</span> b) {...};
}
</pre>
</div></div>  

<p>By default JAX-RS may not be able to handle such methods as it requires that only
a single parameter can be available in a signature that is not annotated by one of the JAX-RS
annotations like @PathParam. So if <br/>
a 'String a' parameter can be mapped to a @Path template variable or one of the query segments
then this signature won't need to be changed :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customers/{a}"</span>)
<span class="code-keyword">public</span> class CustomerService {
   <span class="code-keyword">public</span> void doIt(@PathParam(<span class="code-quote">"a"</span>)
<span class="code-object">String</span> a, <span class="code-object">String</span>
b) {...};
}
</pre>
</div></div>  

<p>Note that CXF Continuations API is supported for both JAXWS and JAXRS services.</p>

<h1><a name="JAX-RSandJAX-WS-SharingCXFDataBindings"></a>Sharing CXF DataBindings</h1>

<p>JAX-WS and JAX-RS endpoints can be configured to share a single CXF DataBinding instance
for reading/writing the data.<br/>
Please see the <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Data+Bindings#JAX-RSDataBindings-CXFDataBindingsasJAXRSproviders"
class="external-link" rel="nofollow">CXF DataBindings</a> section for more information.</p>

<h1><a name="JAX-RSandJAX-WS-SharingJAXRSProviders"></a>Sharing JAX-RS Providers</h1>

<p>JAX-WS and JAX-RS endpoints can be configured to share a single JAX-RS provider instance
for reading/writing the data.<br/>
Please see the <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Data+Bindings#JAX-RSDataBindings-JAXRSDataBinding"
class="external-link" rel="nofollow">JAX-RS DataBinding</a> for more information.</p>

<h1><a name="JAX-RSandJAX-WS-Dealingwithcontexts"></a>Dealing with contexts</h1>

<p>When combining JAXWS and JAXRS, one may need to access some context information as
part of processing a given request. At the moment, CXF JAXRS does not offer a context implementation
which can be used to access a request-specific information common for both JAXWS and JAXRS
requests, in cases when the same methods are used to handle both JAXWS and JAXRS requests.
Please use a JAXWS WebServiceContext and JAXRS contexts or CXF JAXRS composite MessageContext
:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customers"</span>)
@WebService
<span class="code-keyword">public</span> class CustomerService {

   @Resource WebServiceContext jaxwsContext;
   @Resource MessageContext jaxrsContext;

   @WebMethod
   @POST
   <span class="code-keyword">public</span> void doIt(<span class="code-object">String</span>
b) {
       isUserInRole();
   };

   <span class="code-keyword">private</span> void isUserInRole() <span class="code-keyword">throws</span>
WebApplicationException {
       <span class="code-keyword">if</span> (jaxwsContext.getSecurityContext()
!= <span class="code-keyword">null</span>) {
           <span class="code-comment">// soap invocation
</span>           jaxwsContext.getSecurityContext().isUserInRole(theRole);
       } <span class="code-keyword">else</span> {
           <span class="code-comment">// http-only jaxrs one
</span>           jaxrsContext.getSecurityContext().isUserInRole(theRole);
       }  
   }
}
</pre>
</div></div>  

<p>Note that injected context instances (jaxwsContext and jaxrsContext) are in fact
thread-local proxies hence they will not be equal to null even if they do not represent a
given request. For example, jaxrsContext will not be equal to null even if it's not a JAXWS
invocation which is being processed at the moment.</p>

<p>However, if say a (JAXWS or JAXRS) SecurityContext needs to be accessed then it will
be set in, say, jaxwsContext only if it's a JAXWS/SOAP invocation. For this reason it can
be handy using a composite CXF JAXRS MessageContext when accessing a JAXRS-specific context
information when combining JAXWS and JAXRS as one can easily check if it's actually a JAXRS
request by simply checking an individual context like SecurityContext or UriInfo for null.</p>

<p>Using individual contexts like JAXRS SecurityContext might be less attractive :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@WebService
<span class="code-keyword">public</span> class CustomerService {
   @Resource WebServiceContext jaxwsContext;
   <span class="code-comment">// @Resource can be applied too
</span>   @Context SecurityContext jaxrsSecurityContext;  
}
</pre>
</div></div>

<p>as some methods of SecurityContext return boolean values so only throwing a runtime
exception can reliably indicate that this context is actually not in scope.</p>

<p>Note that if you do not share the same service methods between JAXRS and JAXWS invocations
then you can directly access corresponding contexts : </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customers"</span>)
@WebService
<span class="code-keyword">public</span> class CustomerService {

   @Resource WebServiceContext jaxwsContext;
   @Resource MessageContext jaxrsContext;

   @WebMethod
   <span class="code-keyword">public</span> void doItSoap(<span class="code-object">String</span>
b) {
       isUserInRole(jaxwsContext.getSecurityContext().getPrincipal());
   };

   @POST
   <span class="code-keyword">public</span> void doItSoap(<span class="code-object">String</span>
b) {
       isUserInRole(jaxwsContext.getSecurityContext().getPrincipal());
   }

   <span class="code-keyword">private</span> void isUserInRole(Principal p) <span
class="code-keyword">throws</span> WebApplicationException {
       ...  
   }
}
</pre>
</div></div>

<p>Another option is to avoid the use of contexts in the service code and deal with
them in CXF interceptors or JAXRS filters. Sometimes it's possible to avoid the use of contexts
altogether. For example, Spring Security can be used to secure a given service at an individual
method level.     </p>

<h1><a name="JAX-RSandJAX-WS-Applyingexternalusermodels"></a>Applying external
user models</h1>

<p>When using a WSDL-first approach toward developing the SOAP services you may not
want or be able to add JAX-RS annotations to the generated service interface class. Indirectly
applying an external user model to this service class via the jaxrs:server endpoint makes
it possible to REST-ify the service without making the code changes.</p>
    </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/JAX-RS+and+JAX-WS">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=24190959&revisedVersion=2&originalVersion=1">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+and+JAX-WS?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message