Thursday, April 11, 2013

Sending JSON Responses from a Proxy Service in WSO2 ESB

If you have come up with the requirement of sending JSON responses from a proxy service, then following proxy configuration can be used straightaway to try that out.

i.e. Create a proxy service named JSONProxy with the following content. Then, you can try that out by issuing HTTP GET to http://localhost:8280/services/JSONProxy

Proxy Configuration
<proxy xmlns="http://ws.apache.org/ns/synapse" name="JSONProxy" transports="https,http" 
       statistics="disable" trace="disable" startOnLoad="true"> 
   <target> 
      <inSequence> 
         <header name="To" action="remove"/> 
         <property name="RESPONSE" value="true"/> 
         <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/> 
         <payloadFactory> 
            <format> 
               <person> 
                  <fullName> 
                     <firstName>Ruchira</firstName> 
                     <lastName>Wageesha</lastName> 
                  </fullName> 
                  <birthDate> 
                     <month>May</month> 
                     <date>31</date> 
                     <year>1984</year> 
                  </birthDate> 
                  <address> 
                     <street>Flower Road</street> 
                     <province>Western</province> 
                     <city>Colombo</city> 
                     <country>Sri Lanka</country> 
                     <postalCode>0007</postalCode> 
                  </address> 
               </person> 
            </format> 
         </payloadFactory> 
         <property name="messageType" value="application/json" scope="axis2"/> 
         <send/> 
      </inSequence> 
   </target> 
   <description></description> 
</proxy>
JSON Response
{
    "person": {
        "fullName": {
            "firstName": "Ruchira",
            "lastName": "Wageesha"
        },
        "birthDate": {
            "month": "May",
            "date": "31",
            "year": "1984"
        },
        "address": {
            "street": "Flower Road",
            "province": "Western",
            "city": "Colombo",
            "country": "Sri Lanka",
            "postalCode": "0007"
        }
    }
}

14 comments:

  1. I am invoking an axis2 service and converting xml output in json using




    Now i need to enrich the json ouput enveloping it with a js function (jsonp) that rapresents a callback for the client, i.e.

    myCallback({a:b, ....});

    How can this be done in esb?

    Tk u in advance.

    ReplyDelete
  2. Sorry, this is the left part

    <outSequence>
    <property name="messageType" value="application/json" scope="axis2"/>
    <send/>
    </outSequence>

    ReplyDelete
  3. In order to format your as JSONP, you will have to write a custom Axis2 message formatter. Then register it in ESB with a specific content type such as "application/jsonp" and set "messageType" in your proxy service to match the content type.

    Then ESB runtime will call that message formatter and ask it to format the message where you can format it as you want.

    [1] is the JSON message builder which is used to generate JSON. You can simply write something like that.

    [1] https://svn.wso2.org/repos/wso2/carbon/kernel/branches/4.0.0/dependencies/axis2/1.6.1-wso2v7/modules/json/src/org/apache/axis2/json/JSONFormatter.java

    ReplyDelete
    Replies
    1. Hi Wageesha, tk you for your reply.
      I wrote the formatter:

      package org.apache.axis2.json;

      import org.apache.axiom.om.OMDataSource;
      import org.apache.axiom.om.OMOutputFormat;
      import org.apache.axis2.AxisFault;
      import org.apache.axis2.context.MessageContext;
      import org.apache.axis2.json.AbstractJSONMessageFormatter;

      import javax.xml.stream.XMLStreamWriter;
      import java.io.IOException;
      import java.io.OutputStream;
      import java.io.Writer;

      public class JSONPFormatter extends AbstractJSONMessageFormatter {

      @Override
      public byte[] getBytes(MessageContext msgCtxt, OMOutputFormat format) throws AxisFault {
      if (msgCtxt.getProperty("JSON_STRING") != null) {
      if (msgCtxt.getProperty("JSONP_CALLBACK") != null) {
      String jsonResponse = (String) msgCtxt.getProperty("JSONP_CALLBACK") + "(" + (String) msgCtxt.getProperty("JSON_STRING") + ");";
      return jsonResponse.getBytes();
      }
      }
      throw new AxisFault("Could not find the JSON response.");
      }

      @Override
      public void writeTo(MessageContext msgCtxt, OMOutputFormat format,
      OutputStream out, boolean preserve) throws AxisFault {
      if (msgCtxt.getProperty("JSON_STRING") != null) {
      if (msgCtxt.getProperty("JSONP_CALLBACK") != null) {
      String jsonResponse = (String) msgCtxt.getProperty("JSONP_CALLBACK") + "(" + (String) msgCtxt.getProperty("JSON_STRING") + ");";
      try {
      out.write(jsonResponse.getBytes());
      } catch (IOException e) {
      throw AxisFault.makeFault(e);
      }
      }
      }
      }

      @Override
      protected XMLStreamWriter getJSONWriter(Writer arg0) {
      throw new UnsupportedOperationException("Cannot get a JSON writer");
      }

      @Override
      protected String getStringToWrite(OMDataSource arg0) {
      throw new UnsupportedOperationException("Cannot get the JSON string");
      }

      }

      and put the jar in ../wso2-platform/worker/wso2esb-4.6.0/repository/components/extensions

      my axis2.xml contains

      and

      but when i start esb i got the error

      DeploymentException: A ClassNotFoundException error occurred while validating the message builder org.apache.axis2.json.JSONBuilder

      Is that the correct place to put the jar?

      Tk u in advance

      Delete
    2. axis2.xml:
      <messageFormatter contentType="application/jsonp"
      class="org.apache.axis2.json.JSONPFormatter"/>
      <messageBuilder contentType="application/jsonp"
      class="org.apache.axis2.json.JSONBuilder"/>

      Delete
  4. You need to put your jar into <WSO2_ESB_HOME>/repository/components/lib directory. Also, please rename your package to something like "org.apache.axis2.jsonp" as there might be conflicts due to the same package name from different jars.

    ReplyDelete
    Replies
    1. Hi Wageesha, tk you for your reply.

      I implemented the formatter overriding the writeTo method and this works!


      @Override
      public void writeTo(MessageContext msgCtxt, OMOutputFormat format,
      OutputStream out, boolean preserve) throws AxisFault {

      try{
      out.write(new String("jsonpCback(").getBytes("utf8"));

      super.writeTo(msgCtxt, format, out, preserve);

      out.write(new String(");").getBytes("utf8"));

      out.flush();
      }catch(IOException e){
      e.printStackTrace();

      }
      }

      Delete
  5. added proxy configuration and uncommented the JSON buliders and formatters in axis2.xml.
    successfully able to create the proxy and deployed.

    When clicked on TryIt it is failing with below error....


    Error connecting to the Tryit ajax proxy


    Kindly help in resolving.

    ReplyDelete
  6. full error message :


    Error connecting to the Tryit ajax proxy

    ReplyDelete
  7. I like your article it wordpress installation service is very nice would like to
    1337x UK proxy

    ReplyDelete
  8. I am hoping the same best work from you in the future as well. In fact your creative writing abilities may inspired others.
    access Torrentz in UK

    ReplyDelete
  9. Nice tool for JSON Lovers, http://jsonformatter.org

    ReplyDelete