While using Airtunes via iTunes I messed around with the problem to stream the system sound to the AirportExpress (e.g. Youtube Music).
After looking through some forums I stumbled over a little tool called "Airfoil".
After installing it I can choose the AirportExpress as the output speaker for my system sound:
Now all system sounds are streamed to the AirportExpress and it's possible to play sound of youtube videos directly to the AirportExpress. The sound is a little bit delayed (so using it as movie sound stream is senthless).
30. August 2011
Streaming Sound via Airtunes (AirportExpress)
28. Juni 2011
Java: JAXB: Extend generated Classes
We use the same maven2 configuration as mentioned in this post.
Now we add the following line to the JAXB-plugin configuration:
Our complete pom.xml now looks like here:
After that we create a file called "extend.binding.xml" in the folder "xml/binding/".
The file contains the following information:
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:pd="http://chubb.com/cpi/polsvc/xmlobj"
xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
jxb:extensionBindingPrefixes="inheritance"
version="2.1">
<jxb:bindings schemaLocation="../../src/main/resources/xsd/schema.xsd">
<jxb:bindings node="//xs:element[@name='main.object']/xs:complexType">
<inheritance:extends>com.my.package.BaseClass</inheritance:extends>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
The previous XML tells the xjc compiler that he should extend the class created for the xsd-object main.object from the class called com.my.package.BaseClass.
When running
Now we add the following line to the JAXB-plugin configuration:
<bindingDirectory>${basedir}/xml/binding</bindingDirectory>Our complete pom.xml now looks like here:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.package</groupId>
<artifactId>my-jaxb-artifact</artifactId>
<version>0.1</version>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-testing</artifactId>
<version>0.5.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.5.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<url>http://download.java.net/maven/2</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>maven2-repository.dev.java.net</id>
<url>http://download.java.net/maven/2</url>
</pluginRepository>
<pluginRepository>
<id>central</id>
<url>http://repo1.maven.org/maven2</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<extension>true</extension>
<args>
<arg>-XtoString</arg>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
<arg>-Xcopyable</arg>
<arg>-Xmergeable</arg>
<arg>-Xinheritance</arg>
</args>
<bindingDirectory>${basedir}/xml/binding</bindingDirectory>
<schemaDirectory>${basedir}/src/main/resources/xsd</schemaDirectory>
<packagename>com.my.package</packagename>
<generateDirectory>${basedir}/target/generated-sources/xjc</generateDirectory>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.5.2</version>
</plugin>
</plugins>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${basedir}/build/libs</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
</reporting>
</project>After that we create a file called "extend.binding.xml" in the folder "xml/binding/".
The file contains the following information:
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:pd="http://chubb.com/cpi/polsvc/xmlobj"
xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
jxb:extensionBindingPrefixes="inheritance"
version="2.1">
<jxb:bindings schemaLocation="../../src/main/resources/xsd/schema.xsd">
<jxb:bindings node="//xs:element[@name='main.object']/xs:complexType">
<inheritance:extends>com.my.package.BaseClass</inheritance:extends>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
The previous XML tells the xjc compiler that he should extend the class created for the xsd-object main.object from the class called com.my.package.BaseClass.
When running
mvn generate-sources the BaseClass is subclassed by the generated class for main.object.
Java: JAXB Classes with maven2
With existing XSD-Files JAXB gives a very nice opportunity to autogenerate the fitting Java classes to use the xml-Data based on the mentioned XSD-files.
Based on the xsd objects JAXB (xjc) generates the Java Beans.
The following pom.xml enables JAXB Java source file generation via maven's "generate-sources" goal. The files are created at the directory specified by the "generateDirectory"-tag.
Based on the xsd objects JAXB (xjc) generates the Java Beans.
The following pom.xml enables JAXB Java source file generation via maven's "generate-sources" goal. The files are created at the directory specified by the "generateDirectory"-tag.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.package</groupId>
<artifactId>my-jaxb-artifact</artifactId>
<version>0.1</version>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-testing</artifactId>
<version>0.5.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.5.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<url>http://download.java.net/maven/2</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>maven2-repository.dev.java.net</id>
<url>http://download.java.net/maven/2</url>
</pluginRepository>
<pluginRepository>
<id>central</id>
<url>http://repo1.maven.org/maven2</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<extension>true</extension>
<args>
<arg>-XtoString</arg>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
<arg>-Xcopyable</arg>
<arg>-Xmergeable</arg>
<arg>-Xinheritance</arg>
</args>
<schemaDirectory>${basedir}/src/main/resources/xsd</schemaDirectory>
<packagename>com.my.package</packagename>
<generateDirectory>${basedir}/target/generated-sources/xjc</generateDirectory>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.5.2</version>
</plugin>
</plugins>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${basedir}/build/libs</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
12. April 2011
DBVisualizer: ERROR: column c.reltriggers does not exist
DBVisualizer is one of my favourite database development tools because it's plattform and database independent and is really intuitive.
Since I updated my PostgreSQL Database Instance to V9 I get an error in DBVisualizer due to missing relations in the database.
It is possible to edit the statements DBVisualizer executes for displaying tables and data. Go to the Application folder and Right-Click on the DBVisualizer.app and Choose "Show package contents":
Since I updated my PostgreSQL Database Instance to V9 I get an error in DBVisualizer due to missing relations in the database.
It is possible to edit the statements DBVisualizer executes for displaying tables and data. Go to the Application folder and Right-Click on the DBVisualizer.app and Choose "Show package contents":
Then step down to the following directory
Now open the postgresql8.xml file and search and replace:
Search: (c.reltriggers > 0)Replace: (/*c.reltriggers*/ 0 > 0)Save and close the file. After a restart of the DBVisualizer everything should work fine.
Labels:
Database,
Development,
PostgreSQL,
Tools
18. Februar 2011
ASP.NET: Consuming a PHP WSDL SOAP Webservice
After starting Visual Studio we create a new Visual Basic ASP.NET Web Application project:
After it opens up we right-click on the project name in the "Solution Explorer" and choose "Add Web Reference..."
Now we can press debug and the Internet Explorer should pop up and display in the Label1 field the amount of Customers returned by the WebService.
More information about SOAP Webservices:
PHP : SOAP: Creating and Consuming a WSDL Web-Service
After it opens up we right-click on the project name in the "Solution Explorer" and choose "Add Web Reference..."
Now we can enter the URL of the WSDL file 'http://customer-ws.tld/customer-ws_Customers.wsdl' and press 'Enter'. Visual Studio fetches all the information provided by the xml file and shows up all the data:
We enter a "Web reference name" (I choose 'WSDLWebService') and click on "Add Reference". Now we can see the entered Web Reference in the "Solution Explorer":
I have added a Label with the ID "Label1" with the "Designer" and the Toolbar to the Default-Page:We enter a "Web reference name" (I choose 'WSDLWebService') and click on "Add Reference". Now we can see the entered Web Reference in the "Solution Explorer":
Now we right-click the Web Reference called "WSDLWebService" and choose "View in Object Window":
We can see here that Visual Studio has created all the objects and methods that the WSDL file announced.
So we go to the "Code Editor" of our Default.aspx by right-clicking the file in the "Solution Explorer" and enter the following lines:
Public Class _Default Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim CallWebservice As New WSDLWebService.customer-ws_Customers
Dim Cache As System.Net.CredentialCache = New System.Net.CredentialCache
Dim vUserId As String vUserId = "1889941"
Dim vCustomer() As WSDLWebService.Customer vCustomer = CallWebservice.getCustomers()
Label1.Text = vCustomer.length
End Sub
End Class
Now we can press debug and the Internet Explorer should pop up and display in the Label1 field the amount of Customers returned by the WebService.
More information about SOAP Webservices:
PHP : SOAP: Creating and Consuming a WSDL Web-Service
Labels:
.NET,
ASP,
Development,
PHP,
SOAP,
VisualBasic,
VisualStudio,
WebService,
WSDL
17. Februar 2011
PHP: SOAP: Handle requests with class functions
To use a PHP class to handle the requests fetched by the server script you can simply assign the class file to the server:
More information about SOAP Webservices:
PHP : SOAP: Creating and Consuming a WSDL Web-Service
$vClassName = 'MyHandlerClassName';
$vServer = new SoapServer('customer-ws_Customers.wsdl');
$vServer->setClass($vClassName);
$vServer->handle();
More information about SOAP Webservices:
PHP : SOAP: Creating and Consuming a WSDL Web-Service
Labels:
Development,
PHP,
SOAP,
WebService,
WSDL
PHP : SOAP: Creating and Consuming a WSDL Web-Service
WebServices are very usefull if you need an common interface between external applications and your software. Especially WSDL driven WebServices are widely supported by many programming languages. Some SDKs offer possibilities to automatically create classes, functions and objects that you need to interact with the WSDL WebService.
The WSDL File is an xml file that contains all information about the interface.
So we will find here information about the functionality the interface offers and how to access it. It also delivers the definition of parameters and return values required/delivered by the interface.
The definitions are requiered by the clients who access the WSDL-File to get information about the structure of the WSDL file and how to parse it.
targetNamespace and xmlns:tns are set to the URL (in my case: http://customer-ws.tld/customer-ws_Customers.wsdl) of the WSDL file.
Complex Types
The WSDL delivers simple data types like int, string etc. but in most cases we need much more complex data structures that have to be returned by our service. We have to define complex data types in the WSDL xml file. We define an object called 'Customer' and a type 'CustomerArray' which is an array consists of 'Customer' objects.
The Customer objects has the following attributes:
Methods
Now it's time to define the methods our WebService should offer. For now we are creating 3 different methods:
1. getCustomers()
It returns an array of Customer objects.
2. getCustomer(aCustomerId)
It returns the customer with the given 'aCustomerId' as an Customer object
3. sendCustomer(aCustomer)
It sends a Customer Object to the server and returns the new Customer object.
WSDL method definitions always consists of two parts:
The request defines the handle of the data send to the server and the response the resultset.
Service-Definition
The service definition describes how the WebService is accessed and where the server component is located.
First of all we create a new PHP class that extends the SoapServer class delivered with PHP (if compiled in: for more details see here):
MySoapServer.class.php
Now we create the Customer class that we previously defined in the WSDL file:
Customer.class.php
Then we create the server script, that initializes the SOAP server and supplies the functions we have defined in the WSDL file:
server.php
I've left out the actions inside the CustomerUtility because anything can be done here: fetching/storing from/to database etc.
Now we create the SOAP client script that fetches the data from the WSDL file and connects to the soap server and fetches the data.
client.php:
After we connect to the server, we display all functions (__getFunctions) available by the SOAP webservice. Then we call the getCustomers function and the server responds with an array of customers and we take out the first customer, change its lastname to "My-Changed-Lastname" and send this object back to the server.
The WSDL File
The WSDL File is an xml file that contains all information about the interface.
So we will find here information about the functionality the interface offers and how to access it. It also delivers the definition of parameters and return values required/delivered by the interface.
<?xml version ='1.0' encoding ='iso-8859-1' ?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:tns="http://customer-ws.tld/customer-ws_Customers.wsdl"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://customer-ws.tld/customer-ws_Customers.wsdl"
name="customer-WS">
The definitions are requiered by the clients who access the WSDL-File to get information about the structure of the WSDL file and how to parse it.
targetNamespace and xmlns:tns are set to the URL (in my case: http://customer-ws.tld/customer-ws_Customers.wsdl) of the WSDL file.
Complex Types
<wsdl:types>
<s:schema
targetNamespace="http://customer-ws.tld/customer-ws_Customers.wsdl"
xmlns:tns="http://customer-ws.tld/PAF/customer-ws_Customers.wsdl">
<s:complexType name="Customer">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="customerNr" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="salutation" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="title" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="firstname" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="lastname" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="phone" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="fax" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="email" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="postalZip" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="postalCityName" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="postalStreet" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="postalStreetNumber" type="s:string"/>
</s:sequence>
</s:complexType>
<s:complexType name="CustomerArray">
<s:complexContent>
<s:restriction base="soapenc:Array">
<s:attribute ref="soapenc:arrayType" wsdl:arrayType="tns:Customer[]"/>
</s:restriction>
</s:complexContent>
</s:complexType>
</s:schema>
</wsdl:types>
The WSDL delivers simple data types like int, string etc. but in most cases we need much more complex data structures that have to be returned by our service. We have to define complex data types in the WSDL xml file. We define an object called 'Customer' and a type 'CustomerArray' which is an array consists of 'Customer' objects.
The Customer objects has the following attributes:
- customerNr
- salutation
- title
- firstname
- lastname
- phone
- fax
- postalZip
- postalCityName
- postalStreet
- postalStreetNumber
Methods
Now it's time to define the methods our WebService should offer. For now we are creating 3 different methods:
1. getCustomers()
It returns an array of Customer objects.
2. getCustomer(aCustomerId)
It returns the customer with the given 'aCustomerId' as an Customer object
3. sendCustomer(aCustomer)
It sends a Customer Object to the server and returns the new Customer object.
<wsdl:message name='getCustomersRequest'>
</wsdl:message>
<wsdl:message name='getCustomersResponse'>
<wsdl:part name='Result' type='tns:CustomerArray'/>
</wsdl:message>
<wsdl:message name='getCustomerRequest'>
<wsdl:part name='aCustomerId' type='s:string'/>
</wsdl:message>
<wsdl:message name='getCustomerResponse'>
<wsdl:part name='Result' type='tns:Customer'/>
</wsdl:message>
<wsdl:message name='sendCustomerRequest'>
<wsdl:part name='aCustomer' type='tns:Customer'/>
</wsdl:message>
<wsdl:message name='sendCustomerResponse'>
<wsdl:part name='Result' type='tns:Customer'/>
</wsdl:message>
<wsdl:portType name='CustomerPortType'>
<wsdl:operation name='getCustomers'>
<wsdl:input message='tns:getCustomersRequest'/>
<wsdl:output message='tns:getCustomersResponse'/>
</wsdl:operation>
<wsdl:operation name='getCustomer'>
<wsdl:input message='tns:getCustomerRequest'/>
<wsdl:output message='tns:getCustomerResponse'/>
</wsdl:operation>
<wsdl:operation name='sendCustomer'>
<wsdl:input message='tns:sendCustomerRequest'/>
<wsdl:output message='tns:sendCustomerResponse'/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name='ServiceSoap' type='tns:CustomerPortType'>
<soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/>
<wsdl:operation name='getCustomers'>
<soap:operation soapAction='urn:customer-ws.tld-scramble#getCustomers'/>
<wsdl:input>
<soap:body use='encoded' namespace='urn:customer-ws.tld-scramble'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</wsdl:input>
<wsdl:output>
<soap:body use='encoded' namespace='urn:customer-ws.tld-scramble'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name='getCustomer'>
<soap:operation soapAction='urn:customer-ws.tld-scramble#getCustomer'/>
<wsdl:input>
<soap:body use='encoded' namespace='urn:customer-ws.tld-scramble'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</wsdl:input>
<wsdl:output>
<soap:body use='encoded' namespace='urn:customer-ws.tld-scramble'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name='sendCustomer'>
<soap:operation soapAction='urn:customer-ws.tld-scramble#sendCustomer'/>
<wsdl:input>
<soap:body use='encoded' namespace='urn:customer-ws.tld-scramble'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</wsdl:input>
<wsdl:output>
<soap:body use='encoded' namespace='urn:customer-ws.tld-scramble'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
WSDL method definitions always consists of two parts:
- Request
- Response
The request defines the handle of the data send to the server and the response the resultset.
Service-Definition
The service definition describes how the WebService is accessed and where the server component is located.
<wsdl:service name='customer-WS'>
<wsdl:port name="ServiceSoap" binding="tns:ServiceSoap">
<soap:address location='http://customer-ws.tld/server.php'/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
The SOAP server
First of all we create a new PHP class that extends the SoapServer class delivered with PHP (if compiled in: for more details see here):
MySoapServer.class.php
<?php
if(class_exists('SoapServer')){
class Customer_SoapServer extends SoapServer {
}
}
?>Now we create the Customer class that we previously defined in the WSDL file:
Customer.class.php
<?php
class Customer {
public $customerNr;
public $salutation;
public $title;
public $firstname;
public $lastname;
public $phone;
public $fax;
public $email;
public $postalZip;
public $postalCityName;
public $postalStreet;
public $postalStreetNumber;
}
?>Then we create the server script, that initializes the SOAP server and supplies the functions we have defined in the WSDL file:
server.php
<?php
include('Customer_SoapServer.class.php');
include('Customer.class.php');
public function getCustomers(){
$vCustomers = CustomerUtility::getAllCustomersArray();
$vReturnArray = array();
foreach($vCustomers as $vCustomerId => $vCustomer){
$vWSCustomer = getWSCustomer($vCustomer);
$vReturnArray[] = $vWSCustomer;
}
return $vReturnArray;
}
public function getWSCustomer($vCustomer){
$vWSCustomer = new Customer();
$vWSCustomer->customerNr = $vCustomer['id_user'];
$vWSCustomer->salutation = $vCustomer['salutation'];
$vWSCustomer->title = $vCustomer['title'];
$vWSCustomer->firstname = $vCustomer['firstname'];
$vWSCustomer->lastname = $vCustomer['lastname'];
$vWSCustomer->phone = $vCustomer['tel'];
$vWSCustomer->fax = $vCustomer['fax'];
$vWSCustomer->email = $vCustomer['email'];
$vWSCustomer->postalZip = $vCustomer['postal_zip'];
$vWSCustomer->postalCityName = $vCustomer['postal_city'];
$vWSCustomer->postalStreet = $vCustomer['postal_street'];
$vWSCustomer->postalStreetNumber = $vCustomer['postal_streetnumber'];
return $vWSCustomer;
}
public function getCustomer($aCustomerNr){
$vWSCustomer = getWSCustomer(CustomerUtility::getCustomerArrayByCustomerNr($aCustomerNr));
return $vWSCustomer;
}
public function sendCustomer($aWSCustomer){
$vCustomer = CustomerUtility::storeCustomer($aWSCustomer);
return getCustomer($aWSCustomer->customerNr);
}
// turn off the wsdl cache
ini_set("soap.wsdl_cache_enabled", "0");
$vServer = new Customer_SoapServer("customer-ws_Customers.wsdl");
$vServer->addFunction("getCustomers");
$vServer->addFunction("getCustomer");
$vServer->addFunction("sendCustomer");
$vServer->handle();
?>I've left out the actions inside the CustomerUtility because anything can be done here: fetching/storing from/to database etc.
The SOAP client
Now we create the SOAP client script that fetches the data from the WSDL file and connects to the soap server and fetches the data.
client.php:
<?php
include('Customer.class.php');
// turn off the WSDL cache
ini_set('soap.wsdl_cache_enabled', '0');
$vLocation = 'http://customer-ws.tld/server.php';
try {
$vSoapClient = new SoapClient('http://customer-ws.tld/customer-ws_Customers.wsdl',
array(
"location" => $vLocation,
"trace"=>1, "exceptions"=>1
)
);
$vFunctions = $vSoapClient->__getFunctions();
echo "<pre>";
var_dump($vFunctions);
echo "</pre>";
$vCustomerObjectArray = $vSoapClient->__soapCall( 'getCustomers', array());
echo "<pre>";
var_dump($vCustomerObjectArray);
echo "</pre>";
$vSingleCustomerObject = $vCustomerObjectArray[0];
echo "<pre>";
var_dump($vSingleCustomerObject);
echo "</pre>";
$vSingleCustomerObject->lastname = "My-Changed-Lastname";
$vSendCustomerObject = $vSoapClient->__soapCall( 'sendCustomers', array($vSingleCustomerObject));
echo "<pre>";
var_dump($vSendCustomerObject);
echo "</pre>";
}catch (SoapFault $vException) {
echo "Error:<br />" . nl2br($vException->faultcode) . '<br /><br />Error Details:<br />'. nl2br($vException->faultstring) . '<br />';
echo("<br />REQUEST :<br />" . htmlspecialchars($vSoapClient->__getLastRequest()) . "<br />");
echo("<br />RESPONSE:<br />" .htmlspecialchars($vSoapClient->__getLastResponse()) . "<br />");
}
?>After we connect to the server, we display all functions (__getFunctions) available by the SOAP webservice. Then we call the getCustomers function and the server responds with an array of customers and we take out the first customer, change its lastname to "My-Changed-Lastname" and send this object back to the server.
Labels:
Development,
PHP,
SOAP,
WebService,
WSDL
Abonnieren
Posts (Atom)








