Thursday, September 25, 2008

Enabling JSON in Apache Axis2

Apache Axis2 can handle several message formats. JSON is just one of them. Axis2 supports two notations of JSON, they are known as mapped and Badgerfish. Namespaces are not handled in the mapped notation while the Badgerfish notations supports it.

The default Axis2 installation has all the binaries needed to process JSON messages but you need to enable it in order to use JSON. This can be done by adding the following sections to your axis2.xml.

Add the following section to the messageFormatters section in the axis2.xml,

<messageFormatter contentType="application/json"

class="org.apache.axis2.json.JSONMessageFormatter"/>

<messageFormatter contentType="application/json/badgerfish"

class="org.apache.axis2.json.JSONBadgerfishMessageFormatter"/>

<messageFormatter contentType="text/javascript"

class="org.apache.axis2.json.JSONMessageFormatter"/>

And the following to the messageBuilders section of the axis2.xml

<messageBuilder contentType="application/json"

class="org.apache.axis2.json.JSONOMBuilder"/>

<messageBuilder contentType="application/json/badgerfish"

class="org.apache.axis2.json.JSONBadgerfishOMBuilder"/>

<messageBuilder contentType="text/javascript"

class="org.apache.axis2.json.JSONOMBuilder"/>

Now you are all set to invoke services as well as respond using JSON. You would notice that the notation of JSON used depends on the content-type of the message.

15 comments:

Favalos said...

Hi Keith,

I have an Axis2 embedded in my war file. But, I would like to enable json response for my services.

How could I do that?

Thanks in advance and I hope for your response.

Keith Chapman said...

Well you could use the same mechanism described above.

Kedar said...

I get following error at server side:
---------------------------------------------------------------------
[ERROR] Exception occurred while trying to invoke service method twoWayOneParameterEcho
org.apache.axis2.AxisFault: namespace mismatch require http://axis2userguide.axis2.apache.org found

at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:177)
at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:102)
at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:100)

-------------------------------------------------------------------------------------------------------

Could you help me please?

Keith Chapman said...

This error occured because Axis2 expected your request to be namespace qualified, but it was not.

One solution is to make sure your request honour the namespace expected by Axis2.

The other might be to add the following parameter to your services.xml. (I did not test this, but theoretically it should work)
<schema elementFormDefaultQualified="false"/>

Please let me know whether this worked for you.

Kedar said...

Hi Keith, thanx for prompt reply.
No it did not work for me.
How ever i will brief you what am I doing:
1. Have hosted a Axis2 web service from Axis user guide code.
2. Added message formatters and builders at server side.
2. Wrote a JSON client as below:


private OMElement createEnvelope3() throws Exception {
String input = "<twoWayOneParameterEcho><toEcho>Test Me!</toEcho></twoWayOneParameterEcho>";
return AXIOMUtil.stringToOM(input);
}

public void testdoEchoOM() throws Exception{
EndpointReference targetEPR = new EndpointReference(
"http://localhost:1111/axis2/services/SampleService");
OMElement payload = createEnvelope3();
Options options = new Options();
options.setTo(targetEPR);
options.setProperty(Constants.Configuration.MESSAGE_TYPE, "application/json");
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setProperty(Constants.Configuration.HTTP_METHOD, Constants.Configuration.HTTP_METHOD_POST);
File configFile =
new File("D:\\Kedar\\OpenSourceProjects\\Axis2-1.4.1\\modules\\json\\test-resources\\axis2.xml");
ConfigurationContext clientConfigurationContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(null, configFile
.getAbsolutePath());
ServiceClient sender = new ServiceClient(clientConfigurationContext, null);
options.setAction(null);
sender.setOptions(options);
options.setTo(targetEPR);
OMElement result = sender.sendReceive(payload);
result.serialize(System.out);
// OMElement ele = (OMElement)result.getFirstOMChild();
// System.out.println(ele.getText());
}



----------------------------------------------
I need to do following:
1. Host Web Services (w/ Axis2) for SOAP/JSON/XML RPC.
2. Build Automated Client code for each one of the types above.
Kindly guide me in correct direction as I am finding bit lost out here with Axis2.

sushil said...

Hi keith,

I have created a simple webservice which takes the json and return it by appending a string to it.

I am sending a very simple and clean json.
And i expect axis2 should recognised it as
application/json but it is treating it as
application/json/badgerfish.
I/O {log}

GET /axis2/services/one/hello?name=sushil&response=json HTTP/1.1
Host: localhost:9000
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20071008 Ubuntu/7.10 (gutsy) Firefox/2.0.0.6
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

Content-Type: application/json/badgerfish;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 04 Mar 2009 11:48:57 GMT

62
{"ns:helloResponse":{"@xmlns":{"ns":"http:\/\/wsone"},"ns:return":{"$":"sushil passed from one"}}}
0


If i want to support only one type of json message like application/json
then what should i do. (if i remove badgerfish from messageformatter and messagebuilder then content type becomes
application/xml)

Is there any way?

afkham said...

JSON can only be used with RawXML message receivers, and not any other message receivers. Also note that the outermost element in the payload of the soap envelope should not have any namespace qualification of namespace declarations. Elements inside that wrapper element can have namespaces.

Anonymous said...
This comment has been removed by a blog administrator.
mahesh4u said...

Hi Keith,
I’m using axis2-1.6. I have added message formatter and message builder entries in axis2.xml. I simply want the version service to return response in JSON format. But I'm always getting in xml format. Please help me. Basically I'm trying to build REST+JSON webservice using axis2

Manisha said...

Hi,
I want to get and send response in json using axis2/c.is the same procedure applicable to get and send response in axis2c linux platform??

Unknown said...

I am also trying to find some solution how to force AXIS2/C REST service to return JSON .. any suggestion?

Unknown said...
This comment has been removed by the author.
Unknown said...
This comment has been removed by the author.
Keith Chapman said...

I'm not too familiat with Axis2/C to provide an answer to that. My gut feel is that it may not be supported, you can certainly drop a mail to the Axis2/C mailing list and check with them.

Unknown said...

Hello Keith,
I read Afkham's entry above, he says the outermost element must not contain a namespace. That's the problem I encounter now. My test web service containts only one input element 'name' which requires a namespace. If I send a badgerfish including that namespace I get a namespace error. If I wrap it with an arbitrary element that does not have a namespace it is processed but then I get an unexpected element ADBException because of my additional wrapper element.
What it the solution to this?

Many thanks & best regards
Roman