JAX-WS Attachment with MTOM
Creating sample JAX-WS service using Message Transmission Optimization Mechanism (MTOM) to send attachment.
In SOAP world, request and response are transmitted via XML format only. When sending/receiving binary data/ file (byte[]), it will be converted to XML base 64 which will increase request / response size by 33%. To avoid this, file can be send via MTOM or XML binary Optimized packaging (XOP). This will send file as attachment without any conversation and hence size of request / response will be more or less same.
Let us create exam using MTOM. In this post, we are creating Profile Web Service. Profile contains - name, address and display image. There are 2 operations:-
Profile Client:-
Create new java project, create client using wsimport and add generated files in project. Below is Profile client example:
Create Profile Request/Response:-
Get Profile Request/Response:-
Cheers..!!!
In SOAP world, request and response are transmitted via XML format only. When sending/receiving binary data/ file (byte[]), it will be converted to XML base 64 which will increase request / response size by 33%. To avoid this, file can be send via MTOM or XML binary Optimized packaging (XOP). This will send file as attachment without any conversation and hence size of request / response will be more or less same.
Let us create exam using MTOM. In this post, we are creating Profile Web Service. Profile contains - name, address and display image. There are 2 operations:-
- Create Profile
- Get Profile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.profile.service; | |
import java.awt.Image; | |
import javax.xml.bind.annotation.XmlRootElement; | |
@XmlRootElement | |
public class Profile { | |
private String name; | |
private String address; | |
private Image displayPhoto; | |
/** | |
* @return the name | |
*/ | |
public String getName() { | |
return name; | |
} | |
/** | |
* @param name | |
* the name to set | |
*/ | |
public void setName(String name) { | |
this.name = name; | |
} | |
/** | |
* @return the address | |
*/ | |
public String getAddress() { | |
return address; | |
} | |
/** | |
* @param address | |
* the address to set | |
*/ | |
public void setAddress(String address) { | |
this.address = address; | |
} | |
/** | |
* @return the displayPhoto | |
*/ | |
public Image getDisplayPhoto() { | |
return displayPhoto; | |
} | |
/** | |
* @param displayPhoto | |
* the displayPhoto to set | |
*/ | |
public void setDisplayPhoto(Image displayPhoto) { | |
this.displayPhoto = displayPhoto; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.profile.service; | |
import java.util.HashMap; | |
import java.util.Map; | |
/** | |
* In memory Profile database | |
* | |
* | |
*/ | |
public class ProfileDB { | |
private static final Map<String, Profile> profiles = new HashMap<>(); | |
public static void addProfile(final Profile profile) { | |
profiles.put(profile.getName(), profile); | |
} | |
public static Profile getProfile(final String name) { | |
return profiles.get(name); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.profile.service; | |
import javax.jws.WebService; | |
/** | |
* Service Endpoint Interface | |
* | |
*/ | |
@WebService(name = "ProfileService") | |
public interface ProfileService { | |
public String createProfile(Profile profile); | |
public Profile getProfile(String name); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.profile.service; | |
import javax.jws.WebService; | |
import javax.xml.ws.soap.MTOM; | |
/** | |
* | |
* Service Implementation bean | |
*/ | |
@MTOM | |
@WebService(endpointInterface = "com.profile.service.ProfileService") | |
public class ProfileServiceImpl implements ProfileService { | |
@Override | |
public String createProfile(Profile profile) { | |
ProfileDB.addProfile(profile); | |
return profile.getName()+ " Created."; | |
} | |
@Override | |
public Profile getProfile(String name) { | |
return ProfileDB.getProfile(name); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.profile.service; | |
import javax.xml.ws.Endpoint; | |
/** | |
* Profile Service Publisher | |
* | |
*/ | |
public class ProfileServicePublisher { | |
public static void main(String[] args) { | |
Endpoint.publish("http://localhost:8080/ws/pofile", new ProfileServiceImpl()); | |
System.out.println("Profile Service running at http://localhost:8080/ws/pofile"); | |
} | |
} |
Profile Client:-
Create new java project, create client using wsimport and add generated files in project. Below is Profile client example:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.profile.service; | |
import java.io.IOException; | |
import java.net.URL; | |
import java.nio.file.Files; | |
import java.nio.file.Paths; | |
import javax.xml.namespace.QName; | |
import javax.xml.ws.BindingProvider; | |
import javax.xml.ws.Service; | |
import javax.xml.ws.soap.SOAPBinding; | |
public class ProfileClient { | |
private static final ObjectFactory FACTORY = new ObjectFactory(); | |
private static final String TESTFILE = "/var/tmp/test.png"; | |
public static void main(String[] args) throws IOException { | |
// Create Proxy | |
URL url = new URL("http://localhost:8080/ws/pofile?wsdl"); | |
QName qname = new QName("http://service.profile.com/", "ProfileServiceImplService"); | |
Service service = Service.create(url, qname); | |
ProfileService profileService = service.getPort(ProfileService.class); | |
// Enabling MTOM at client end | |
BindingProvider bp = (BindingProvider) profileService; | |
SOAPBinding binding = (SOAPBinding) bp.getBinding(); | |
binding.setMTOMEnabled(true); | |
// Create Profile | |
System.out.println("Creating Profile"); | |
String profileName = profileService.createProfile(getProfile()); | |
System.out.println("Response from Create profile " + profileName); | |
// Get Profile | |
System.out.println("\n\nCalling Get Profile"); | |
Profile response = profileService.getProfile("Test User"); | |
System.out.println(response.getName() + "\n"+response.getAddress() ); | |
} | |
private static Profile getProfile() throws IOException { | |
Profile profile = FACTORY.createProfile(); | |
profile.setName("Test User"); | |
profile.setAddress("Address Lines...."); | |
profile.setDisplayPhoto( Files.readAllBytes( Paths.get(TESTFILE) ) ); | |
return profile; | |
} | |
} |
Create Profile Request/Response:-
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---[HTTP request]--- | |
Accept: text/xml, multipart/related | |
Connection: keep-alive | |
Host: localhost:8080 | |
User-agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e | |
Content-type: multipart/related;start="<rootpart*4db29ca4-a6eb-4596-a5d4-ae0fda21c201@example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:4db29ca4-a6eb-4596-a5d4-ae0fda21c201";start-info="text/xml" | |
Soapaction: "http://service.profile.com/ProfileService/createProfileRequest" | |
Content-length: 12103 | |
--uuid:4db29ca4-a6eb-4596-a5d4-ae0fda21c201 | |
Content-Id: <rootpart*4db29ca4-a6eb-4596-a5d4-ae0fda21c201@example.jaxws.sun.com> | |
Content-Type: application/xop+xml;charset=utf-8;type="text/xml" | |
Content-Transfer-Encoding: binary | |
<?xml version="1.0" ?> | |
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> | |
<S:Body><ns2:createProfile xmlns:ns2="http://service.profile.com/"> | |
<arg0> | |
<address>Address Lines....</address> | |
<displayPhoto> | |
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:a167bf8a-4a9f-4fc7-9f45-bb7c5bf93ed3@example.jaxws.sun.com"></xop:Include> | |
</displayPhoto> | |
<name>Test User</name> | |
</arg0> | |
</ns2:createProfile> | |
</S:Body> | |
</S:Envelope> | |
--uuid:4db29ca4-a6eb-4596-a5d4-ae0fda21c201 | |
Content-Id: <a167bf8a-4a9f-4fc7-9f45-bb7c5bf93ed3@example.jaxws.sun.com> | |
Content-Type: application/octet-stream | |
Content-Transfer-Encoding: binary | |
<Binary Content of PNG File> | |
-------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---[HTTP response 200]--- | |
Date: Sat, 23 Sep 2017 09:45:01 GMT | |
Transfer-encoding: chunked | |
Content-type: multipart/related;start="<rootpart*663ae683-7cff-4a47-9fe3-ddbcb4bbb96b@example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:663ae683-7cff-4a47-9fe3-ddbcb4bbb96b";start-info="text/xml" | |
--uuid:663ae683-7cff-4a47-9fe3-ddbcb4bbb96b | |
Content-Id: <rootpart*663ae683-7cff-4a47-9fe3-ddbcb4bbb96b@example.jaxws.sun.com> | |
Content-Type: application/xop+xml;charset=utf-8;type="text/xml" | |
Content-Transfer-Encoding: binary | |
<?xml version="1.0" ?> | |
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> | |
<S:Body><ns2:createProfileResponse xmlns:ns2="http://service.profile.com/"> | |
<return>Test User Created.</return> | |
</ns2:createProfileResponse> | |
</S:Body> | |
</S:Envelope> | |
--uuid:663ae683-7cff-4a47-9fe3-ddbcb4bbb96b---------------------- |
Get Profile Request/Response:-
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---[HTTP request]--- | |
Accept: text/xml, multipart/related | |
Connection: keep-alive | |
Host: localhost:8080 | |
User-agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e | |
Content-type: multipart/related;start="<rootpart*527f0b86-5670-4318-b7b1-3dc2996d39fb@example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:527f0b86-5670-4318-b7b1-3dc2996d39fb";start-info="text/xml" | |
Soapaction: "http://service.profile.com/ProfileService/getProfileRequest" | |
Content-length: 488 | |
--uuid:527f0b86-5670-4318-b7b1-3dc2996d39fb | |
Content-Id: <rootpart*527f0b86-5670-4318-b7b1-3dc2996d39fb@example.jaxws.sun.com> | |
Content-Type: application/xop+xml;charset=utf-8;type="text/xml" | |
Content-Transfer-Encoding: binary | |
<?xml version="1.0" ?> | |
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> | |
<S:Body> | |
<ns2:getProfile xmlns:ns2="http://service.profile.com/"> | |
<arg0>Test User</arg0> | |
</ns2:getProfile> | |
</S:Body> | |
</S:Envelope> | |
--uuid:527f0b86-5670-4318-b7b1-3dc2996d39fb---------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---[HTTP response 200]--- | |
Date: Sat, 23 Sep 2017 09:45:01 GMT | |
Transfer-encoding: chunked | |
Content-type: multipart/related;start="<rootpart*e760379b-7bc8-4673-bea9-3bb94e2423db@example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:e760379b-7bc8-4673-bea9-3bb94e2423db";start-info="text/xml" | |
--uuid:e760379b-7bc8-4673-bea9-3bb94e2423db | |
Content-Id: <rootpart*e760379b-7bc8-4673-bea9-3bb94e2423db@example.jaxws.sun.com> | |
Content-Type: application/xop+xml;charset=utf-8;type="text/xml" | |
Content-Transfer-Encoding: binary | |
<?xml version="1.0" ?> | |
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> | |
<S:Body><ns2:getProfileResponse xmlns:ns2="http://service.profile.com/"> | |
<return> | |
<address>Address Lines....</address> | |
<displayPhoto> | |
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:f9e7325e-98e6-440c-9d33-abe2f2ea7e90@example.jaxws.sun.com"></xop:Include> | |
</displayPhoto> | |
<name>Test User</name> | |
</return> | |
</ns2:getProfileResponse> | |
</S:Body> | |
</S:Envelope> | |
--uuid:e760379b-7bc8-4673-bea9-3bb94e2423db | |
Content-Id: <f9e7325e-98e6-440c-9d33-abe2f2ea7e90@example.jaxws.sun.com> | |
Content-Type: image/png | |
Content-Transfer-Encoding: binary | |
<Binary Content Of PNG> | |
-------------------- |
Comments
Post a Comment