Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Receiving isomorphic.xml.XMLParsingException while saveData() with JSON as payload

    I have this DataSource class:

    <code>
    public abstract class BasicRestDataSource extends RestDataSource {
    protected abstract void bindFields();
    public BasicRestDataSource() {
    createAndInitRestDatasource();
    bindFields();
    }
    protected void createAndInitRestDatasource() {
    setDataFormat(DSDataFormat.JSON);
    }
    protected void setUpOperationBindings() {
    // set up FETCH to use GET requests
    OperationBinding fetch = new OperationBinding();
    fetch.setOperationType(DSOperationType.FETCH);
    fetch.setDataProtocol(DSProtocol.GETPARAMS);
    DSRequest fetchProps = new DSRequest();
    fetchProps.setHttpMethod("GET");
    fetch.setRequestProperties(fetchProps);

    // set up ADD to use POST requests
    OperationBinding add = new OperationBinding();
    add.setOperationType(DSOperationType.ADD);
    add.setDataProtocol(DSProtocol.POSTMESSAGE);
    DSRequest addProps = new DSRequest();
    addProps.setHttpMethod("POST");
    addProps.setContentType("application/json");
    add.setRequestProperties(addProps);

    // set up UPDATE to use PUT
    OperationBinding update = new OperationBinding();
    update.setOperationType(DSOperationType.UPDATE);
    update.setDataProtocol(DSProtocol.POSTMESSAGE);
    DSRequest updateProps = new DSRequest();
    updateProps.setHttpMethod("POST");
    updateProps.setContentType("application/json");
    update.setRequestProperties(updateProps);

    // set up REMOVE to use DELETE
    OperationBinding remove = new OperationBinding();
    remove.setOperationType(DSOperationType.REMOVE);
    remove.setDataProtocol(DSProtocol.POSTMESSAGE);
    DSRequest removeProps = new DSRequest();
    removeProps.setHttpMethod("DELETE");
    remove.setRequestProperties(removeProps);

    // apply all the operational bindings
    setOperationBindings(fetch, add, update, remove);
    }
    }
    </code>
    I have this Impl Class for my BasicRestDataSource

    <code>
    public class TestDataSource extends BasicRestDataSource {
    @Override
    protected void createAndInitRestDatasource() {
    super.createAndInitRestDatasource();
    setUpOperationBindings();
    }

    @Override
    protected void bindFields() {
    DataSourceTextField cityClinicSystemId = new DataSourceTextField("CityClinicSystemId", "City Clinic System ID");
    cityClinicSystemId.setPrimaryKey(true);
    cityClinicSystemId.setCanEdit(false);

    DataSourceTextField stateClinicSystemId = new DataSourceTextField("stateClinicSystemId", "State Clinic System ID");
    DataSourceTextField activityStatus = new DataSourceTextField("activityStatus", "Activity Status");
    DataSourceDateField dateitem = new DataSourceDateField("dateitem","Date of Inception");
    setFields(stateClinicSystemId,activityStatus,dateitem);

    setFetchDataURL("http://localhost:4567/fetchData");
    setAddDataURL("http://localhost:4567/saveData");
    setUpdateDataURL("http://localhost:4567/saveData");
    }
    }
    </code>

    I have tested the rest resources using curl and they all work fine. No issues. 100% perfect. Not to worry there at all

    Now in my GWT Module. I have a code which simple creates a form like as follows:

    <code>
    private DynamicForm createDynamicForm() {
    DynamicForm dynaForm = new DynamicForm();
    dynaForm.setNumCols(2);
    dynaForm.setColWidths("230,*");
    dynaForm.setWidth(401);
    dynaForm.setAutoDraw(false);
    dynaForm.setDataSource(new TestDataSource());
    return dynaForm;
    }
    </code>
    and then I have a two buttons. Button for fetch and Button for save. Very Simple. No complications

    <code>
    Button fd = new Button("fetch");
    Button sd = new Button("save");
    vStack.addMember(fd);
    vStack.addMember(sd);
    fd.addClickHandler(new ClickHandler() {

    @Override
    public void onClick(ClickEvent event) {
    dynaForm.fetchData();
    }
    });
    sd.addClickHandler(new ClickHandler() {

    @Override
    public void onClick(ClickEvent event) {
    dynaForm.saveData();
    }
    });
    </code>
    when I click the fetch button. I get response from the rest and dynaFOrm happily loads the data and i am happy. But when I press save button. I get this error

    <code>
    === 2013-09-07 17:48:37,628 [l0-2] DEBUG RPCDMI - rpc returned RPCResponse
    === 2013-09-07 17:48:37,628 [l0-2] DEBUG RPCManager - Content type for RPC transaction: text/plain; charset=UTF-8
    === 2013-09-07 18:03:50,893 [l0-2] DEBUG XML - Parsed XML from (in memory stream): 2ms
    === 2013-09-07 18:03:50,895 [l0-2] DEBUG HttpProxyServlet - HttpProxy - ProxyData is: {
    xsi:"http://www.w3.org/2000/10/XMLSchema-instance",
    url:"http://localhost:4567/saveData",
    httpMethod:"POST",
    params:{
    isc_dataFormat:"json"
    },
    contentType:"application/json",
    requestBody:"{\r \"dataSource\":\"isc_TestDataSource_0\", \r \"operationType\":\"update\", \r \"componentId\":\"isc_DynamicForm_0\", \r \"data\":{\r \"stateClinicSystemId\":\"100\", \r \"activityStatus\":\"Active\", \r \"dateitem\":\"2013-09-04\", \r \"ownerType\":\"Public\"\r }, \r \"oldValues\":{\r \"stateClinicSystemId\":\"100\", \r \"activityStatus\":\"Active\", \r \"dateitem\":\"2013-09-04\", \r \"ownerType\":\"Public\"\r }\r}"
    }
    === 2013-09-07 18:03:50,895 [l0-2] ERROR XML - XML parser fatal error: file '(in memory stream)' line 1: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
    === 2013-09-07 18:03:50,895 [l0-2] DEBUG XML - Exception thrown during XML parsing
    === 2013-09-07 18:03:50,896 [l0-2] ERROR HttpProxyServlet - HttpProxy - Top-level servlet error:
    com.isomorphic.xml.XMLParsingException: [
    "XML parser fatal error: file '(in memory stream)' line 1: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog."
    ]
    at com.isomorphic.xml.XML.parseXML(XML.java:206)
    at com.isomorphic.xml.XML.parseXML(XML.java:125)
    at com.isomorphic.servlet.HttpProxyServlet.doPost(HttpProxyServlet.java:495)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:324)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
    </code>

    The debug console gives this as a trace

    DSRequest Tab output of RPC TAB

    <code>
    {
    dataSource:"isc_TestDataSource_0",
    operationType:"update",
    componentId:"isc_DynamicForm_0",
    data:"{\r \"dataSource\":\"isc_TestDataSource_0\", \r \"operationType\":\"update\", \r \"componentId\":\"isc_DynamicForm_0\", \r \"data\":{\r \"stateClinicSystemId\":\"100\", \r \"activityStatus\":\"Active\", \r \"dateitem\":\"2013-09-04\", \r \"ownerType\":\"Public\"\r }, \r \"oldValues\":{\r \"stateClinicSystemId\":\"100\", \r \"activityStatus\":\"Active\", \r \"dateitem\":\"2013-09-04\", \r \"ownerType\":\"Public\"\r }\r}",
    callback:{
    target:[DynamicForm ID:isc_DynamicForm_0],
    methodName:"saveEditorReply"
    },
    showPrompt:true,
    prompt:"Saving form...",
    oldValues:{
    stateClinicSystemId:"100",
    activityStatus:"Active",
    dateitem:"2013-09-04",
    ownerType:"Public"
    },
    requestId:"isc_TestDataSource_0$6272",
    clientContext:{
    },
    fallbackToEval:false,
    afterFlowCallback:"isc_DynamicForm_0.$49z(dsRequest, dsResponse, data)",
    editor:[DynamicForm ID:isc_DynamicForm_0],
    lastClientEventThreadCode:"MUP0",
    httpMethod:"POST",
    contentType:"application/json",
    bypassCache:true,
    isRestRequest:true,
    dataFormat:"json"
    }
    </code>
    I DONOT understand. The payload is JSON then whcy do I get an XML Parsing error, that too from the http Proxy. The call does not even
    get to the REST resource.

    I am using licensed version of smart gwt SmartClient Version: v9.0p_2013-09-04/Pro Deployment (built 2013-09-04)

    #2
    Your URLs should be expressed as relative paths, otherwise, there is no reliable way to detect if they are on the same host, so the HttpProxy is automatically used to get around the same origin policy.

    Bigger picture, you probably want to delete your entire DataSource definition and start over after reading the QuickStart Guide. The only thing your code achieves is to break the automatic transaction capability by sending "add" and "update" to different URLs. And by using RestDataSource, you aren't taking advantage of autoDeriveSchema, a key capability that is covered at the beginning of the Server Framework chapter.

    Comment


      #3
      Thanks for your response. But let me try to explain my situation once again.

      I already have a back end which is being exposed by REST resources. We are also in the process of modifying the Response object and Request objects by the REST resources to accommodate smartgwt.RestDatasource.

      On the client side, we are using SmartGWT v4 and would like to connect to the already exposed REST apis using RestDatasource from Smart GWT application. Thats all there is to it. And further more, my fetchData() already works with no issues.

      The only thing I need to know is a reason for HttpProxy trying to parse JSON payload as an XML doc.

      Could you please confirm that my understanding is correct and I could continue to use the

      SmartGWT + RestDatasource <--> OurREST Resources.

      Or we have to use SmartGWT Server framework and use REST Handler and drop our jersey based REST apis. That's fine and we wil be happy to do so. Please suggest us a route to take.

      Comment


        #4
        As we explained, the reason for the HttpProxy being used is because your URLs are not relative (they start with "http").

        While it is possible to continue on your current path with Jersey, we would very strongly advise that you not do so. You are expending extra effort for a much worse result than what you would get if you used server-side integration as explained in the QuickStart. Aside from transactions, you're also missing out on all the export features and many other things.

        See also the FAQ for a detailed explanation of why it's usually a bad idea to use generated REST APIs.

        Comment


          #5
          So how do I call a REST resource using RestHandler where the REST url is not at the same server and is not even on same port.

          The REST url is localhost:4567/fetchCity for GET
          The REST url is localhost:4567/saveCity for POST

          Could you please point me to some sample project. I am not finding one.

          Comment


            #6
            You don't want to deploy that way for your core rest services, because it means that every request to such an service has to be relayed by the HttpProxy on the server.

            That said, when you do have a legitimate reason to call some API hosted elsewhere (eg SalesForce WSDL or similar), use of the HttpProxy will normally just be transparent, with no special settings.

            Comment


              #7
              Thanks for ur prompt response.

              But when performing a POST. I get this exception

              com.isomorphic.xml.XMLParsingException: [
              "XML parser fatal error: file '(in memory stream)' line 1: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog."
              ]

              I have the code in the original post. This is extremely important for us to move forward as, with this XMPParsingExcption we are going in circles right now.

              B/W i am fine in deploying using the RESTHandler in favor of http proxy. I am yet to see how though. Could you please break this ice and show me the sample which will allow me to do so (connect SmartGWT client to an existing Spring MVC REST Resources.)

              Comment


                #8
                Actually, you're going in circles because you're not following the advice in the QuickStart Guide. None of these concerns you've hit - HttpProxies, relative URLs, different operationTypes going to different URLs, or JSON vs XML encoding, etc - are relevant *at all* if you just use the approach in the QuickStart Guide, which again also gets you exports and other features with no additional effort.

                Comment


                  #9
                  I ran into the same issue with RestDataSource.

                  For Add operation, I need to send JSON object as payload of the POST request.

                  The REST API server is not running in the same domain, therefore, the request is routed through HttpProxy.

                  I got the following error:
                  === 2014-02-15 01:19:52,373 [l0-4] ERROR XML - XML parser fatal error: file '(in memory stream)' line 1: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
                  === 2014-02-15 01:19:52,373 [l0-4] DEBUG XML - Exception thrown during XML parsing
                  === 2014-02-15 01:19:52,373 [l0-4] ERROR HttpProxyServlet - HttpProxy - Top-level servlet error:
                  com.isomorphic.xml.XMLParsingException: [
                  "XML parser fatal error: file '(in memory stream)' line 1: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog."
                  ]

                  The HttpProxy servlet failed to forward the request with json payload to a remote server. How do I workaround this problem? Thanks!
                  I have read the previous response. I do not have a choice to host the REST API server on the same domain.

                  You should be able to reproduce this problem by modifying the RestfulDataSourceSample showcase example and move the json data files to a different domain. Also change the data protocol for add from postParams to postMessages
                  Last edited by mshen; 14 Feb 2014, 17:28.

                  Comment


                    #10
                    Please post all the information that the forums prompts you for.

                    Please try to remember to do this consistently.

                    Comment


                      #11
                      I have encountered this problem with SmartGWT EE version 4.0.

                      The issue can be reproduced by using the RestfulDataSourceSample showcase example, but forcing the request to go through httpProxy.

                      Get request works fine, but not post request.

                      Comment


                        #12
                        Please play close attention to what the forums prompts you for:

                        1. full version

                        2. server logs

                        3. contents of RPC tab, etc

                        If you are not already testing against the latest patched version of 4.0, please do so now.

                        Comment


                          #13
                          With the information that I provide, it should be very easy to reproduce.

                          If not, I can send you the program and then maybe you can get whatever information that you need to triage this problem by running the program itself. Is it something can be discussed through email? I don't want to post my code here though.

                          Comment


                            #14
                            If it's already fixed, we're not going to be able to reproduce it, right?

                            Please simply follow the instructions and this will be resolved quickly.

                            Comment


                              #15
                              Please refer to #1 post on this thread for detailed information including code, server logs and contents of RPC tab.

                              The version that I tried is SmartGWT EE 4.0 trial version that I downloaded on January 9th, 2014.

                              Comment

                              Working...
                              X