Using the JAX-WS (jdk built-in implementation) method, this time to use a complex type of Customer in the service, and to achieve the function of attachment transmission, here using the MTOM attachment transmission method. MTOM is a SOAP Message Transmission Optimization Mechanism. MTOM can send binary data in a SOAP Message.
Let's first look at the Customer class:
Package org. duke. jaxws. server;
Import java. util. Date;
Import javax. activation. DataHandler;
Import javax. xml. bind. annotation. XmlAccessType;
Import javax. xml. bind. annotation. XmlAccessorType;
Import javax. xml. bind. annotation. XmlMimeType;
Import javax. xml. bind. annotation. XmlRootElement;
@ XmlRootElement (name = "Customer ")
@ XmlAccessorType (XmlAccessType. FIELD)
Public class Customer {
Private long id;
Private String name;
Private Date birthday;
@ XmlMimeType ("application/octet-stream ")
Private DataHandler imageData;
Public long getId (){
Return id;
}
Public void setId (long id ){
This. id = id;
}
Public String getName (){
Return name;
}
Public void setName (String name ){
This. name = name;
}
Public Date getBirthday (){
Return birthday;
}
Public void setBirthday (Date birthday ){
This. birthday = birthday;
}
Public DataHandler getImageData (){
Return imageData;
}
Public void setImageData (DataHandler imageData ){
This. imageData = imageData;
}
}
The attachment to be transmitted in the MTOM mode must use javax. activation. for the DataHandler class, you must also use the @ XmlAccessorType (FIELD) Annotation on the class to indicate that JAXB only pays attention to fields when performing conversion between JAVA objects and XML, do not pay attention to the properties (getXXX () method). Otherwise, two imageData attribute errors will be reported when the Web service is published. The cause is unknown and may be a BUG.
Then, use the @ XmlMimeType annotation to mark the data of the attachment type. Here we mark imageData as a binary file. Of course, you can also use the specific MIME type, for example: image/jpg, image/gif, etc., but consider whether the client supports it.
Interface Class:
Package org. duke. jaxws. server;
Import javax. jws. WebParam;
Import javax. jws. WebService;
Import javax. jws. soap. SOAPBinding;
Import javax. xml. ws. soap. MTOM;
@ WebService (name = "Hello ")
@ SOAPBinding (style = SOAPBinding. Style. RPC)
@ MTOM
Public interface Hello {
Public void printContext ();
Public Customer selectCustomerByName (
@ WebParam (name = "customer") Customer customer );
Public Customer selectMaxAgeCustomer (Customer c1, Customer c2 );
}
@ MTOM annotation is used to enable the MTOM function.
@ The name attribute in the WebService annotation is marked on the interface class. You can specify the interface name in the wsdl, that is, the name of the Interface Class in the generated client code.
@ SOAPBinding (style = SOAPBinding. style. RPC) specifies the SOAP message style, which has two enumerated values: SOAPBinding. style. DOCUMENT (default) and SOAPBinding. style. RPC, you can compare the two methods to generate different wsdl, And the generated client code is also different.
Implementation class:
Package org. duke. jaxws. server;
Import java. io. File;
Import java. io. FileOutputStream;
Import java. io. IOException;
Import java. io. InputStream;
Import java. io. OutputStream;
Import java. text. ParseException;
Import java. text. SimpleDateFormat;
Import java. util. Date;
Import java. util. Set;
Import javax. activation. DataHandler;
Import javax. activation. FileDataSource;
Import javax. annotation. Resource;
Import javax. jws. WebService;
Import javax. xml. ws. WebServiceContext;
Import javax. xml. ws. handler. MessageContext;
@ WebService (serviceName = "Hello", portName = "HelloPort", targetNamespace = "http://server.jaxws.duke.org/", endpointInterface = "org. duke. jaxws. server. Hello ")
Public class HelloImpl implements Hello {
@ Resource
Private WebServiceContext context;
@ Override
Public void printContext (){
MessageContext ctx = context. getMessageContext ();
Set <String> set = ctx. keySet ();
For (String key: set ){
System. out. println ("{" + key + "," + ctx. get (key) + "}");
Try {
System. out. println ("key. scope =" + ctx. getScope (key ));
} Catch (Exception e ){
System. out. println (key + "is not exits ");
}
}
}
@ Override
Public Customer selectCustomerByName (Customer customer ){
If ("duke". equals (customer. getName ())){
Customer. setId (1 );
Try {
Customer. setBirthday (new SimpleDateFormat ("yyyy-MM-dd ")
. Parse ("1985-03-14 "));
} Catch (ParseException e ){
E. printStackTrace ();
}
Customer. setImageData (new DataHandler (new FileDataSource (new File (
"C:" + File. separator + "duke.jpg "))));
} Else {
Customer. setId (2 );
Customer. setBirthday (new Date ());
Customer. setImageData (new DataHandler (new FileDataSource (new File (
"C:" + File. separator + "origin.jpg "))));
}
Return customer;
}
@ Override
Public Customer selectMaxAgeCustomer (Customer c1, Customer c2 ){
Try {
// Output the received attachment
System. out. println ("c1.getImageData (). getContentType () ="
+ C1.getImageData (). getContentType ());
InputStream is = c2.getImageData (). getInputStream ();
OutputStream OS = new FileOutputStream ("c: \ temp1.jpg ");
Byte [] bytes = new byte [1, 1024];
Int c;
While (c = is. read (bytes ))! =-1 ){
OS. write (bytes, 0, c );
}
OS. close ();
System. out. println ("c2.getImageData (). getContentType () ="
+ C2.getImageData (). getContentType ());
Is = c2.getImageData (). getInputStream ();
OS = new FileOutputStream ("c :\\ temp2.jpg ");
Bytes = new byte [1024];
While (c = is. read (bytes ))! =-1 ){
OS. write (bytes, 0, c );
}
OS. close ();
} Catch (IOException e ){
E. printStackTrace ();
}
If (c1.getBirthday (). getTime ()> c2.getBirthday (). getTime ()){
Return c2;
} Else {
Return c1;
}
}
}
@ WebService the serviceName attribute of the annotation specifies the name attribute value of the service node in the wsdl. The portName attribute specifies the port node name attribute value under the service node in the wsdl. The targetNamespace attribute specifies the targetNamespace attribute value of the wsdl root node definitions. The endpointInterface attribute specifies the full path name of the WebService interface to be released. When the implementation class implements multiple interfaces, you need to use this attribute to indicate which class is the service endpoint interface (SEI) of WebService ).
In this class, a WebServiceContext object is injected with the @ Resource annotation, which is the context environment of WebService.
Publish this service:
Package org. duke. jaxws. server;
Import javax. xml. ws. Endpoint;
Public class SoapServer {
Public static void main (String [] args ){
Endpoint. publish ("http: // localhost: 8080/Service/Hello", new HelloImpl ());
}
}
Type "wsimport-s src-p org. duke. jaxws. client-keep http: // localhost: 8080/Service/Hello?" In the command line? "Wsdl" generates client code and copies it to the corresponding project folder. Then, you can call this service:
Package org. duke. jaxws. test;
Import java. io. FileOutputStream;
Import java. io. IOException;
Import java. io. InputStream;
Import java. io. OutputStream;
Import java.net. MalformedURLException;
Import java.net. URL;
Import java. text. ParseException;
Import java. text. SimpleDateFormat;
Import java. util. GregorianCalendar;
Import javax. activation. DataHandler;
Import javax. activation. DataSource;
Import javax. activation. FileDataSource;
Import javax. xml. datatype. DatatypeConfigurationException;
Import javax. xml. datatype. DatatypeFactory;
Import javax. xml. namespace. QName;
Import org. duke. jaxws. client. Customer;
Import org. duke. jaxws. client. Hello;
Import org. duke. jaxws. client. Hello_Service;
Public class SoapClient {
Public static void main (String [] args) throws ParseException,
MalformedURLException {
QName qName = new QName ("http://server.jaxws.duke.org/", "Hello ");
Hello_Service helloService = new Hello_Service (new URL (
& Quot; http: // localhost: 8080/Service/Hello? Wsdl "), qName );
Hello hello = (Hello) helloService. getPort (Hello. class );
Hello. printContext ();
System. out. println ("##################################### ###");
Customer customer = new Customer ();
Customer. setName ("duke ");
DataSource ds = hello. selectCustomerByName (customer). getImageData ()
. GetDataSource ();
String attachmentMimeType = ds. getContentType ();
System. out. println (attachmentMimeType );
Try {
InputStream is = ds. getInputStream ();
OutputStream OS = new FileOutputStream (
"C: \ Shawn \ duke-real_temp.jpg ");
Byte [] bytes = new byte [1, 1024];
Int c;
While (c = is. read (bytes ))! =-1 ){
OS. write (bytes, 0, c );
}
} Catch (IOException e ){
E. printStackTrace ();
}
System. out. println ("##################################### ###");
Customer c1 = new Customer ();
C1.setId (1 );
C1.setName ("duke ");
GregorianCalendar calendar = (GregorianCalendar) GregorianCalendar
. GetInstance ();
Calendar. setTime (new SimpleDateFormat ("yyyy-MM-dd"). parse ("1985-03-14 "));
Try {
C1.setBirthday (DatatypeFactory. newInstance ()
. NewXMLGregorianCalendar (calendar ));
} Catch (DatatypeConfigurationException e ){
E. printStackTrace ();
}
C1.setImageData (new DataHandler (new FileDataSource (
"C: \ Shawn \ duke1.jpg ")));
Customer c2 = new Customer ();
C2.setId (2 );
C2.setName ("abc ");
Calendar. setTime (new SimpleDateFormat ("yyyy-MM-dd"). parse ("1986-03-14 "));
Try {
C2.setBirthday (DatatypeFactory. newInstance ()
. NewXMLGregorianCalendar (calendar ));
} Catch (DatatypeConfigurationException e ){
E. printStackTrace ();
}
C2.setImageData (new DataHandler (new FileDataSource (
"C: \ Shawn \ duke-real_temp.jpg ")));
Customer c = hello. selectMaxAgeCustomer (c1, c2 );
System. out. println (c. getName ());
}
}
Author: silence is gold