├── .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 |
--------------------------------------------------------------------------------