Modified: websites/production/cxf/content/docs/jax-rs-client-api.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-client-api.html (original)
+++ websites/production/cxf/content/docs/jax-rs-client-api.html Wed Sep 13
15:05:52 2017
@@ -32,8 +32,8 @@
<link type="text/css" rel="stylesheet"
href="/resources/highlighter/styles/shThemeCXF.css">
<script src='/resources/highlighter/scripts/shCore.js'></script>
-<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
+<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script>
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
@@ -121,11 +121,11 @@ Apache CXF -- JAX-RS Client API
 </p><p> </p><p> </p><p> </p><p> </p><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1505311220372 {padding: 0px;}
-div.rbtoc1505311220372 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1505311220372 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1505314945248 {padding: 0px;}
+div.rbtoc1505314945248 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1505314945248 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1505311220372">
+/*]]>*/</style></p><div class="toc-macro rbtoc1505314945248">
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSClientAPI-MavenDependency">Maven Dependency</a></li><li><a
shape="rect" href="#JAX-RSClientAPI-JAX-RS2.0ClientAPI">JAX-RS 2.0 Client
API</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSClientAPI-JAX-RS2.0andCXFspecificAPI">JAX-RS 2.0 and CXF specific
API</a></li></ul>
</li><li><a shape="rect" href="#JAX-RSClientAPI-Proxy-basedAPI">Proxy-based
API</a>
@@ -134,14 +134,14 @@ div.rbtoc1505311220372 li {margin-left:
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSClientAPI-Asynchronousinvocations">Asynchronous
invocations</a></li><li><a shape="rect"
href="#JAX-RSClientAPI-Workingwithexplicitcollections">Working with explicit
collections</a></li><li><a shape="rect"
href="#JAX-RSClientAPI-Handlingexceptions.1">Handling exceptions</a></li><li><a
shape="rect" href="#JAX-RSClientAPI-ConfiguringHTTPclientsinSpring">Configuring
HTTP clients in Spring</a></li></ul>
</li><li><a shape="rect"
href="#JAX-RSClientAPI-XML-centricclients">XML-centric clients</a></li><li><a
shape="rect"
href="#JAX-RSClientAPI-SupportforarbitraryHTTPmethodsforsyncinvocations.">Support
for arbitrary HTTP methods for sync invocations.</a></li><li><a shape="rect"
href="#JAX-RSClientAPI-ThreadSafety">Thread Safety</a></li><li><a shape="rect"
href="#JAX-RSClientAPI-ConfiguringClientsatRuntime">Configuring Clients at
Runtime</a></li><li><a shape="rect"
href="#JAX-RSClientAPI-CreatingclientsprogrammaticallywithnoSpringdependencies">Creating
clients programmatically with no Spring dependencies</a></li><li><a
shape="rect"
href="#JAX-RSClientAPI-ConfiguringanHTTPConduitfromSpring">Configuring an HTTP
Conduit from Spring</a></li><li><a shape="rect"
href="#JAX-RSClientAPI-ClientsandAuthentication">Clients and
Authentication</a></li><li><a shape="rect"
href="#JAX-RSClientAPI-ClientsinSpringBoot">Clients in Spring Boot</a></li></ul>
</div><h1 id="JAX-RSClientAPI-MavenDependency">Maven Dependency</h1><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><dependency>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.0.0-milestone1</version>
</dependency>
</pre>
</div></div><p>In CXF 2.7.x no JAX-RS 2.0 Client API is supported and CXF
specific Client API is located in the cxf-rt-frontend-jaxrs module.</p><p>CXF
Apache HttpClient based transport is required to get the asynchronous
invocations working correctly:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><dependency>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-hc</artifactId>
<!-- 2.7.8 or 3.0.0-milestone1 -->
@@ -149,7 +149,7 @@ div.rbtoc1505311220372 li {margin-left:
</dependency>
</pre>
</div></div><h1 id="JAX-RSClientAPI-JAX-RS2.0ClientAPI">JAX-RS 2.0 Client
API</h1><p>CXF 3.0.0 implements JAX-RS 2.0 Client API. Internally it is
implemented in terms of CXF specific WebClient.</p><p>The <a shape="rect"
class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/index.html"
rel="nofollow">javax.ws.rs.client</a> provides a short overview of how JAX-RS
2.0 Client API works.</p><p>Typically, one starts from <a shape="rect"
class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/ClientBuilder.html"
rel="nofollow">ClientBuilder</a> in order to create a <a shape="rect"
class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/Client.html"
rel="nofollow">Client</a>. <br clear="none"> Next <a shape="rect"
class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/WebTarget.html"
rel="nofollow">WebTarget</a> is created and furthe
r customized as needed.</p><p>Next, <a shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/Invocation.Builder.html"
rel="nofollow">Invocation.Builder</a> is initialized and the request can be
made immediately using one of the <a shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/SyncInvoker.html"
rel="nofollow">SyncInvoker</a> methods, with the builder directly implementing
SyncInvoker.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Client client = ClientBuilder.newBuilder().newClient();
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Client client = ClientBuilder.newBuilder().newClient();
WebTarget target = client.target("http://localhost:8080/rs");
target = target.path("service").queryParam("a", "avalue");
@@ -159,7 +159,7 @@ Book book = builder.get(Book.class);
</pre>
</div></div><p>The above sequence can be easily collapsed into a single code
sequence if preferred.<br clear="none"> Note that SyncInvoker (and
AsyncInvoker) expects <a shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/Entity.html"
rel="nofollow">Entity</a> to represent the request
body.</p><p>Invocation.Builder has a shortcut to <a shape="rect"
class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/Invocation.html"
rel="nofollow">Invocation</a> via its build(...) methods to further customize
the invocation.</p><p>Invocation.Builder.async() links to
AsyncInvoker.</p><p>Client and WebTarget are all can be individually
configured, the implement <a shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/core/Configurable.html"
rel="nofollow">Configurable</a> interface which can accept the providers and
properties and return <a sha
pe="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/core/Configuration.html"
rel="nofollow">Configuration</a>. Configuring the Client directly or
indirectly via ClientBuilder.withConfig method affects all the WebClients
spawned by a given Client.</p><h2
id="JAX-RSClientAPI-JAX-RS2.0andCXFspecificAPI">JAX-RS 2.0 and CXF specific
API</h2><p>CXF proxy and WebClient client code has been retrofitted to support
JAX-RS 2.0 client filters, reader and writer interceptors, new exception
classes and Response API.</p><p>WebClient offers shortcuts to JAX-RS 2.0 <a
shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/AsyncInvoker.html"
rel="nofollow">AsyncInvoker</a> and <a shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/SyncInvoker.html"
rel="nofollow">SyncInvoker</a> interfaces.</p><p>WebClient.getConfig(Object
client) su
pports JAX-RS 2.0 <a shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/WebTarget.html"
rel="nofollow">WebTarget</a> and <a shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/Invocation.Builder.html"
rel="nofollow">Invocation.Builder</a> for 2.0 clients to be able to get to the
lower-level CXF configuration and set up the properties such as
'receiveTimeout', etc.</p><h1 id="JAX-RSClientAPI-Proxy-basedAPI">Proxy-based
API</h1><p>With the proxy-based API, one can reuse on the client side the
interfaces or even the resource classes which have already been designed for
processing the HTTP requests on the server side (note that a <a shape="rect"
class="external-link" href="http://cglib.sourceforge.net/"
rel="nofollow">cglib</a>-nodeps dependency will need to be available on the
classpath for proxies created from concrete classes). When reused on the client
side, the
y simply act as remote proxies.</p><p><a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactory.java">JAXRSClientFactory</a>
is a utility class which wraps <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java">JAXRSClientFactoryBean</a>.
JAXRSClientFactory offers a number of utility methods but
JAXRSClientFactoryBean can also be used directly if desired.</p><p>For example,
given these class definitions:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">@Path("/bookstore")
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Path("/bookstore")
public interface BookStore {
@GET
Books getAllBooks();
@@ -185,7 +185,7 @@ public class BookResourceImpl implements
</pre>
</div></div><p>the following client code retrieves a Book with id '1' and a
collection of books:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">BookStore store =
JAXRSClientFactory.create("http://bookstore.com", BookStore.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">BookStore store =
JAXRSClientFactory.create("http://bookstore.com", BookStore.class);
// (1) remote GET call to http://bookstore.com/bookstore
Books books = store.getAllBooks();
// (2) no remote call
@@ -194,23 +194,23 @@ BookResource subresource = store.getBook
Book b = subresource.getBook();
</pre>
</div></div><p>When proxies are created, initially or when subresource methods
are invoked, the current URI is updated with corresponding @Path, @PathParam,
@QueryParam or @MatrixParam values, while @HttpHeader and @CookieParam values
contribute to the current set of HTTP headers. Same happens before the remote
invocation is done.</p><p>It is important to understand that strictly speaking
there is no direct relationship between a given method on the client side and
the same one on the server side. The job of the proxy is to construct a correct
URI according to given class and method specifications - it may or may not be
the same method on the corresponding server class that will be invoked
(provided of course that it is a JAX-RS annotated server resource class - but
that may not be the case!) More often than not, you will see a method foo()
invoked on a server resource class whenever the same method is invoked on the
corresponding remote proxy - but in the presence of @Path annotati
ons with arbitrary regular expressions this is not guaranteed, however this
doesn't matter, as the most important thing is that a proxy will produce a
correct URI and it will be matched as <strong>expected</strong> by a server
class.</p><p>Client-side MessageBodyReaders and MessageBodyWriters are used to
process request or response bodies just as they do on the server side. More
specifically, method body writers are invoked whenever a remote method
parameter is assumed to be a request body (that is, it has no JAX-RS
annotations attached) or when a form submission is emulated with the help of
either @FormParams or the JAX-RS MultivaluedMap.</p><p>You can make multiple
remote invocations on the same proxy (initial or subresource), the current URI
and headers will be updated properly for each call.</p><p>If you would like to
proxify concrete classes such as BookStoreImpl for example (say you can not
extract interfaces), then drop the cglib-nodeps.jar on a classpath. Such
classes must h
ave a default constructor. All methods which have nothing to do with JAX-RS
will simply be ignored on the client side and marked as unsupported.</p><h2
id="JAX-RSClientAPI-Customizingproxies">Customizing proxies</h2><p>Proxies end
up implementing not only the interface requested at proxy creation time but
also a <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/Client.java">Client</a>
interface. In many cases one does not need to explicitly specify commonly used
HTTP headers such as Content-Type or Accept as this information will likely be
available from @Consumes or @Produces annotations. At the same time you may
explicitly set either of these headers, or indeed some other header. You can
use a simple <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java">WebClient</a>
utility metho
d for converting a proxy to a base client:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
WebClient.client(proxy).accept("text/xml");
// continue using the proxy
</pre>
</div></div><p>You can also check a current set of headers, current and base
URIs and a client Response.</p><h2
id="JAX-RSClientAPI-ConvertingproxiestoWebClientsandviceversa">Converting
proxies to Web Clients and vice versa</h2><p>Using proxies is just one way to
consume a service. Proxies hide away the details of how URIs are being composed
while HTTP-centric WebClients provide for an explicit URI creation. Both
proxies and http clients rely on the same base information such as headers and
the current URI so at any moment of time you can create a WebClient instance
out of the existing proxy:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
Client client = WebClient.client(proxy);
WebClient httpClient = WebClient.fromClient(client);
// continue using the http client
</pre>
</div></div><p>At any moment of time you can convert an http client into a
proxy too:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">BookStore proxy1 =
JAXRSClientFactory.create("http://books", BookStore.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">BookStore proxy1 =
JAXRSClientFactory.create("http://books", BookStore.class);
Client client = WebClient.client(proxy1);
BookStore proxy2 = JAXRSClientFactory.fromClient(client, BookStore.class);
</pre>
</div></div><h2 id="JAX-RSClientAPI-Handlingexceptions">Handling
exceptions</h2><p>There are a couple of ways you can handle remote exceptions
with proxies.<br clear="none"> One approach is to register a <a shape="rect"
class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ResponseExceptionMapper.java">ResponseExceptionMapper</a>
as a provider either from Spring using a jaxrs:client or using a corresponding
JAXRSClientFactory utility method. This way you can map remote error codes to
expected checked exceptions or runtime exceptions if needed.</p><p>If no
ResponseExceptionMapper is available when a remote invocation failed then an
instance of javax.ws.rs.WebApplicationException will be thrown (Note
org.apache.cxf.jaxrs.client.ServerWebApplicationException is used to represent
the server exceptions before CXF 2.7.0.). At this point of time you can check
the actual Response and proceed from there:</p><div clas
s="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
try {
proxy.getBook();
} catch(WebApplicationException ex) {
@@ -219,14 +219,14 @@ try {
}
</pre>
</div></div><p>javax.ws.rs.ProcessingException will be thrown if the exception
has occurred for one of two reasons:</p><ul class="alternate"><li>the remote
invocation succeeded but no proper MessageBodyReader has been found on the
client side; in this case the Response object representing the result of the
invocation will still be available</li><li>the remote invocation has failed for
whatever reasons on the client side, example, no MessageBodyWriter is
available.</li></ul><p>Note
org.apache.cxf.jaxrs.client.ClientWebApplicationException is used to represent
the client processing exceptions before CXF 2.7.0.</p><h2
id="JAX-RSClientAPI-ConfiguringproxiesinSpring">Configuring proxies in
Spring</h2><p>When creating a proxy with JAXRSClientFactory, you can pass a
Spring configuration location as one of the arguments. Or you can create a
default bus using Spring configuration and all proxies will pick it up:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeConten
t panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">SpringBusFactory bf = new SpringBusFactory();
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">SpringBusFactory bf = new SpringBusFactory();
Bus bus =
bf.createBus("org/apache/cxf/systest/jaxrs/security/jaxrs-https.xml");
BusFactory.setDefaultBus(bus);
// BookStore proxy will get the configuration from Spring
BookStore proxy = JAXRSClientFactory.create("http://books", BookStore.class);
</pre>
</div></div><h2 id="JAX-RSClientAPI-Injectingproxies">Injecting
proxies</h2><p>For injecting proxies via a spring context, use the jaxrs:client
element like:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"> <jaxrs:client id="restClient"
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> <jaxrs:client id="restClient"
address="http://localhost:${testutil.ports.BookServerRestSoap}/test/services/rest"
serviceClass="org.apache.cxf.systest.jaxrs.BookStoreJaxrsJaxws"
inheritHeaders="true">
@@ -236,7 +236,7 @@ BookStore proxy = JAXRSClientFactory.cre
</jaxrs:client>
</pre>
</div></div><p>See this <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml">bean</a>
for a full example of how jaxrs:client can be used to inject a proxy. Note
that WebClient can also be injected as a jaxrs:client.</p><p> </p><h2
id="JAX-RSClientAPI-Asynchronousproxyinvocations">Asynchronous proxy
invocations</h2><p>Starting from CXF 3.1.7 it is possible to do the
asynchronous proxy invocations. One needs to register JAX-RS 2.0 <a
shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/client/InvocationCallback.html"
rel="nofollow">InvocationCallback</a> as a proxy request context
property:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
Book book = null;
final InvocationCallback<Book> callback = new
InvocationCallback<Book>() {
@@ -253,7 +253,7 @@ assertNull(proxy.getBook());
Thread.sleep(3);
assertNotNull(book);</pre>
</div></div><p>If you have a proxy with different methods returning different
response types then either register an Object bound InvocationCallback or
register a collection of type-specific callbacks:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class);
// Book
Book book = null;
@@ -286,21 +286,21 @@ assertNull(proxy.getBookChapter(123L));
Thread.sleep(3);
assertNotNull(chapter);</pre>
</div></div><p>Make sure a proxy is created in a thread safe mode if it is
being accessed by multiple threads for every new request thread to have its own
callback.</p><h2 id="JAX-RSClientAPI-BufferingResponses">Buffering
Responses</h2><p>One way to buffer proxy responses is to have a proxy method
return JAX-RS Response, use its bufferEntity()  method (available in
JAX-RS 2.0) and use Response.readEntity which can return typed responses if
preferred.</p><p>The other option is to have a "buffer.proxy.response" property
enabled on a given proxy instance.</p><h2
id="JAX-RSClientAPI-Limitations">Limitations</h2><p>Proxy sub-resource methods
returning Objects can not be invoked. Prefer to have sub-resource methods
returning typed classes: interfaces, abstract classes or concrete
implementations.</p><p> </p><h2
id="JAX-RSClientAPI-Workingwithusermodels">Working with user
models</h2><p>Proxies can be created with the external user model being applied
to a proxy class, for example
:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">JAXRSClientFactory.createFromModel("http://books",
BookNoAnnotations.class, "classpath:/resources/model.xml", null);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">JAXRSClientFactory.createFromModel("http://books",
BookNoAnnotations.class, "classpath:/resources/model.xml", null);
</pre>
</div></div><p>BookNoAnnotations is either an interface or concrete class with
no JAX-RS annotations. Both client proxies and server endpoints can 'turn' it
into a RESTful resource by applying an external user model.</p><h1
id="JAX-RSClientAPI-CXFWebClientAPI">CXF WebClient API</h1><p>HTTP centric
clients are <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java">WebClient</a>
instances which also implement the <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/Client.java">Client</a>
interface. In addition to setting various Client request properties, you can
also make an explicit HTTP invocation with an HTTP verb being the name of a
given operation :</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">WebClient client = WebClient.create("http://books");
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">WebClient client = WebClient.create("http://books");
Book book = client.path("bookstore/books").accept("text/xml").get(Book.class);
</pre>
</div></div><p>You can choose to get an explicit JAX-RS Response instead and
check the response code, headers or entity body if any:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">WebClient client = WebClient.create("http://books");
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">WebClient client = WebClient.create("http://books");
client.path("bookstore/books");
client.type("text/xml").accept("text/xml")
Response r = client.post(new Book());
Book b = r.readEntity(Book.class);
</pre>
</div></div><p>WebClient lets you get back to a base URI or to a previous path
segment and move forward, it can be handy for getting a number of individual
entries from a service with ids embedded in path segments :</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">WebClient client = WebClient.create("http://books");
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">WebClient client = WebClient.create("http://books");
List<Book> books = getBooks(client, 1L, 2L, 3L)
private List<Book> getBooks(WebClient client, Long ...ids) {
@@ -313,17 +313,17 @@ private List<Book> getBooks(WebCli
}
</pre>
</div></div><p>The above code will send requests like "GET <a shape="rect"
class="external-link" href="http://books/1" rel="nofollow">http://books/1</a>",
"GET <a shape="rect" class="external-link" href="http://books/2"
rel="nofollow">http://books/2</a>", etc.</p><p>If the request URI can be
parameterized then you may want to use the following code:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Book book =
WebClient.create("http://books").path("{year}/{id}", 2010, 123).get(Book.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Book book =
WebClient.create("http://books").path("{year}/{id}", 2010, 123).get(Book.class);
// as opposed to
// WebClient.create("http://books").path(2010).path(123).get(Book.class);
</pre>
</div></div><p>When reusing the same WebClient instance for multiple
invocations, one may want to reset its state with the help of the reset()
method, for example, when the Accept header value needs to be changed and the
current URI needs to be reset to the baseURI (as an alternative to a back(true)
call). The resetQuery() method may be used to reset the query values only. Both
options are available for proxies too.</p><p><span
class="confluence-anchor-link"
id="JAX-RSClientAPI-asynchronousinvocations"></span></p><h2
id="JAX-RSClientAPI-Asynchronousinvocations">Asynchronous
invocations</h2><p>WebClient has several methods accepting JAX-RS 2.0 <a
shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/client/InvocationCallback.html"
rel="nofollow">InvocationCallback</a> and returning Future. Alternatively,
users can also use WebClient.async() shortcut to work with a standard <a
shape="rect" class="external-link" href="https://jax-rs-spec.ja
va.net/nonav/2.0/apidocs/javax/ws/rs/client/AsyncInvoker.html"
rel="nofollow">AsyncInvoker</a>.</p><h2
id="JAX-RSClientAPI-Workingwithexplicitcollections">Working with explicit
collections</h2><p>WebClient supports <a shape="rect" class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/core/GenericEntity.html"
rel="nofollow">GenericEntity</a> and JAX-RS 2.0 <a shape="rect"
class="external-link"
href="https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/core/GenericType.html"
rel="nofollow">GenericType</a> directly and via JAX-RS 2.0 SyncInvoker and
AsyncInvoker to make it easier to work with the explicit
collections.</p><p>WebClient also has few collection-aware methods,
example:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Collection<? extends Book> books =
WebClient.getCollection(Book.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Collection<? extends Book> books =
WebClient.getCollection(Book.class);
Collection<? extends Book> books = WebClient.postAndGetCollection(new
ArrayList<Book>(), Book.class);
</pre>
</div></div><h2 id="JAX-RSClientAPI-Handlingexceptions.1">Handling
exceptions</h2><p>You can handle remote exceptions by either explicitly getting
a Response object as shown above and handling error statuses as needed or you
can catch either javax.ws.rs.WebApplicationException or
javax.ws.rs.ProcessingException exceptions, the same way it can be done with
proxies.</p><h2 id="JAX-RSClientAPI-ConfiguringHTTPclientsinSpring">Configuring
HTTP clients in Spring</h2><p>Like proxies, HTTP clients can be created using a
number of WebClient static utility methods: you can pass a location to a Spring
configuration bean if needed or you can set up a default bus as shown above.
For example:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="myJsonProvider"
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="myJsonProvider"
class="org.apache.cxf.jaxrs.provider.JSONProvider" >
<property name="supportUnwrapped" value="true" />
<property name="wrapperName" value="nodeName" />
@@ -341,7 +341,7 @@ value="http://some.base.url.that.respond
</bean>
</pre>
</div></div><p>Note, starting from CXF 2.7.5 it is possible to set-up
WebClient instances the same way as proxies, using jaxrs:client:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><jaxrs:client id="webClient"
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><jaxrs:client id="webClient"
address="https://localhost:${port}/services/rest"
serviceClass="org.apache.cxf.jaxrs.client.WebClient">
<jaxrs:headers>
@@ -350,18 +350,18 @@ value="http://some.base.url.that.respond
</jaxrs:client>
</pre>
</div></div><p>The only limitation of using this option is that some of
jaxrs:client attributes ("inheritHeaders", "modelRef") and elements ("model")
are not really applicable to WebClient.</p><h1
id="JAX-RSClientAPI-XML-centricclients">XML-centric clients</h1><p>XML-centric
clients are WebClients using an <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/xml/XMLSource.java">XMLSource</a>
utility class. XMLSource has a number of methods facilitating the retrieval of
JAXB beans, individual properties or links with the help of XPath expressions.
For example:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">WebClient wc =
WebClient.create("http://aggregated/data");
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">WebClient wc =
WebClient.create("http://aggregated/data");
XMLSource source = wc.get(XMLSource.class);
source.setBuffering(true);
Book b1 = source.getNode("/books/book[position() = 1]", Book.class);
Book b2 = source.getNode("/books/book[position() = 2]", Book.class);
</pre>
</div></div><p>Note that an XMLSource instance can be set to buffer the input
stream thus allowing for executing multiple XPath queries.<br clear="none">
XMlSource can also help with getting the URIs representing the links or XML
instances as Strings.</p><h1
id="JAX-RSClientAPI-SupportforarbitraryHTTPmethodsforsyncinvocations.">Support
for arbitrary HTTP methods for sync invocations.</h1><p>To get the arbitrary
HTTP methods supported with the synchronous client calls or bypass some known
Java HTTPUrlConnection issues (example it will block empty DELETE requests) add
the HttpClient-based transport dependency and set a "use.async.http.conduit"
contextual property.</p><p>This will work as is for asynchronous calls given
that the HttpClient-based transport is required.</p><h1
id="JAX-RSClientAPI-ThreadSafety">Thread Safety</h1><p>Proxies and web clients
(clients) are not thread safe by default. In some cases this can be a
limitation, especially when clients are injected; synchronizing o
n them can cause performance side effects.</p><p>One way to 'make' clients
thread-safe is to use WebClient.fromClient(Client) for web clients or
JAXRSClientFactoryBean.fromClient() factory methods which copy all the original
configuration properties and can be used to create new client instances per
every request.</p><p>A single client doing multiple invocations without
changing the current URI or headers is thread-safe. The only limitation in this
case applies to proxies, in that they can not get "out of band" headers without
synchronizing, ex :</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">// get some response headers passed to us 'out of
band', which is not thread-safe for a plain proxy:
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">// get some response headers passed to us 'out of
band', which is not thread-safe for a plain proxy:
String bookHeader =
WebClient.client(injectedBookStoreProxy).getHeaders().getFirst("BookHeader");
</pre>
</div></div><p>Final option is to use a 'threadSafe' boolean property when
creating proxies or web clients (either from Spring or programmatically), see
this <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultithreadedClientTest.java">test</a>
for more details. Thread-safe clients created this way keep their state in a
thread-local storage.</p><p>If a number of incoming threads is limited then one
option is just do nothing, while the other option is to reset the thread local
state :</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">try {
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">try {
webClient.path("bar")
webClient.header("bar", baz);
webClient.invoke(...);
@@ -371,7 +371,7 @@ String bookHeader = WebClient.client(inj
}
</pre>
</div></div><p>Yet another option is to use JAXRSClientFactoryBean and a
'secondsToKeepState' property for creating thread-safe clients - this will
instruct clients to clean-up the thread-local state periodically.</p><h1
id="JAX-RSClientAPI-ConfiguringClientsatRuntime">Configuring Clients at
Runtime</h1><p>Proxy and http-centric clients are typically created by
JAXRSClientFactory or WebClient factory methods but <a shape="rect"
class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java">JAXRSClientFactoryBean</a>
can also be used for pre-configuring clients before they are
created.</p><p>Sometimes, you may want to configure a client instance after it
is been created. For example, one may want to configure HTTPConduit
programmatically, as opposed to setting its properties using Spring.
ClientConfiguration represents a client-specific configuration state and can be
accessed like this :</
p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Book proxy = JAXRSClientFactory.create("http://books",
Book.class);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Book proxy = JAXRSClientFactory.create("http://books",
Book.class);
ClientConfiguration config = WebClient.getConfig(proxy);
HTTPConduit conduit1 = (HTTPConduit)config.getConduit();
@@ -379,14 +379,14 @@ WebClient webclient = WebClient.create("
HTTPConduit conduit2 =
(HTTPConduit)WebClient.getConfig(webclient).getConduit();
</pre>
</div></div><p>When working with JAX-RS 2.0 Client API one can set some
low-level HTTP properties via Configurable interface:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">//http.connection.timeout
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">//http.connection.timeout
//http.receive.timeout
//http.proxy.server.uri
//http.proxy.server.port
Client client = ClientBuilder.newClient();
client.property("http.receive.timeout", 1000000); </pre>
</div></div><h1
id="JAX-RSClientAPI-CreatingclientsprogrammaticallywithnoSpringdependencies">Creating
clients programmatically with no Spring dependencies</h1><p>Example :</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">JAXRSClientFactoryBean sf = new
JAXRSClientFactoryBean();
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">JAXRSClientFactoryBean sf = new
JAXRSClientFactoryBean();
sf.setResourceClass(CustomerService.class);
sf.setAddress("http://localhost:9000/");
BindingFactoryManager manager =
sf.getBus().getExtension(BindingFactoryManager.class);
@@ -397,19 +397,19 @@ CustomerService service = sf.create(Cust
WebClient wc = sf.createWebClient();
</pre>
</div></div><h1
id="JAX-RSClientAPI-ConfiguringanHTTPConduitfromSpring">Configuring an HTTP
Conduit from Spring</h1><p>There's a number of ways to configure HTTPConduits
for proxies and WebClients.</p><p>It is possible to have an HTTPConduit
configuration which will apply to all clients using different request URIs or
only to those with using a specific URI. For example:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><http:conduit
name="http://books:9095/bookstore.*"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><http:conduit
name="http://books:9095/bookstore.*"/>
</pre>
</div></div><p>This configuration will affect all proxies and WebClients which
have requestURIs starting from 'http://books:9095/bookstore'. Note the trailing
'.*' suffix in the name of the http:conduit element.</p><p>Please see <a
shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/security/jaxrs-https-url.xml">this
configuration file</a> for more examples.</p><p>Alternatively you can just
do:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><http:conduit name="*.http-conduit"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><http:conduit name="*.http-conduit"/>
</pre>
</div></div><p>This configuration will affect all the clients, irrespective of
the URIs being dealt with.</p><p>If you work with proxies then you can have the
proxy-specific configuration using the expanded QName notation:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><http:conduit
name="{http://foo.bar}BookService.http-conduit"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><http:conduit
name="{http://foo.bar}BookService.http-conduit"/>
</pre>
</div></div><p>In this example, 'foo.bar' is a reverse package name of the
BookService proxy class.</p><p>Similarly, for WebClients you can do:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><http:conduit
name="{http://localhost:8080}WebClient.http-conduit"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><http:conduit
name="{http://localhost:8080}WebClient.http-conduit"/>
</pre>
</div></div><p>In this example, 'http://localhost:8080' is the base service
URI.</p><p>Please see <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/security/jaxrs-https-client1.xml">jaxrs-https-client1.xml</a>
and <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/security/jaxrs-https-client2.xml">jaxrs-https-client2.xml</a>
configuration files for more examples.</p><p>Also see <a shape="rect"
href="client-http-transport-including-ssl-support.html">this wiki page</a> on
how to configure HTTPConduits.</p><h1
id="JAX-RSClientAPI-ClientsandAuthentication">Clients and
Authentication</h1><p>Proxies and HTTP-centric clients can have the HTTP
Authorization header set up explicitly:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">// Replace 'user' and 'password' by the actual values
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">// Replace 'user' and 'password' by the actual values
String authorizationHeader = "Basic "
+
org.apache.cxf.common.util.Base64Utility.encode("user:password".getBytes());
@@ -421,7 +421,7 @@ webClient.header("Authorization", author
</pre>
</div></div><p>or by providing a username and password pair at client creation
time, for example:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class, "username",
"password", "classpath:/config/https.xml");
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">BookStore proxy =
JAXRSClientFactory.create("http://books", BookStore.class, "username",
"password", "classpath:/config/https.xml");
WebClient client = WebClient.create("http://books", "username", "password",
"classpath:/config/https.xml");
</pre>
Modified: websites/production/cxf/content/docs/jax-rs-cors.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-cors.html (original)
+++ websites/production/cxf/content/docs/jax-rs-cors.html Wed Sep 13 15:05:52
2017
@@ -32,8 +32,8 @@
<link type="text/css" rel="stylesheet"
href="/resources/highlighter/styles/shThemeCXF.css">
<script src='/resources/highlighter/scripts/shCore.js'></script>
-<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
+<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script>
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
@@ -124,11 +124,11 @@ Apache CXF -- JAX-RS CORS
<style type="text/css">/*<![CDATA[*/
-div.rbtoc1505311214781 {padding: 0px;}
-div.rbtoc1505311214781 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1505311214781 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1505314943907 {padding: 0px;}
+div.rbtoc1505314943907 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1505314943907 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style><div class="toc-macro rbtoc1505311214781">
+/*]]>*/</style><div class="toc-macro rbtoc1505314943907">
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSCORS-Introduction">Introduction</a></li><li><a shape="rect"
href="#JAX-RSCORS-Mavendependencies">Maven dependencies</a></li><li><a
shape="rect" href="#JAX-RSCORS-Examples">Examples</a></li></ul>
</div>
@@ -145,7 +145,7 @@ div.rbtoc1505311214781 li {margin-left:
<h1 id="JAX-RSCORS-Mavendependencies">Maven dependencies</h1>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-security-cors</artifactId>
@@ -161,7 +161,7 @@ div.rbtoc1505311214781 li {margin-left:
<p>Note that an origin is restricted to "http://area51.mil:31415" by the
'allowOrigins' property, which may contain multiple URI values. A boolean
'allowAllOrigins' property can be used instead (to simplify the testing or when
it is deemed it is secure enough within a given environment to allow for all
the origins). </p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">
@CrossOriginResourceSharing(
allowOrigins = {
"http://area51.mil:31415"
@@ -250,7 +250,7 @@ public class AnnotatedCorsServer {
<p>The server configuration fragment:</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">
<beans>
<bean id="cors-filter"
class="org.apache.cxf.rs.security.cors.CrossOriginResourceSharingFilter"/>