2008. 12. 10. 14:20
Apache CXF에서 com.ctc.wstx.exc.WstxEOFException 발생 Computing에 관한 독백2008. 12. 10. 14:20
스프링과 아파치 CXF를 이용해 POJO 웹 서비스를 디자인하고 구현하기, Part 2: RESTful 웹 서비스 만들기의 예제(예제도 위 site에서 받을 수 있다) 따라 하다 된통 걸렸다... -.-
HTTP POST method로 request를 날려 Order(주문)를 하나 추가하려고 했는데 다음과 같은 알도살도 못하는 Exception이 발생하였다.
이 뭥미? 해결책을 찾을 수 있길 바라며, 일단 오류를 남긴다. 관련 오류가 Apache CXF Issue Tracker에도 있어서 좀 불길하긴 하다만...(https://issues.apache.org/jira/browse/CXF-1863)
----------- 해결 -----------
문제는 client였다. 기본 예제의 client인 Client.java는 아래와 같이 단순히 java.net.URL을 기반으로 작성되었다.
혹시나 하는 마음에 화끈하게 Apache HttpClient library를 써서 아래와 같이 다시 만들어 보았다.
이랬더니 정상적으로 동작하였다. 하기사 java.net.URL이 잘 동작했으면 Apache HttpClient가 있을 필요가 있겠어?
설마허니, 예제 code 돌려보지도 않은 것은 아니겠지? 혹시 Web site에서 배포하는 예제에서 동일한 문제를 겪으시는 분들은 위 Client.java로 다시 해 보시길...
그런데 둘 차이는 뭘까? 한 번 파보고 싶은데... 싶은데싶은데싶은데싶은데싶은데... 젠장.
HTTP POST method로 request를 날려 Order(주문)를 하나 추가하려고 했는데 다음과 같은 알도살도 못하는 Exception이 발생하였다.
2008. 12. 10 오후 1:55:57 org.apache.cxf.binding.http.interceptor.DispatchInterceptor handleMessage
정보: Invoking POST on /orders
2008. 12. 10 오후 1:55:57 org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor handleMessage
정보: URIParameterInterceptor handle message on path [/orders] with content-type [application/x-www-form-urlencoded]
2008. 12. 10 오후 1:55:57 org.apache.cxf.phase.PhaseInterceptorChain doIntercept
정보: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Unexpected EOF in prolog
at [row,col {unknown-source}]: [1,0]
at org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor.mergeParams(URIParameterInInterceptor.java:120)
at org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor.handleMessage(URIParameterInInterceptor.java:103)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:220)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)
at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:92)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:285)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:131)
at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:175)
at org.apache.cxf.transport.servlet.AbstractCXFServlet.doPost(AbstractCXFServlet.java:153)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog
at [row,col {unknown-source}]: [1,0]
at com.ctc.wstx.sr.StreamScanner.throwUnexpectedEOF(StreamScanner.java:686)
at com.ctc.wstx.sr.BasicStreamReader.handleEOF(BasicStreamReader.java:2134)
at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2040)
at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1069)
at org.apache.cxf.staxutils.StaxUtils.readDocElements(StaxUtils.java:746)
at org.apache.cxf.staxutils.StaxUtils.read(StaxUtils.java:605)
at org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor.mergeParams(URIParameterInInterceptor.java:118)
... 22 more
정보: Invoking POST on /orders
2008. 12. 10 오후 1:55:57 org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor handleMessage
정보: URIParameterInterceptor handle message on path [/orders] with content-type [application/x-www-form-urlencoded]
2008. 12. 10 오후 1:55:57 org.apache.cxf.phase.PhaseInterceptorChain doIntercept
정보: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Unexpected EOF in prolog
at [row,col {unknown-source}]: [1,0]
at org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor.mergeParams(URIParameterInInterceptor.java:120)
at org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor.handleMessage(URIParameterInInterceptor.java:103)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:220)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)
at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:92)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:285)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:131)
at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:175)
at org.apache.cxf.transport.servlet.AbstractCXFServlet.doPost(AbstractCXFServlet.java:153)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog
at [row,col {unknown-source}]: [1,0]
at com.ctc.wstx.sr.StreamScanner.throwUnexpectedEOF(StreamScanner.java:686)
at com.ctc.wstx.sr.BasicStreamReader.handleEOF(BasicStreamReader.java:2134)
at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2040)
at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1069)
at org.apache.cxf.staxutils.StaxUtils.readDocElements(StaxUtils.java:746)
at org.apache.cxf.staxutils.StaxUtils.read(StaxUtils.java:605)
at org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor.mergeParams(URIParameterInInterceptor.java:118)
... 22 more
이 뭥미? 해결책을 찾을 수 있길 바라며, 일단 오류를 남긴다. 관련 오류가 Apache CXF Issue Tracker에도 있어서 좀 불길하긴 하다만...(https://issues.apache.org/jira/browse/CXF-1863)
- 사용 JDK: Sun JDK 1.6.0_11 for Windows
- 사용 library: Apache CXF 2.1.3
- 사용 Servlet/JSP Engine: Apache Tomcat 6.0.18
----------- 해결 -----------
문제는 client였다. 기본 예제의 client인 Client.java는 아래와 같이 단순히 java.net.URL을 기반으로 작성되었다.
package demo.order.client;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.net.URL;
import java.net.HttpURLConnection;
public final class Client {
public static void main(String[] args) throws Exception {
String xml = null;
try {
// Make a HTTP connection to the server
URL u = new URL("http://localhost:8080/orderapp_rest/orders");
HttpURLConnection httpCon = (HttpURLConnection) u.openConnection();
// Set the request method as POST
httpCon.setRequestMethod("POST");
httpCon.setDoOutput(true);
OutputStream os = httpCon.getOutputStream();
// XML are encoded in UTF-8 format
OutputStreamWriter wout = new OutputStreamWriter(os, "UTF-8");
wout.write("<?xml version=\"1.0\"?>\r\n");
// Add customer name as XML fragment
wout.write("<order xmlns=\"http://demo.order\"><name>Rajeev</name></order>r\n");
wout.flush();
// Make implicit connection to the server
httpCon.getContentLength();
httpCon.disconnect();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.net.URL;
import java.net.HttpURLConnection;
public final class Client {
public static void main(String[] args) throws Exception {
String xml = null;
try {
// Make a HTTP connection to the server
URL u = new URL("http://localhost:8080/orderapp_rest/orders");
HttpURLConnection httpCon = (HttpURLConnection) u.openConnection();
// Set the request method as POST
httpCon.setRequestMethod("POST");
httpCon.setDoOutput(true);
OutputStream os = httpCon.getOutputStream();
// XML are encoded in UTF-8 format
OutputStreamWriter wout = new OutputStreamWriter(os, "UTF-8");
wout.write("<?xml version=\"1.0\"?>\r\n");
// Add customer name as XML fragment
wout.write("<order xmlns=\"http://demo.order\"><name>Rajeev</name></order>r\n");
wout.flush();
// Make implicit connection to the server
httpCon.getContentLength();
httpCon.disconnect();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
혹시나 하는 마음에 화끈하게 Apache HttpClient library를 써서 아래와 같이 다시 만들어 보았다.
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
public class Client {
public static void main(String... args) throws Exception {
String strURL = "http://localhost:8080/orderapp_rest/orders";
String reqData = "<?xml version=\"1.0\"?>\r\n<order xmlns=\"http://demo.order\"><name>Rajeev</name></order>\r\n";
PostMethod post = new PostMethod(strURL);
post.setRequestEntity(new StringRequestEntity(reqData));
HttpClient httpclient = new HttpClient();
try {
int result = httpclient.executeMethod(post);
if (200 == result)
System.out.println(post.getResponseBodyAsString());
} finally {
post.releaseConnection();
}
}
}
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
public class Client {
public static void main(String... args) throws Exception {
String strURL = "http://localhost:8080/orderapp_rest/orders";
String reqData = "<?xml version=\"1.0\"?>\r\n<order xmlns=\"http://demo.order\"><name>Rajeev</name></order>\r\n";
PostMethod post = new PostMethod(strURL);
post.setRequestEntity(new StringRequestEntity(reqData));
HttpClient httpclient = new HttpClient();
try {
int result = httpclient.executeMethod(post);
if (200 == result)
System.out.println(post.getResponseBodyAsString());
} finally {
post.releaseConnection();
}
}
}
이랬더니 정상적으로 동작하였다. 하기사 java.net.URL이 잘 동작했으면 Apache HttpClient가 있을 필요가 있겠어?
설마허니, 예제 code 돌려보지도 않은 것은 아니겠지? 혹시 Web site에서 배포하는 예제에서 동일한 문제를 겪으시는 분들은 위 Client.java로 다시 해 보시길...
그런데 둘 차이는 뭘까? 한 번 파보고 싶은데... 싶은데싶은데싶은데싶은데싶은데... 젠장.