<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>Apache Wink : 6.2 Configuring the Apache Wink Client</title>
	    <link rel="stylesheet" href="styles/site.css" type="text/css" />
        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">	    
    </head>

    <body>
	    <table class="pagecontent" border="0" cellpadding="0" cellspacing="0" width="100%" bgcolor="#ffffff">
		    <tr>
			    <td valign="top" class="pagebody">
				    <div class="pageheader">
					    <span class="pagetitle">
                            Apache Wink : 6.2 Configuring the Apache Wink Client
                                                    </span>
				    </div>
				    <div class="pagesubheading">
					    This page last changed on Oct 13, 2009 by <font color="#0050B2">michael</font>.
				    </div>

				    <h2><a name="6.2ConfiguringtheApacheWinkClient-ClientConfiguration"></a>Client Configuration</h2>

<p>The RestClient configuration is performed by using the ClientConfig class. An instance of the configuration class is passed to the constructor of the RestClient when constructing a new RestClient.</p>

<p>The following options can be configured in the RestClient:</p>

<ul>
	<li>Custom providers via JAX-RS Application</li>
</ul>


<ul>
	<li>Handler chain</li>
</ul>


<ul>
	<li>Proxy host and port</li>
</ul>


<ul>
	<li>Connect and read timeouts</li>
</ul>


<ul>
	<li>Redirect</li>
</ul>


<h3><a name="6.2ConfiguringtheApacheWinkClient-HandlerConfiguration"></a>Handler Configuration</h3>

<p>The following example demonstrates how to register a custom handler.</p>


<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">1  ClientConfig config = new ClientConfig();
// Create new JAX-RS Application
2  config.handlers(new DummyHandler());
// create the rest client instance
3  RestClient client = new RestClient(config);
// create the resource instance to interact with
4  Resource resource = client.resource(<span class="code-quote">"http://services.com/HelloWorld"</span>);
// perform a GET on the resource
// the resource will be returned as plain text
5  String response = resource.accept(<span class="code-quote">"text/plain"</span>).get(String.class);
</pre>
</div></div>

<h4><a name="6.2ConfiguringtheApacheWinkClient-Explanation"></a>Explanation</h4>

<p>First, a new instance of a ClientConfig is created as it appears in line 1. Then the new handler is added to the handlers chain by invoking the handlers() method on the ClientConfig instance as it appears in line 2. Finally, a new instance of a RestClient is created with this configuration as it appears in line 3.</p>

<h3><a name="6.2ConfiguringtheApacheWinkClient-CustomProviderConfiguration"></a>Custom Provider Configuration</h3>

<p>The following example demonstrates how to register a custom entity provider.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">1  ClientConfig config = new ClientConfig();
   // Create new JAX-RS Application
2    Application app = new Application() {
     @Override
      public Set<span class="code-tag">&lt;Class&lt;?&gt;</span>&gt; getClasses() {
        HashSet<span class="code-tag">&lt;Class&lt;?&gt;</span>&gt; set = new HashSet<span class="code-tag">&lt;Class&lt;?&gt;</span>&gt;();
        set.add(FooProvider.class);
        return set;}};
3  conf.applications(app);
// create the rest client instance
4  RestClient client = new RestClient(config);
// create the resource instance to interact with
5  Resource resource = client.resource(<span class="code-quote">"http://services.com/HelloWorld"</span>);
// perform a GET on the resource. the resource will be returned as plain text
6  String response = resource.accept(<span class="code-quote">"text/plain"</span>).get(String.class);
</pre>
</div></div>

<h4><a name="6.2ConfiguringtheApacheWinkClient-Explanation"></a>Explanation</h4>

<p>First, a new instance of ClientConfig is created as it appears in line 1. Then a new anonymous Application is instantiated and set on the ClientConfig as it appears in line 2 and 3. Finally, a new instance of a RestClient is created with this configuration as it appears in line 4.</p>

				    
                    			    </td>
		    </tr>
	    </table>
	    <table border="0" cellpadding="0" cellspacing="0" width="100%">
			<tr>
				<td height="12" background="http://cwiki.apache.org/confluence/images/border/border_bottom.gif"><img src="images/border/spacer.gif" width="1" height="1" border="0"/></td>
			</tr>
		    <tr>
			    <td align="center"><font color="grey">Document generated by Confluence on Nov 11, 2009 06:57</font></td>
		    </tr>
	    </table>
    </body>
</html>