cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Want the oppurtunity to discuss enhancements to PTC products? Join a working group! X

POSTing via a REST call in Java

No ratings

Below is where I will discuss the simple implementation of constructing a POST request in Java.

I have embedded the entire source at the bottom of this post for easy copy and paste.

To start you will want to define the URL you are trying to POST to:

String url = "http://127.0.0.1:80/Thingworx/Things/Thing_Name/Services/​Service_to_Post_to​";

Breaking down this url String:

    • http://​ - a non-SSL connection is being used in this example
    • 127.0.0.1:80 -- the address and port that ThingWorx is hosted on
    • /Thingworx -- this bit is necessary because we are talking to ThingWorx
    • /Things -- Things is used as an example here because the service I am posting to is on a Thing
        • Some alternatives to substitute in are ThingTemplates, ThingShapes, Resources, and Subsystems
    • /​Thing_Name​ -- Substitute in the name of your Thing where the service is located
    • /Services -- We are calling a service on the Thing, so this is how you drill down to it
    • /​Service_to_Post_to​ -- Substitute in the name of the service you are trying to invoke

Create a URL object:

URL obj = new URL(url);

Class URL, included in the java.net.URL import, represents a Uniform Resource Locator, a pointer to a "resource" on the Internet. Adding the port is optional, but if it is omitted port 80 will be used by default.

Define a HttpURLConnection object to later open a single connection to the URL specified:

HttpURLConnection con = (HttpURLConnection) obj.openConnection();

Class HttpURLConnection, included in the java.net.HttpURLConnection import, provides a single instance to connect to the URL specified. The method openConnection is called to create a new instance of a connection, but there is no connection actually made at this point.

Set the type of request and the header values to pass:

con.setRequestMethod("POST");

con.setRequestProperty("Accept", "application/json");

con.setRequestProperty("Content-Type", "application/json");

con.setRequestProperty("appKey", "80aab639-ad99-43c8-a482-2e1e5dc86a2d");


You can see that we are performing a POST request, passing in an Accept header, a Content-Type header, and a ThingWorx specific appKey header.

Pass true into the setDoOutput method because we are performing a POST request; when sending a PUT request we would pass in true as well. When there is no request body being sent false can be passed in to denote there is no "output" and we are making a GET request.

   

    con.setDoOutput(true);

Create a DataOutputStream object that wraps around the con object's output stream. We will call the flush method on the DataOutputStream object to push the REST request from the stream to the url defined for POSTing. We immediately close the DataOutputStream object because we are done making a request.

   

    DataOutputStream wr = new DataOutputStream(con.getOutputStream());

    wr.flush();

    wr.close();


          The DataOutputStream class lets the Java SDK write primitive Java data types to the ​con​ object's output stream.


The next line returns the HTTP status code returned from the request. This will be something like 200 for success or 401 for unauthorized.

   

    int responseCode = con.getResponseCode();


The final block of this code uses a BufferedReader that wraps an InputStreamReader that wraps the con object's input stream (the byte response from the server). This BufferedReader object is then used to iterate through each line in the response and append it to a StringBuilder object. Once that has completed we close the BufferedReader object and print the response we just retrieved.

   

    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

    String inputLine;

    StringBuilder response = new StringBuilder();

    while((inputLine = in.readLine()) != null) {

      response.append(inputLine);

    }

    in.close();

    System.out.println(response.toString());


   The InputStreamReader decodes bytes to character streams using a specified charset.

        The BufferedReader provides a more efficient way to read characters from an InputStreamReader object.

        The StringBuilder object is an unsynchronized method of creating a String representation of the content residing in the BufferedReader object. StringBuffer can be used instead in a case where multi-threaded synchronization is necessary.     



Below is the block of code in it's entirety from the discussion above:

public void sendPost() throws Exception {

  String url = "http://127.0.0.1:80/Thingworx/Things/Thing_Name/Services/Service_to_Post_to";

  URL obj = new URL(url);

  HttpURLConnection con = (HttpURLConnection) obj.openConnection();

  //add request header

  con.setRequestMethod("POST");

  con.setRequestProperty("Accept", "application/json");

  con.setRequestProperty("Content-Type", "application/json");

  con.setRequestProperty("appKey", "80aab639-ad99-43c8-a482-2e1e5dc86a2d");

  // Send post request

  con.setDoOutput(true);

  DataOutputStream wr = new DataOutputStream(con.getOutputStream());

  wr.flush();

  wr.close();

  int responseCode = con.getResponseCode();

  System.out.println("\nSending 'POST' request to URL : " + url);

  System.out.println("Response Code : " + responseCode);

  BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

  String inputLine;

  StringBuilder response = new StringBuilder();

  while((inputLine = in.readLine()) != null) {

  response.append(inputLine);

  }

  in.close();

  //print result

  System.out.println(response.toString());

  }

Comments

I used the similar approach but I am getting exception. (Status 500 returned). I need to send an XML and not sure how the API should receive it. Currently I have it as input with XML type. It is not getting defined. Do I need to specify any additional step to map my XML content to input parameter?  Any help will be greatly appreciated.

You're going to have to wrap the XML content in a JSON structure.

For example:

Let's say you have an input parameter of type XML on your custom service called "xmlContent". Your XML content is <xml><name>Meghan</name></xml>

The body you are then passing along with the REST call is {"xmlContent":"<xml><name>Meghan</name></xml>"}

Awesome!!  Quick question, so all content being sent to a service targeting a specific parameter has to be wrapped in JSON object?

Or in other words, I want to send a json object to a parameter for my thingworx service.  Do I simply specify the body like so:

 

con.setRequestProperty("Body", "{"+"JSONInput"+":"+obj+"}"); where the obj is the variable containing the JSON object?

Version history
Last update:
‎Dec 14, 2015 10:12 AM
Updated by:
Labels (1)