Sending attachments to web services

In addition to sending and accepting the data types discussed in the previous sections, web service methods can send and accept file attachments. The following example illustrates how to do this:

package net.ensode.javaeebook.jaxws; 
 
import java.io.FileOutputStream; 
import java.io.IOException; 
 
import javax.activation.DataHandler; 
import javax.jws.WebMethod; 
import javax.jws.WebService; 
 
@WebService 
public class FileAttachment { 
 
    @WebMethod 
    public void attachFile(DataHandler dataHandler) { 
        FileOutputStream fileOutputStream; 
        try { 
            fileOutputStream = 
new FileOutputStream("/tmp/logo.png");
dataHandler.writeTo(fileOutputStream);
fileOutputStream.flush(); fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }

In order to write a web service method that receives one or more attachments, all we need to do is add a parameter of type javax.activation.DataHandler for each attachment the method will receive. In the preceding example, the attachFile() method takes a single parameter of this type and simply writes it to the filesystem.

At this point, we need to package our code in a WAR file and deploy it as usual. Once deployed, a WSDL will automatically be generated. We then need to execute the wsimport utility to generate code that our web service client can use to access the web service. As previously discussed, the wsimport can be invoked directly from the command line or via an Apache Maven plugin.

Once we have executed wsimport to generate code to access the web service, we can write and compile our client code:

package net.ensode.javaee8book.fileattachmentserviceclient; 
 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.URL; 
import javax.enterprise.context.RequestScoped; 
import javax.inject.Named; 
import javax.xml.ws.WebServiceRef; 
import net.ensode.javaeebook.jaxws.FileAttachment; 
import net.ensode.javaeebook.jaxws.FileAttachmentService; 
 
@Named 
@RequestScoped 
public class FileAttachmentServiceClientController { 
 
    @WebServiceRef(wsdlLocation = "http://localhost:8080/fileattachmentservice/" 
            + "FileAttachmentService?wsdl") 
    private FileAttachmentService fileAttachmentService; 
 
    public void invokeWebService() { 
        try { 
            URL attachmentUrl = new URL( 
        "http://localhost:8080/fileattachmentserviceclient/resources/img/logo.png"); 
 
            FileAttachment fileAttachment = fileAttachmentService. 
                    getFileAttachmentPort(); 
 
            InputStream inputStream = attachmentUrl.openStream(); 
 
            byte[] fileBytes = inputStreamToByteArray(inputStream);            
fileAttachment.attachFile(fileBytes);
} catch (IOException ioe) { ioe.printStackTrace(); } } private byte[] inputStreamToByteArray(InputStream inputStream) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int bytesRead = 0; while ((bytesRead = inputStream.read(buffer, 0, buffer.length)) != -1) { byteArrayOutputStream.write(buffer, 0, bytesRead); } byteArrayOutputStream.flush(); return byteArrayOutputStream.toByteArray(); } }

Web service attachments need to be sent as a byte array to the web service, therefore, web service clients need to convert the file to attach to this type. In our example, we send an image as an attachment, we load the image into memory by creating an instance of java.net.URL, passing the URL of the image in question as a parameter to its constructor. We then obtain an InputStream instance corresponding to the image by invoking the openStream() method on our URL instance, convert our InputStream instance to a byte array, then pass this byte array to the web service method that expects an attachment.

Notice that, unlike when passing standard parameters, the parameter type used when the client invokes a method expecting an attachment is different from the parameter type of the method in the web server code. The method in the web server code expects an instance of javax.activation.DataHandler for each attachment; however, the code generated by wsimport expects an array of bytes for each attachment. These arrays of bytes are converted to the right type ( javax.activation.DataHandler ) behind the scenes by the wsimport generated code. As application developers, we don't need to concern ourselves with the details of why this happens; we just need to keep in mind that, when sending attachments to a web service method, parameter types will be different in the web service code and in the client invocation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.3.175