├── .gitignore ├── LICENSE ├── README.md ├── nb-configuration.xml ├── pom.xml └── src ├── main ├── java │ └── hu │ │ └── vanio │ │ └── spring │ │ └── boot │ │ └── integration │ │ ├── ContentRepository.java │ │ ├── ContentRepositoryImpl.java │ │ ├── ContentStoreService.java │ │ ├── ContentStoreServiceImpl.java │ │ ├── ExampleIntegrationApplication.java │ │ └── client │ │ └── JaxWsClient.java └── resources │ ├── contentStore.wsdl │ ├── cxf-servlet.xml │ ├── integration-context.xml │ ├── logback.xml │ └── spring-ws-logo.png └── test └── java └── hu └── vanio └── spring └── boot └── integration └── tests └── SampleIntegrationApplicationTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | /target/ 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Vanio Informatika 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Spring-integration project with CXF WebService endpoint botstrapped with Spring-boot 2 | ==================================================================================== 3 | 4 | Spring-boot project with Spring-integration and CXF WebService MTOM aware endpoint handling large attachements. 5 | 6 | To try out: 7 | ----------- 8 | 9 | 1. check out the project from GitHub 10 | 1. install JDK 1.8+ (Java8) 11 | 1. install Maven 3.0.3+ 12 | 1. set JAVA_HOME environment variable to home of the installed JDK 1.8 13 | 1. go to the project directory and issue mvn clean spring-boot:run 14 | 1. open a browser and enter the following address: http://localhost:8080/services/contentStoreCxf?wsdl 15 | 1. use the WSDL to create a client of your preference 16 | 17 | -------------------------------------------------------------------------------- /nb-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 16 | JDK_1.8 17 | 18 | 19 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | hu.vanio.spring.boot 8 | spring-boot-cxf-integration-example 9 | 1.0.0-SNAPSHOT 10 | jar 11 | 12 | 13 | 1.6 14 | UTF-8 15 | UTF-8 16 | 1.0.2.RELEASE 17 | 4.0.1.RELEASE 18 | 2.7.5 19 | 1.8 20 | 1.8 21 | 22 | 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web 27 | ${spring-boot.version} 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-actuator 32 | ${spring-boot.version} 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-integration 37 | ${spring-boot.version} 38 | 39 | 40 | 41 | org.springframework.integration 42 | spring-integration-xml 43 | ${spring.integration.version} 44 | 45 | 46 | org.springframework 47 | spring-messaging 48 | 4.0.4.RELEASE 49 | 50 | 51 | org.apache.cxf 52 | cxf-rt-frontend-jaxws 53 | ${cxf.version} 54 | 55 | 56 | org.apache.cxf 57 | cxf-rt-transports-http 58 | ${cxf.version} 59 | 60 | 61 | 62 | 63 | org.springframework.boot 64 | spring-boot-starter-test 65 | ${spring-boot.version} 66 | test 67 | 68 | 69 | junit 70 | junit 71 | 4.11 72 | test 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | maven-war-plugin 82 | 2.4 83 | 84 | false 85 | 86 | 87 | 88 | 89 | org.codehaus.mojo 90 | jaxws-maven-plugin 91 | 1.12 92 | 93 | 94 | 95 | wsimport 96 | 97 | 98 | ${basedir}/src/main/resources 99 | 100 | contentStore.wsdl 101 | 102 | hu.vanio.springwsmtom.wstypes 103 | ${project.build.directory}/generated-sources/wsimport 104 | 105 | 106 | 107 | 108 | 109 | 110 | maven-surefire-plugin 111 | 2.16 112 | 113 | 114 | 115 | org.springframework.boot 116 | spring-boot-maven-plugin 117 | ${spring-boot.version} 118 | 119 | 120 | 121 | repackage 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | spring-milestones 132 | Spring Milestones 133 | http://repo.spring.io/milestone 134 | 135 | false 136 | 137 | 138 | 139 | spring-releases 140 | Spring Releases 141 | http://repo.spring.io/release 142 | 143 | false 144 | 145 | 146 | 147 | 148 | 149 | spring-milestones 150 | Spring Milestones 151 | http://repo.spring.io/milestone 152 | 153 | false 154 | 155 | 156 | 157 | spring-releases 158 | Spring Releases 159 | http://repo.spring.io/release 160 | 161 | false 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /src/main/java/hu/vanio/spring/boot/integration/ContentRepository.java: -------------------------------------------------------------------------------- 1 | package hu.vanio.spring.boot.integration; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import javax.activation.DataHandler; 7 | 8 | /** 9 | * Content repository interface 10 | * 11 | * @author Gyula Szalai 12 | */ 13 | public interface ContentRepository { 14 | 15 | /** 16 | * Loads the specified content 17 | * @param name The name of the content 18 | * @return A file that stores the content 19 | */ 20 | File loadContent(String name); 21 | 22 | /** 23 | * Stores the specified content 24 | * @param name The name of the content 25 | * @param content The content 26 | * @throws java.io.IOException If an error occurs during storing the content 27 | */ 28 | void storeContent(String name, DataHandler content) throws IOException; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/hu/vanio/spring/boot/integration/ContentRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package hu.vanio.spring.boot.integration; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.OutputStream; 8 | 9 | import javax.activation.DataHandler; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.springframework.stereotype.Component; 16 | 17 | /** 18 | * Content repository implementation 19 | * 20 | * @author Gyula Szalai 21 | */ 22 | @Component("contentRepository") 23 | public class ContentRepositoryImpl implements ContentRepository{ 24 | 25 | /** Logger */ 26 | final static Logger logger = LoggerFactory.getLogger(ContentRepositoryImpl.class); 27 | 28 | /** Path to the filestore */ 29 | @Value(value = "#{ systemProperties['java.io.tmpdir'] }") 30 | private String fileStorePath; 31 | 32 | @Override 33 | public File loadContent(String name) { 34 | return new File(this.fileStorePath, name + ".tmp"); 35 | } 36 | 37 | @Override 38 | public void storeContent(String name, DataHandler content) throws IOException { 39 | File outFile = new File(this.fileStorePath, name + ".tmp"); 40 | logger.info("Storing content in file: {}", outFile.getAbsolutePath()); 41 | InputStream dhis = content.getInputStream(); 42 | logger.info("******************************************** dhis: {}", dhis.getClass().getName()); 43 | int i = 0; 44 | byte[] buffer = new byte[1024]; 45 | try (InputStream is = content.getInputStream()) { 46 | try (OutputStream outStream = new FileOutputStream(outFile)) { 47 | while ((i = is.read(buffer, 0, buffer.length)) > 0) { 48 | outStream.write(buffer, 0, i); 49 | } 50 | } 51 | } 52 | logger.info("Content stored."); 53 | 54 | } 55 | 56 | /** 57 | * Path to the filestore 58 | * @return the fileStorePath 59 | */ 60 | public String getFileStorePath() { 61 | return fileStorePath; 62 | } 63 | 64 | /** 65 | * Path to the filestore 66 | * @param fileStorePath the fileStorePath to set 67 | */ 68 | public void setFileStorePath(String fileStorePath) { 69 | this.fileStorePath = fileStorePath; 70 | } 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/hu/vanio/spring/boot/integration/ContentStoreService.java: -------------------------------------------------------------------------------- 1 | package hu.vanio.spring.boot.integration; 2 | 3 | import hu.vanio.springwsmtom.wstypes.LoadContentRequest; 4 | import hu.vanio.springwsmtom.wstypes.LoadContentResponse; 5 | import hu.vanio.springwsmtom.wstypes.StoreContentRequest; 6 | import hu.vanio.springwsmtom.wstypes.StoreContentResponse; 7 | 8 | /** 9 | * ContentStore service interface. 10 | * 11 | * @author Gyula Szalai 12 | */ 13 | public interface ContentStoreService { 14 | 15 | /** 16 | * Handles the specified request. Entry point for service activator. 17 | * @param request The request to be handled 18 | * @return The response 19 | */ 20 | public Object handle(Object request); 21 | 22 | /** 23 | * Handles the specified StoreContentRequest 24 | * @param storeContentRequest The request 25 | * @return The StoreContentResponse 26 | */ 27 | public StoreContentResponse storeContent(StoreContentRequest storeContentRequest); 28 | 29 | /** 30 | * Handles the specified LoadContentRequest 31 | * @param loadContentRequest The request 32 | * @return The LoadContentResponse 33 | */ 34 | public LoadContentResponse loadContent(LoadContentRequest loadContentRequest); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/hu/vanio/spring/boot/integration/ContentStoreServiceImpl.java: -------------------------------------------------------------------------------- 1 | package hu.vanio.spring.boot.integration; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import javax.activation.DataHandler; 7 | import javax.activation.FileDataSource; 8 | 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.messaging.MessagingException; 14 | import org.springframework.stereotype.Component; 15 | 16 | import hu.vanio.springwsmtom.wstypes.LoadContentRequest; 17 | import hu.vanio.springwsmtom.wstypes.LoadContentResponse; 18 | import hu.vanio.springwsmtom.wstypes.ObjectFactory; 19 | import hu.vanio.springwsmtom.wstypes.StoreContentRequest; 20 | import hu.vanio.springwsmtom.wstypes.StoreContentResponse; 21 | 22 | /** 23 | * ContentStore service implementation 24 | * 25 | * @author Gyula Szalai 26 | */ 27 | @Component("contentStoreService") 28 | public class ContentStoreServiceImpl implements ContentStoreService { 29 | 30 | /** logger */ 31 | private final Logger logger = LoggerFactory.getLogger(ContentStoreServiceImpl.class); 32 | 33 | @Autowired 34 | private ContentRepository contentRepository; 35 | 36 | @Override 37 | public Object handle(Object request) { 38 | logger.debug("Handling request of type: {}", request.getClass().getName()); 39 | if (request instanceof StoreContentRequest) { 40 | return storeContent((StoreContentRequest)request); 41 | } else if (request instanceof LoadContentRequest) { 42 | return loadContent((LoadContentRequest)request); 43 | } else { 44 | logger.debug("Unhandled request type: {}", request.getClass().getName()); 45 | throw new MessagingException("Unhandled request type: " + request.getClass().getName()); 46 | } 47 | } 48 | 49 | @Override 50 | public LoadContentResponse loadContent(LoadContentRequest request) { 51 | logger.debug("LoadContentResponse received, name: {}", request.getName()); 52 | LoadContentResponse resp = new ObjectFactory().createLoadContentResponse(); 53 | File content = this.contentRepository.loadContent(request.getName()); 54 | logger.debug("Content found interface repository: {}", content.getAbsolutePath()); 55 | resp.setContent(new DataHandler(new FileDataSource(content))); 56 | logger.debug("Content put into response"); 57 | return resp; 58 | } 59 | 60 | @Override 61 | public StoreContentResponse storeContent(StoreContentRequest request) { 62 | logger.debug("StoreContentResponse received, name: {}", request.getName()); 63 | try { 64 | this.contentRepository.storeContent(request.getName(), request.getContent()); 65 | } catch (IOException ex) { 66 | throw new MessagingException("Storing content failed", ex); 67 | } 68 | StoreContentResponse resp = new ObjectFactory().createStoreContentResponse(); 69 | resp.setMessage("Content successfully stored"); 70 | logger.debug("StoreContentResponse constructed!"); 71 | return resp; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/hu/vanio/spring/boot/integration/ExampleIntegrationApplication.java: -------------------------------------------------------------------------------- 1 | package hu.vanio.spring.boot.integration; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.boot.context.embedded.ServletRegistrationBean; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.ComponentScan; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.annotation.ImportResource; 10 | 11 | @Configuration 12 | @EnableAutoConfiguration 13 | @ComponentScan 14 | @ImportResource({ "/integration-context.xml", "/cxf-servlet.xml" }) 15 | public class ExampleIntegrationApplication { 16 | 17 | public static void main(String[] args) throws Exception { 18 | SpringApplication.run(ExampleIntegrationApplication.class, args); 19 | } 20 | 21 | @Bean 22 | public ServletRegistrationBean cxfServlet() { 23 | org.apache.cxf.transport.servlet.CXFServlet cxfServlet = new org.apache.cxf.transport.servlet.CXFServlet(); 24 | ServletRegistrationBean servletDef = new ServletRegistrationBean(cxfServlet, "/services/*"); 25 | servletDef.setLoadOnStartup(1); 26 | return servletDef; 27 | } 28 | 29 | // @Bean 30 | // public WsdlDefinition contentStore() { 31 | // return new SimpleWsdl11Definition(new ClassPathResource("/contentStore.wsdl")); 32 | // } 33 | 34 | // @Bean 35 | // public Object marshaller() { 36 | // Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 37 | // marshaller.setMtomEnabled(true); 38 | // marshaller.setContextPath("hu.vanio.springwsmtom.wstypes"); 39 | // return marshaller; 40 | // } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/hu/vanio/spring/boot/integration/client/JaxWsClient.java: -------------------------------------------------------------------------------- 1 | package hu.vanio.spring.boot.integration.client; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.activation.DataHandler; 6 | import javax.xml.ws.BindingProvider; 7 | import javax.xml.ws.soap.SOAPBinding; 8 | 9 | import hu.vanio.springwsmtom.wstypes.ContentStoreHttpPort; 10 | import hu.vanio.springwsmtom.wstypes.ContentStoreHttpPortService; 11 | import hu.vanio.springwsmtom.wstypes.LoadContentRequest; 12 | import hu.vanio.springwsmtom.wstypes.LoadContentResponse; 13 | import hu.vanio.springwsmtom.wstypes.ObjectFactory; 14 | import hu.vanio.springwsmtom.wstypes.StoreContentRequest; 15 | import hu.vanio.springwsmtom.wstypes.StoreContentResponse; 16 | 17 | /** 18 | * Simple JAX-WS MTOM enabled client 19 | * 20 | * @author Gyula Szalai 21 | */ 22 | public class JaxWsClient { 23 | 24 | /** JAXB object factory */ 25 | private final ObjectFactory objectFactory = new ObjectFactory(); 26 | 27 | /** 28 | * Sends the specified content file to the WebService 29 | * 30 | * @param name The name of the content to be stored 31 | * @param content The content to be stored 32 | * @return The message that tthe server sent back 33 | */ 34 | public String storeContent(String name, DataHandler content) throws Exception { 35 | ContentStoreHttpPortService contentStoreService = new ContentStoreHttpPortService(); 36 | ContentStoreHttpPort contentStorePort = contentStoreService.getContentStoreHttpPortSoap11(); 37 | SOAPBinding binding = (SOAPBinding) ((BindingProvider) contentStorePort).getBinding(); 38 | binding.setMTOMEnabled(true); 39 | 40 | StoreContentRequest request = objectFactory.createStoreContentRequest(); 41 | request.setName(name); 42 | request.setContent(content); 43 | 44 | StoreContentResponse response = contentStorePort.storeContent(request); 45 | return response.getMessage(); 46 | } 47 | 48 | /** 49 | * Loads the content with the specified name from the WebService 50 | * 51 | * @param name The name of the content 52 | * @return The loaded content 53 | * @throws IOException If an IO error occurs 54 | */ 55 | public DataHandler loadContent(String name) throws IOException { 56 | ContentStoreHttpPortService service = new ContentStoreHttpPortService(); 57 | ContentStoreHttpPort loadContentPort = service.getContentStoreHttpPortSoap11(); 58 | SOAPBinding binding = (SOAPBinding) ((BindingProvider) loadContentPort).getBinding(); 59 | binding.setMTOMEnabled(true); 60 | 61 | LoadContentRequest request = objectFactory.createLoadContentRequest(); 62 | request.setName(name); 63 | LoadContentResponse response = loadContentPort.loadContent(request); 64 | DataHandler content = response.getContent(); 65 | return content; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/resources/contentStore.wsdl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/main/resources/cxf-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/resources/integration-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ${LOG_PATTERN} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/resources/spring-ws-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanioinformatika/spring-boot-cxf-integration-example/f7a3abc3eb993c95dc93c7967c7386338f89fa1f/src/main/resources/spring-ws-logo.png -------------------------------------------------------------------------------- /src/test/java/hu/vanio/spring/boot/integration/tests/SampleIntegrationApplicationTest.java: -------------------------------------------------------------------------------- 1 | package hu.vanio.spring.boot.integration.tests; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.OutputStream; 8 | import java.net.URL; 9 | 10 | import javax.activation.DataHandler; 11 | import javax.activation.FileDataSource; 12 | import javax.activation.URLDataSource; 13 | 14 | import org.junit.AfterClass; 15 | import static org.junit.Assert.assertEquals; 16 | import static org.junit.Assert.assertNotNull; 17 | import static org.junit.Assert.assertTrue; 18 | import org.junit.BeforeClass; 19 | import org.junit.Test; 20 | 21 | import org.springframework.boot.SpringApplication; 22 | import org.springframework.context.ConfigurableApplicationContext; 23 | 24 | import hu.vanio.spring.boot.integration.ExampleIntegrationApplication; 25 | import hu.vanio.spring.boot.integration.client.JaxWsClient; 26 | 27 | /** 28 | * Integration test 29 | * 30 | * @author Gyula Szalai 31 | */ 32 | public class SampleIntegrationApplicationTest { 33 | 34 | /** Spring context */ 35 | private static ConfigurableApplicationContext context; 36 | 37 | /** Webservice client */ 38 | private final static JaxWsClient client = new JaxWsClient(); 39 | 40 | /** Test content URL */ 41 | static public final URL TEST_CONTENT_URL = Thread.currentThread().getContextClassLoader().getResource("spring-ws-logo.png"); 42 | 43 | @BeforeClass 44 | public static void start() throws Exception { 45 | context = SpringApplication.run(ExampleIntegrationApplication.class); 46 | } 47 | 48 | @AfterClass 49 | public static void stop() { 50 | if (context != null) { 51 | context.close(); 52 | } 53 | } 54 | 55 | @Test 56 | public void test() throws Exception { 57 | String message = client.storeContent("test", new DataHandler(new URLDataSource(TEST_CONTENT_URL))); 58 | System.out.println("Server message: " + message); 59 | assertEquals("Content successfully stored", message); 60 | 61 | DataHandler dh = client.loadContent("test"); 62 | assertNotNull(dh); 63 | File tempFile = new File(System.getProperty("java.io.tmpdir"), "spring_mtom_jaxws_tmp.bin"); 64 | tempFile.deleteOnExit(); 65 | long size = saveContentToFile(dh, tempFile); 66 | assertTrue(size > 0); 67 | assertTrue(tempFile.length()>0); 68 | } 69 | 70 | /** 71 | * Saves the specified content to the specified file 72 | * 73 | * @param content The content 74 | * @param outFile The output file 75 | * @throws IOException If an error occurs during saving 76 | */ 77 | static public long saveContentToFile(DataHandler content, File outFile) throws IOException { 78 | long size = 0; 79 | byte[] buffer = new byte[1024]; 80 | try (InputStream is = content.getInputStream()) { 81 | try (OutputStream outStream = new FileOutputStream(outFile)) { 82 | for (int readBytes; (readBytes = is.read(buffer, 0, buffer.length)) > 0;) { 83 | size += readBytes; 84 | outStream.write(buffer, 0, readBytes); 85 | } 86 | } 87 | } 88 | return size; 89 | } 90 | } 91 | --------------------------------------------------------------------------------