달력

3

« 2024/3 »

  • 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

'REST'에 해당되는 글 1

  1. 2008.12.10 Apache CXF에서 com.ctc.wstx.exc.WstxEOFException 발생
스프링과 아파치 CXF를 이용해 POJO 웹 서비스를 디자인하고 구현하기, Part 2: RESTful 웹 서비스 만들기의 예제(예제도 위 site에서 받을 수 있다) 따라 하다 된통 걸렸다... -.-

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

이 뭥미? 해결책을 찾을 수 있길 바라며, 일단 오류를 남긴다. 관련 오류가 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();
        }
    }
}

혹시나 하는 마음에 화끈하게 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();
    }
  }
}

이랬더니 정상적으로 동작하였다. 하기사 java.net.URL이 잘 동작했으면 Apache HttpClient가 있을 필요가 있겠어?

설마허니, 예제 code 돌려보지도 않은 것은 아니겠지? 혹시 Web site에서 배포하는 예제에서 동일한 문제를 겪으시는 분들은 위 Client.java로 다시 해 보시길...

그런데 둘 차이는 뭘까? 한 번 파보고 싶은데... 싶은데싶은데싶은데싶은데싶은데... 젠장.
:
Posted by 하얀 말