첨부파일을 JAX-WS 에서는 어떻게 넘길가가 궁금해서 한번 도전해보았습니다.
무모한 도전의 결과는 무한삽질의 반복이...
여튼 어느정도 성공을 한 듯 합니다. ㅋㅋㅋㅋ
ㅁ Server Side
kr/co/vicki/webservices/conf/uploadWebservicesContext.xml
01 | <? xml version = "1.0" encoding = "UTF-8" ?> |
07 | < bean class = "org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter" > |
11 | < bean id = "uploadWebService" class = "kr.co.vicki.webservices.webservice.UploadWebService" /> |
WEB-INF/web.xml
04 | < param-name >contextConfigLocation</ param-name > |
07 | classpath:kr/co/vicki/webservices/conf/uploadWebservicesContext.xml |
12 | < listener-class >org.springframework.web.context.ContextLoaderListener</ listener-class > |
kr.co.vicki.webservices.webservice.UploadWebService.java
01 | import java.io.BufferedInputStream; |
03 | import java.io.FileOutputStream; |
04 | import java.io.IOException; |
05 | import java.io.InputStream; |
07 | import javax.activation.DataHandler; |
08 | import javax.jws.WebParam; |
09 | import javax.jws.WebService; |
10 | import javax.jws.soap.SOAPBinding; |
11 | import javax.xml.bind.annotation.XmlMimeType; |
12 | import javax.xml.ws.soap.MTOM; |
16 | @SOAPBinding (style = SOAPBinding.Style.RPC) |
17 | public class UploadWebService { |
19 | public void fileUpload( |
20 | @WebParam (name= "filename" ) String filename, |
21 | @XmlMimeType ( "application/octet-stream" ) DataHandler handler) { |
24 | inputStreamToFile(filename, handler.getInputStream()); |
25 | } catch (IOException e) { |
35 | private void inputStreamToFile(String filename, InputStream is) { |
- @MTOM: binary attachment 전송을 위한 어노테이션
- @SOAPBinding(style = SOAPBinding.Style.RPC)... 이건 무슨 말인지 모르겠습니다.
아래와 같은 설명이 어딘가에 있더라구요... 해석이 딸리므로... 읽으시는 분께 맡기겠습니다.
그러나 해당 어노테이션이 정의되어 있지 않으면 클라이언트쪽에서 제너레이션 된 메소드의 파라미터가
byte[] 이 아닌 DataHandler 가 되므로 일단 어노테이션을 위와 같이 설정합니다.
No, this is specified by the SOAPBinding annotation on the service class. Notice this in the original post above:
@SOAPBinding(style = SOAPBinding.Style.RPC)
This is telling wsgen that this is an rpc/literal service. A document/literal (doc/lit) service is specified thusly:
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
Actually, things are a little more complicated. This is actually specifying a doc/lit/wrapped service, meaning that the SOAP message body can contain multiple parameters. By contrast, in a doc/lit/bare service, the SOAP message body can contain only one parameter. For all the gory details, see the Annotations section of the JAX-WS User's Guide.
ㅁ Client Side
kr/co/vicki/client/conf/webservicesContext.xml
01 | <? xml version = "1.0" encoding = "UTF-8" ?> |
07 | < bean class = "org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter" > |
11 | < bean id = "uploadWebService" class = "kr.co.vicki.webservices.webservice.UploadWebService" /> |
kr/co/vicki/client/Client.java
01 | import java.io.ByteArrayOutputStream; |
03 | import java.io.FileInputStream; |
04 | import java.io.IOException; |
05 | import java.io.InputStream; |
07 | import kr.co.vicki.webservices.webservice.UploadWebService; |
09 | import org.springframework.beans.factory.BeanFactory; |
10 | import org.springframework.context.support.ClassPathXmlApplicationContext; |
14 | private UploadWebService uploadWebService; |
16 | public void setUploadWebService(UploadWebService uploadWebService) { |
17 | this .uploadWebService = uploadWebService; |
20 | public void fildUpload(File file) { |
21 | uploadWebService.fileUpload(file.getName(), readFromFile(file)); |
24 | public static void main(String[] args) { |
25 | BeanFactory factory = new ClassPathXmlApplicationContext( |
26 | "kr/co/vicki/client/conf/webservicesContext.xml" ); |
28 | Client client = (Client) factory.getBean( "client" ); |
29 | client.fildUpload( new File( "C:\\notice2.html" )); |
33 | * 파일의 내용을 byte 배열로 반환합니다. |
37 | private static byte [] readFromFile(File file) { |
서버의
public void fileUpload(String filename, DataHandler handler) 메소드는
클라이언트에서
public void fileUpload(String filename, byte[] arg1) 로 제너레이션 됩니다.
파일을 byte[] 로 변환하여 파일명과 함께 넘겨주게 되면 서버쪽에서 inputStream 으로 접근이 가능하게 됩니다.
첨부파일을 7KB와 4MB, 20MB 로 테스트 해본결과 20MB 는 힙 메모리 부족이라는 익센션을 날려주었습니다.
JAX-WS User Guide를 보면 용량 제한하는 어노테이션도 보이던데 테스트는 해보지 못했습니다.
이걸 해보며서 알게된 사항은 org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter 이놈은 한 컨텍스트에
한개의 웹서비스를 Export 해주는 것 같습니다. 크흑..
웹서비스는 재밌습니다?
[참고자료]
JAX-WS User Guide
- https://jax-ws.dev.java.net/guide/Large_Attachments.html
- https://jax-ws.dev.java.net/guide/Binary_Attachments.html
- https://jax-ws.dev.java.net/guide/Creating_a_MTOM_Web_Service.html
java.net Forums
-
http://forums.java.net/jive/thread.jspa?threadID=25614