Trong bài này chúng ta sẽ cùng tìm hiểu cách sử dụng Message Transmission Optimization Mechanism (MTOM) và XML-Binary Optimized Packaging (XOP) để upload file lên Server và download file từ Server về Client.
Tạo WebService Server
DocumentService.java
package com.gpcoder.ws.document; import javax.activation.DataHandler; import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; @WebService @SOAPBinding(style = Style.RPC) public interface DocumentService { @WebMethod DataHandler download(String name); @WebMethod String upload(DataHandler data); }
DocumentServiceImpl.java
package com.gpcoder.ws.document; import javax.activation.DataHandler; import javax.jws.WebService; import javax.xml.ws.WebServiceException; import javax.xml.ws.soap.MTOM; @MTOM @WebService(endpointInterface = "com.gpcoder.ws.document.DocumentService") public class DocumentServiceImpl implements DocumentService { public static final String UPLOADED_FOLDER = "data/upload/"; @Override public DataHandler download(String name) { return DocumentUtils.getFileAsDataHandler("data/" + name); } @Override public String upload(DataHandler dataHandler) { if (dataHandler != null) { String fileName = UPLOADED_FOLDER + "upload-" + System.currentTimeMillis() + ".docx"; DocumentUtils.storeDataToFile(dataHandler, fileName); return "Uploaded Successful with name " + fileName; } throw new WebServiceException("Upload Failed!"); } }
Trong phần cài đặt trên, tôi sử dụng:
Sử dụng @MTOM : để enable sử dụng MTOM cho Web service.
DataHandler để có thể nhận được nhiều loại source, format từ Client gửi lên và tối ưu hơn về performance.
Lớp tiện ích hỗ trợ đọc/ ghi file từ DataHandler:
DocumentUtils.java
package com.gpcoder.ws.document; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import javax.activation.DataHandler; import javax.activation.FileDataSource; public class DocumentUtils { private DocumentUtils() { super(); } public static void storeDataToFile(DataHandler dataHandler, String fileName) { try { File file = new File(fileName); OutputStream os = new FileOutputStream(file); dataHandler.writeTo(os); os.flush(); os.close(); } catch (Exception e) { e.printStackTrace(); } } public static DataHandler getFileAsDataHandler(String fileName) { FileDataSource dataSource = new FileDataSource(fileName); return new DataHandler(dataSource); } }
DocumentPublisher.java
package com.gpcoder.ws.document; import javax.xml.ws.Endpoint; public class DocumentPublisher { public static final String WS_URL = "http://localhost:8080/ws/document"; public static void main(String[] args) { Endpoint.publish(WS_URL, new DocumentServiceImpl()); System.out.println("Server is published!"); } }
Chạy chương trình DocumentPublisher.
Tạo Client truy cập WS
Chúng ta cần chuẩn bị một số resource để hỗ trợ upload/ download file theo cấu trúc thư mục sau:
Ứng dụng Client, truy xuất WS upload file
DocumentClientDownload.java
package com.gpcoder.ws.document; import java.net.URL; import javax.activation.DataHandler; import javax.xml.namespace.QName; import javax.xml.ws.BindingProvider; import javax.xml.ws.Service; import javax.xml.ws.soap.SOAPBinding; public class DocumentClientUpload { public static void main(String[] args) throws Exception { // Create URL of .wsdl file URL url = new URL(DocumentPublisher.WS_URL + "?wsdl"); // Create a QName using targetNamespace and name QName qname = new QName("http://document.ws.gpcoder.com/", "DocumentServiceImplService"); // Creates a Service instance with the specified WSDL document location and // service qualified name Service service = Service.create(url, qname); // We need to pass interface and model beans to client DocumentService imageServer = service.getPort(DocumentService.class); // Enable MTOM in client BindingProvider bp = (BindingProvider) imageServer; SOAPBinding binding = (SOAPBinding) bp.getBinding(); binding.setMTOMEnabled(true); // Prepare document for upload DataHandler dataHandler = DocumentUtils.getFileAsDataHandler("data/test.docx"); // Perform upload document String status = imageServer.upload(dataHandler); System.out.println("upload() : " + status); } }
Chạy chương trình trên, chúng ta có kết quả như sau:
upload() : Uploaded Successful with name data/upload/upload-1559229879163.docx
Ứng dụng Client, truy xuất WS download file
package com.gpcoder.ws.document; import java.net.URL; import javax.activation.DataHandler; import javax.xml.namespace.QName; import javax.xml.ws.Service; public class DocumentClientDownload { public static final String DOWNLOADED_FOLDER = "data/download/"; public static void main(String[] args) throws Exception { // Create URL of .wsdl file URL url = new URL(DocumentPublisher.WS_URL + "?wsdl"); // Create a QName using targetNamespace and name QName qname = new QName("http://document.ws.gpcoder.com/", "DocumentServiceImplService"); // Creates a Service instance with the specified WSDL document location and // service qualified name Service service = Service.create(url, qname); // We need to pass interface and model beans to client DocumentService imageServer = service.getPort(DocumentService.class); // Perform download document DataHandler dataHandler = imageServer.download("test.docx"); // Save the result to file String fileName = DOWNLOADED_FOLDER + "dowload-" + System.currentTimeMillis() + ".docx"; DocumentUtils.storeDataToFile(dataHandler, fileName); System.out.println("download() : Downloaded Successful with name " + fileName); } }
Chạy chương trình trên, chúng ta có kết quả như sau:
download() : Downloaded Successful with name data/download/dowload-1559229893344.docx