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 > Servlet Transport
Date Mon, 25 Jul 2011 11:41:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/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/Servlet+Transport">Servlet
Transport</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~christian%2Bschneider">Christian
Schneider</a>
    </h4>
        <br/>
                         <h4>Changes (2)</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" >       org.apache.cxf.transport.servlet.CXFServlet
<br>    &lt;/servlet-class&gt; <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
   &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;  <br></td></tr>
            <tr><td class="diff-unchanged" >  &lt;/servlet&gt; <br>
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >    &lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;
<br>    &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt; <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">
   &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;  <br></td></tr>
            <tr><td class="diff-unchanged" >  &lt;/servlet-mapping&gt;
<br>&lt;/web-app&gt; <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h1><a name="ServletTransport-Settingupyourweb.xml"></a>Setting
up your web.xml</h1>

<p>To create services that use this transport you can either use the CXF APIs (for example,
see <a href="/confluence/display/CXF20DOC/Developing+a+Service" title="Developing a Service">JAX-WS</a>)
or create an XML file which registers services for you.</p>

<h2><a name="ServletTransport-PublishinganendpointfromXML"></a>Publishing
an endpoint from XML</h2>

<p>CXF uses <a href="/confluence/display/CXF20DOC/Configuration" title="Configuration">Spring</a>
to provide XML configuration of services. This means that first we'll want to load Spring
via a Servlet listener and tell it where our XML configuration file is:</p>

<p>Next, you'll need to add CXFServlet to your web.xml:</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">"ISO-8859-1"</span>?&gt;</span>
&lt;!DOCTYPE web-app
    PUBLIC <span class="code-quote">"-//Sun Microsystems, Inc.//DTD Web Application
2.3//EN"</span>
    <span class="code-quote">"http://java.sun.com/dtd/web-app_2_3.dtd"</span>&gt;
<span class="code-tag">&lt;web-app&gt;</span>
  <span class="code-tag">&lt;context-param&gt;</span>
	<span class="code-tag">&lt;param-name&gt;</span>contextConfigLocation<span
class="code-tag">&lt;/param-name&gt;</span>
	<span class="code-tag">&lt;param-value&gt;</span>
		classpath:com/acme/ws/services.xml
	<span class="code-tag">&lt;/param-value&gt;</span>
 <span class="code-tag">&lt;/context-param&gt;</span>

  <span class="code-tag">&lt;listener&gt;</span>
     <span class="code-tag">&lt;listener-class&gt;</span>
        org.springframework.web.context.ContextLoaderListener
     <span class="code-tag">&lt;/listener-class&gt;</span>
  <span class="code-tag">&lt;/listener&gt;</span>


  <span class="code-tag">&lt;servlet&gt;</span>
    <span class="code-tag">&lt;servlet-name&gt;</span>CXFServlet<span
class="code-tag">&lt;/servlet-name&gt;</span>
    <span class="code-tag">&lt;display-name&gt;</span>CXF Servlet<span
class="code-tag">&lt;/display-name&gt;</span>
    <span class="code-tag">&lt;servlet-class&gt;</span>
       org.apache.cxf.transport.servlet.CXFServlet
    <span class="code-tag">&lt;/servlet-class&gt;</span>
    <span class="code-tag">&lt;load-on-startup&gt;</span>1<span class="code-tag">&lt;/load-on-startup&gt;</span>

  <span class="code-tag">&lt;/servlet&gt;</span>

  <span class="code-tag">&lt;servlet-mapping&gt;</span>
    <span class="code-tag">&lt;servlet-name&gt;</span>CXFServlet<span
class="code-tag">&lt;/servlet-name&gt;</span>
    <span class="code-tag">&lt;url-pattern&gt;</span>/services/*<span
class="code-tag">&lt;/url-pattern&gt;</span>
  <span class="code-tag">&lt;/servlet-mapping&gt;</span>
<span class="code-tag">&lt;/web-app&gt;</span>
</pre>
</div></div>

<p>Alternatively, you can point to the configuration file using a CXFServlet init parameter
:</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">"ISO-8859-1"</span>?&gt;</span>
&lt;!DOCTYPE web-app
    PUBLIC <span class="code-quote">"-//Sun Microsystems, Inc.//DTD Web Application
2.3//EN"</span>
    <span class="code-quote">"http://java.sun.com/dtd/web-app_2_3.dtd"</span>&gt;
<span class="code-tag">&lt;web-app&gt;</span>

  <span class="code-tag">&lt;servlet&gt;</span>
    <span class="code-tag">&lt;servlet-name&gt;</span>CXFServlet<span
class="code-tag">&lt;/servlet-name&gt;</span>
    <span class="code-tag">&lt;display-name&gt;</span>CXF Servlet<span
class="code-tag">&lt;/display-name&gt;</span>
    <span class="code-tag">&lt;servlet-class&gt;</span>
        org.apache.cxf.transport.servlet.CXFServlet
    <span class="code-tag">&lt;/servlet-class&gt;</span>
    <span class="code-tag">&lt;init-param&gt;</span>
      <span class="code-tag">&lt;param-name&gt;</span>config-location<span
class="code-tag">&lt;/param-name&gt;</span>
      <span class="code-tag">&lt;param-value&gt;</span>/WEB-INF/beans.xml<span
class="code-tag">&lt;/param-value&gt;</span>    
    <span class="code-tag">&lt;/init-param&gt;</span>
    <span class="code-tag">&lt;load-on-startup&gt;</span>1<span class="code-tag">&lt;/load-on-startup&gt;</span>
  <span class="code-tag">&lt;/servlet&gt;</span>

  <span class="code-tag">&lt;servlet-mapping&gt;</span>
    <span class="code-tag">&lt;servlet-name&gt;</span>CXFServlet<span
class="code-tag">&lt;/servlet-name&gt;</span>
    <span class="code-tag">&lt;url-pattern&gt;</span>/services/*<span
class="code-tag">&lt;/url-pattern&gt;</span>
  <span class="code-tag">&lt;/servlet-mapping&gt;</span>
  
  
<span class="code-tag">&lt;/web-app&gt;</span>
</pre>
</div></div>



<p>The next step is to actually write the configuration file:</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:jaxws</span>=<span class="code-quote">"http://cxf.apache.org/jaxws"</span>
      <span class="code-keyword">xmlns:jaxrs</span>=<span class="code-quote">"http://cxf.apache.org/jaxrs"</span>
      xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
         http://cxf.apache.org/jaxws
         http://cxf.apache.org/schemas/jaxws.xsd
         http://cxf.apache.org/jaxrs
         http://cxf.apache.org/schemas/jaxrs.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-soap.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>

  &lt;jaxws:endpoint id=<span class="code-quote">"greeter"</span>
      implementor=<span class="code-quote">"org.apache.hello_soap_http.GreeterImpl"</span>
      address=<span class="code-quote">"/Greeter1"</span>/&gt;

  &lt;jaxrs:server id=<span class="code-quote">"greeterRest"</span>
      serviceClass=<span class="code-quote">"org.apache.hello_soap_http.GreeterImpl"</span>
      address=<span class="code-quote">"/GreeterRest"</span>/&gt; 

<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>
<p>Here we're creating a JAX-WS endpoint based on our implementation class, GreeterImpl.</p>

<p><b>NOTE:</b> We're publishing endpoints "http://localhost/mycontext/services/Greeter1"
and "http://localhost/mycontext/services/GreeterRest", but we set jaxws:endpoint/@address
and jaxrs:server/@address to relative values such as "/Greeter1" "/GreeterRest". </p>


<h2><a name="ServletTransport-Redirectingrequestsandservingthestaticcontent"></a>Redirecting
requests and serving the static content</h2>


<p>Starting from CXF 2.2.5 it is possible to configure CXFServlet to redirect current
requests to other servlets or serve the static resources.</p>

<p>"redirects-list" init parameter can be used to provide a space separated list of
URI patterns; if a given request URI matches one of the patterns then CXFServlet will try
to find a RequestDispatcher using the pathInfo of the current HTTP request and will redirect
the request to it.</p>

<p>"redirect-servlet-path" can be used to affect a RequestDispatcher lookup, if specified
then it will concatenated with the pathInfo of the current request.  </p>

<p>"redirect-servlet-name" init parameter can be used to enable a named RequestDispatcher
look-up, after one of the URI patterns in the "redirects-list" has matched the current request
URI.</p>

<p>"static-resources-list" init parameter can be used to provide a space separated list
of static resource such as html, css, or pdf files which CXFServlet will serve directly. </p>

<p>One can have requests redirected to other servlets or JSP pages. </p>

<p>CXFServlets serving both JAXWS and JAXRS based endpoints can avail of this feature.</p>

<p>For example, please see this <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/WEB-INF/web.xml"
class="external-link" rel="nofollow">web.xml</a>. </p>

<p>The "http://localhost:9080/the/bookstore1/books/html/123" request URI will initially
be matched by the CXFServlet given that it has a more specific URI pattern than the RedirectCXFServlet.
After a current URI has reached a jaxrs:server endpoint, the response will be redirected by
the JAXRS <a href="http://cxf.apache.org/docs/jax-rs.html#JAX-RS-WithRequestDispatcherProvider"
class="external-link" rel="nofollow">RequestDispatcherProvider</a> to a "/book.html"
address, see "dispatchProvider1" bean <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/WEB-INF/beans.xml"
class="external-link" rel="nofollow">here</a>.</p>

<p>Next, the request URI "/book.html" will be handled by a RequestCXFServlet. Note that
a uri pattern can be a regular expression. This servlet redirects the request further to a
RequestDispatcher capable of handling a "/static/book.html".</p>

<p>Finally, DefaultCXFServlet serves a requested book.html.</p>

<h2><a name="ServletTransport-PublishinganendpointwiththeAPI"></a>Publishing
an endpoint with the API</h2>

<p>Once your Servlet is registered in your web.xml, you should set the default bus with
CXFServlet's bus to make sure that CXF uses it as it's HTTP Transport. Simply publish with
the related path "Greeter" and your service should appear at the address you specify:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> javax.xml.ws.Endpoint;
<span class="code-keyword">import</span> org.apache.cxf.Bus;
<span class="code-keyword">import</span> org.apache.cxf.BusFactory;
<span class="code-keyword">import</span> org.apache.cxf.transport.servlet.CXFServlet;
.....
<span class="code-comment">// cxf is the instance of the CXFServlet, you could also
get 
</span><span class="code-comment">// <span class="code-keyword">this</span>
instance by extending the CXFServlet
</span>Bus bus = cxf.getBus();
BusFactory.setDefaultBus(bus); 
Endpoint.publish(<span class="code-quote">"/Greeter"</span>, <span class="code-keyword">new</span>
GreeterImpl());
</pre>
</div></div>
<p>The one thing you must ensure is that your CXFServlet is set up to listen on that
path. Otherwise the CXFServlet will never receive the requests. </p>

<p><b>NOTE:</b> </p>

<p>Endpoint.publish(...) is a JAX-WS API for publishing JAX-WS endpoints.  Thus, it
would require the JAX-WS module and API's to be present.   If you are not using JAX-WS or
want more control over the published endpoint properties, you should replace that call with
the proper calls to the appropriate ServerFactory.</p>

<p>Since CXFServlet know nothing about the web container listen port and the application
context path, you need to specify the relate path instead of full http address.</p>


<h2><a name="ServletTransport-UsingtheservlettransportwithoutSpring"></a>Using
the servlet transport without Spring</h2>

<p>Some user who doesn't want to touch any Spring stuff could also publish the endpoint
with CXF servlet transport. First you should extend the CXFNonSpringServlet and then override
the method loadBus which below codes:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> javax.xml.ws.Endpoint;
...  
  
    @Override
    <span class="code-keyword">public</span> void loadBus(ServletConfig servletConfig)
<span class="code-keyword">throws</span> ServletException {
        <span class="code-keyword">super</span>.loadBus(servletConfig);      
 
        
        <span class="code-comment">// You could add the endpoint publish codes here
</span>        Bus bus = cxf.getBus();
        BusFactory.setDefaultBus(bus); 
        Endpoint.publish(<span class="code-quote">"/Greeter"</span>, <span
class="code-keyword">new</span> GreeterImpl());
        
        <span class="code-comment">// You can als use the simple frontend API to <span
class="code-keyword">do</span> <span class="code-keyword">this</span>
</span>        ServerFactoryBean factroy = <span class="code-keyword">new</span>
ServerFactoryBean();
        factory.setBus(bus);
        factory.setServiceClass(GreeterImpl.class);
        factory.setAddress(<span class="code-quote">"/Greeter"</span>);
        factory.create();              
    }
</pre>
</div></div>

<p>If you are using the Jetty as the embedded servlet engine, you could publish endpoint
like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> javax.xml.ws.Endpoint;
...

        <span class="code-comment">// Setup the system properties to use the CXFBusFactory
not the SpringBusFactory
</span>        <span class="code-object">String</span> busFactory = 
            <span class="code-object">System</span>.getProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME);
        <span class="code-object">System</span>.setProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME,

            <span class="code-quote">"org.apache.cxf.bus.CXFBusFactory"</span>);
        <span class="code-keyword">try</span> {
            <span class="code-comment">// Start up the jetty embedded server
</span>            httpServer = <span class="code-keyword">new</span> Server(9000);
            ContextHandlerCollection contexts = <span class="code-keyword">new</span>
ContextHandlerCollection();
            httpServer.setHandler(contexts);
            
            Context root = <span class="code-keyword">new</span> Context(contexts,
<span class="code-quote">"/"</span>, Context.SESSIONS);
            
            CXFNonSpringServlet cxf = <span class="code-keyword">new</span> CXFNonSpringServlet();
            ServletHolder servlet = <span class="code-keyword">new</span> ServletHolder(cxf);
            servlet.setName(<span class="code-quote">"soap"</span>);
            servlet.setForcedPath(<span class="code-quote">"soap"</span>);
            root.addServlet(servlet, <span class="code-quote">"/soap/*"</span>);
            
            httpServer.start();
            
            Bus bus = cxf.getBus();
            setBus(bus);
            BusFactory.setDefaultBus(bus);
            GreeterImpl impl = <span class="code-keyword">new</span> GreeterImpl();
            Endpoint.publish(<span class="code-quote">"/Greeter"</span>, impl);
        } <span class="code-keyword">catch</span> (Exception e) {
            <span class="code-keyword">throw</span> <span class="code-keyword">new</span>
RuntimeException(e);
        } <span class="code-keyword">finally</span> {
            <span class="code-comment">// clean up the system properties
</span>            <span class="code-keyword">if</span> (busFactory != <span
class="code-keyword">null</span>) {
                <span class="code-object">System</span>.setProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME,

                   busFactory);
            } <span class="code-keyword">else</span> {
                <span class="code-object">System</span>.clearProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME);
            }
        }
</pre>
</div></div>

<h2><a name="ServletTransport-AccessingtheMessageContextand%2ForHTTPRequestandResponse"></a>Accessing
the MessageContext and/or HTTP Request and Response</h2>

<p>Sometimes you'll want to access more specific message details in your service implementation.
 One example might be accessing the actual request or response object itself.  This can be
done using the WebServiceContext object.</p>

<p>First, declare a private field for the <a href="http://java.sun.com/javase/6/docs/api/javax/xml/ws/WebServiceContext.html"
class="external-link" rel="nofollow">WebServiceContext</a> in your service implementation,
and annotate it as a resource:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Resource
<span class="code-keyword">private</span> WebServiceContext context;
</pre>
</div></div>
<p>Then, within your implementing methods, you can access the MessageContext, HttpServletRequest,
and HttpServletResponse as follows:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> javax.servlet.http.HttpServletRequest;
<span class="code-keyword">import</span> javax.servlet.http.HttpServletResponse;
<span class="code-keyword">import</span> javax.xml.ws.handler.MessageContext;
<span class="code-keyword">import</span> org.apache.cxf.transport.http.AbstractHTTPDestination;
...

MessageContext ctx = context.getMessageContext();
HttpServletRequest request = (HttpServletRequest) 
    ctx.get(AbstractHTTPDestination.HTTP_REQUEST);
HttpServletResponse response = (HttpServletResponse) 
    ctx.get(AbstractHTTPDestination.HTTP_RESPONSE);
</pre>
</div></div>
<p>Of course, it is always a good idea to program defensively if using transport-specific
entities like the HttpServletRequest and HttpServletResponse.  If the transport were changed
(for instance to the JMS transport), then these values would likely be null.</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/Servlet+Transport">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=46339&revisedVersion=28&originalVersion=27">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/Servlet+Transport?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message