简体   繁体   中英

COSM JSON Parser Error on .POST

I'm using jpachube and am running into problems with .POST on creatDatastream. I am getting POST error 400, and the following details from COSM's debug tool:

{"title":"JSON Parser Error","errors":"lexical error: invalid char in json text. <?   xmlversion=\"1.0\"encoding=\"U"}

My XML request body from the COSM debug tool is as follows:

<?xml version="1.0" encoding="UTF-8"?>
       <eeml xmlns="http://www.eeml.org/xsd/005"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd"><environment><data id="0">
       <tag>CPU</tag>
            <current_value>0.0</current_value>
        </data>
       </environment>
   </eeml>

COSM's API documentation for what the xml request body should look like is as follows:

<eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-     instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/0.5.1   http://www.eeml.org/xsd/0.5.1/0.5.1.xsd">
  <environment>
    <data id="23">
      <tag>apple</tag>
      <tag>jag</tag>
      <tag>tag</tag>
      <tag>lag</tag>
      <current_value>11</current_value>
      <max_value>211.0</max_value>
      <min_value>7.0</min_value>
    <unit type="conversionBasedUnits" symbol="symbol">label</unit>
  </data>
</environment>

The only difference I found was the version #, but I made that switch in the code already and got the same error.

I thought for the v2 of the COSM API was set up so xml and JSON are interchangeable but it converts everything to JSON.

The error is coming from this method call in Pachube.java

public boolean createDatastream(int feed, String s) throws PachubeException {
        HttpRequest hr = new HttpRequest("http://api.cosm.com/v2/feeds/"
                + feed + "/datastreams/");
        hr.setMethod(HttpMethod.POST);
        hr.addHeaderItem("X-PachubeApiKey", this.API_KEY);
        hr.setBody(s);
        HttpResponse g = this.client.send(hr);

        if (g.getHeaderItem("Status").equals("HTTP/1.1 201 Created")) {
            return true;
        } else {
            throw new PachubeException(g.getHeaderItem("Status"));
        }
    }

Any input appreciated.

Day two...

Modified the createDatastream method using input from bjpirt (much thanks). Method looks like this

public boolean createDatastream(int feed, String s) throws PachubeException {

        HttpRequest hr = new HttpRequest("http://api.cosm.com/v2/feeds/"
                + feed + "/datastreams.xml");
        hr.setMethod(HttpMethod.POST);
        hr.addHeaderItem("X-PachubeApiKey", this.API_KEY);
        hr.addHeaderItem("Content-Type:", "application/xml");
        hr.setBody(s);
        HttpResponse g = this.client.send(hr);

        if (g.getHeaderItem("Status").equals("HTTP/1.1 201 Created")) {
            return true;
        } else {
            Log.d("create data stream", "prob");
            throw new PachubeException(g.getHeaderItem("Status"));
        }
    }

This throws the following error for .POST on the COSM debug tool (error code 422):

<?xml version="1.0" encoding="UTF-8"?><errors><title>Unprocessable Entity</title>         <error>Stream ID has already been taken</error></errors>

So, naturally, I need to get a title on this request. That is done through the toXMLWithWrapper in Data.java

public String toXMLWithWrapper() {
    String ret = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<eeml xmlns=\"http://www.eeml.org/xsd/005\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"5\" xsi:schemaLocation=\"http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd\"><environment>";
    ret = ret + ">\n\t<title>" + "cosm app" + "</title>\n\t";//inserted this line to add title
    ret = ret + this.toXML() + "</environment></eeml>";
    return ret;
}

And the request body looks like (from COSM debug tool):

<?xml version="1.0" encoding="UTF-8"?>
<eeml xmlns="http://www.eeml.org/xsd/005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd"><environment>
<title>cosm app</title>
<data id="0">
    <tag>CPU</tag>
    <current_value >0.0</current_value>
</data></environment></eeml>

This comes back as error code 500 (ouch!)

Response body is

<?xml version="1.0" encoding="UTF-8"?><errors><title>Oops, something's broken</title>  <error>We've been unable to complete your request due to a problem with our server</error></errors>

day three

it was pointed out that there was a problem with the xml (see below). I fixed the typo and I'm back to a 422 error. So, looking more closely at the response body I thought maybe that there was something wrong with the data stream. I delete all of the datastreams in the feed, create a new feed, and I get exactly ONE AWESOME HTTP:/1.1 201 - happy, right? Wrong, after the first .POST I get nothing. When I turn the app off and then back on, I'm back to 422 error and the same response body "Stream ID has already been taken". Yikes!

It seems like the xml may be invalid.

The opening <environment> node seems to be closed twice <environment>>

The 422 is probably because you are trying to POST to an existing feed.

To update a feed you need to send a PUT request.

See the Updating a feed docs

The clue is that the system looks like it's expecting json but you're feeding it XML. The default for the v2 api is json, so you'll need to make sure that you're including XML in the URL, eg:

https://api.cosm.com/v2/feeds/113/datastreams.json

Alternatively, you can set a content type header on the request to indicate this:

Content-Type: application/xml

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM