I have an Axis2 web service that's already deployed, and which communicates with clients using SOAP. There's a new requirement now to enable REST calls by sending JSON requests and receiving JSON formatted responses.
Following this small tutorial: http://code.google.com/p/jsonp-support-for-axis2/wiki/OneStopPage
I was able to configure my Axis 2 web service correctly. Using my browser, I used the following URL to return a Student object:
http://localhost:8181/Axis2Json/services/StudentService/getStudent?response=application/json&value=3
OUTPUT :
{"return":{"#type":"ax21:Student","age":25,"firstName":"Mouhammed","lastName":"Soueidane"}}
The problem is that the returned JSON, doesn't look like a standard JSON representation (Not even in badgerfish format). So for instance, if I want to call a method called "setStudent" which takes in a Student object, I really have no clue of the JSON string that I need to pass to it.
I tried so many stuff, most of which resulted in a casting exception (java.lang.ClassCastException: java.lang.String cannot be cast to org.codehaus.jettison.json.JSONObject)
Does anyone have an idea about how to allow an Axis 2 web service to use both SOAP and JSON, based on the content type of the client?
Related
I am creating an controller where there is certain attributes in json which is an doing in postman a POST request like this if all attributes are posted then its fine
if one then is missing then it would look like this
i want this response when some attribute is missing how to implement this
This is normally implemented in two steps:
Implement a validation mechanism for the method that handles the incoming request. Normally you would throw an exception here if the input is incorrect, in your example a missing JSON key.
Implement a global error handler that will process the exception from point 1 and format the response as JSON.
For point 1 the usual choice is the Java Bean Validation framework because it's integrated with Spring Boot and allows to define validation constraints with annotations like #NotEmpty. You can take a look at this example.
For point 2 the usual choice is #RestControllerAdvice or #ControllerAdvice. You would have to understand your service web server setup to implement it properly e.g. it might behave differently if you use Spring WebFlux.
Is there a way to set request attributes in a ContentExchange object? What I have been doing so far is send information to the server in the Request body by using the setRequestContentSource(InputStream inputstream) method. But what should I do if I want to send information categorized by field names, say like, Content, Title, Author etc.?
The code that I have as of now is pasted below. Thanks for your help!
exchange.setRequestContentSource(new ByteArrayInputStream(
serialized.getBytes("UTF-8")));
exchange.setRequestContentType("text/html");
exchange.setMethod("POST");
exchange.setURL(("http://localhost:8089/"));
client.send(exchange);
To be more precise, by request attributes, I mean something equivalent to request.setAttribute("Name","ABC"). Only in this case, the request is sent is through the ContentExchange object.
Ah, so ServletRequest attributes are not part of the HTTP protocol.
There is no standard way to send those attributes via a HTTP protocol.
In fact, the servlet spec itself limits its use for application specific information (such as passing information from a filter to a servlet) and SSL certificate related information.
However, using standard POST and form data, via exchange.setRequestContentType("multipart/form-data"); and obtain those values using HttpServletRequest.getParameter("Content"), etc.. similar to how a FORM is submitted from a web browser. Benefit here, is that you can even provide a simple HTML FORM to test our your application.
Choice #2 is to send your data in a markup like JSON or XML and have the server parse it.
This has the benefit of allowing for hierarchical data.
If this interests you, I'd recommend you read about REST and maybe dig into a REST library like Jersey, Restlet, and standards like JAX-RS.
I am creating a Web Service that will handle incoming request properly (I knew, it is a description) I found some sample code which present SOAP WS and looks like:
#SoapAction("some fine url")
#ResponsePayload
public CertResponse getCert(#RequestPayload Cert param)
{...}
It takes Cert object from request and manages it properly. I want to do it in the REST approach and I changed this class to look like:
#RequestMapping(value="getCert", method = RequestMethod.POST)
#ResponseBody
public CertResponse getCert(#RequestBody Cert param)
{...}
But I have no idea how or even if it is possible to write a client that can send object through HTTP Post.
Can anyone give me a hint how can i send object Cert? Or if i have to stay with #SoapAction what should I do to make it work? I guess removing #Controller is not enough.
In SOAP approach, there is a well defined way to convert each class object to SOAP formatted XML. Thus, there is no effort.
If you will use RESTful approach, you have to describe how your Cert or CertResponse objects will be written to/read from the response/request.
Basically you have three options:
Use JSON or XML or plain String. Convert your Web service descriptor so that the request and response are one of those (JSON, XML, String). Then your getCert method should convert the request to Cert object, prepare your response as CertResponse object and convert it to an appropriate response type.
Leave your getCert method as is. But you need to specify "how Cert objects are read from request" and "how CertResponse objects are written to response" You need to define classes that extend interfaces MessageBodyReader and MessageBodyWriter. In these classes a similar conversion logic should be implemented that converts your objects to/from JSON or XML or String.
In any of these two options you need to implement two things : A method that converts JSON/XML/String to Cert, a method that converts CertResponse object to JSON/XML/String.
You can do a text based implementation, which parses/constructs the request/response by text processing and uses String class only. Or you can use some library such as JSON library with JSONObject class, or Java SAX or DOM based XML libraries that come with the Java bundle.
Check out for application frameworks such as Spring. They might provide ways to automatically convert your objects to JSON or XML, reducing the programming effort necessary.
Spring allows you to pass JSON objects from the client as a request parameters, it will convert them into your objects automatically. This discussion have some examples.
SOAP services are not really compatible with REST semantics. And it's not clear what SOAP framework do you use. Typically most SOAP frameworks offer you one way or another to generate a SOAP client code for you WSDL. You can check cxf.apache.org.
For REST services use something like Jersey or Spring MVC
How, if possible, do I get the raw XML request/response that is invoked/retrieved by Axis in my application?
I'm using WSDL2Java that is included with Axis to generate the Java stubs.
EDIT:
What I currently have is an app that uses Axis to handle the remote API calls.
One of the requirement is to 'store' all the XML request/response from these calls in the session so that it will be available in the JSP (for debugging purposes). How can I achieve this?
I tried writing a custom handler that extends BasicHandler but in that handler, I still can't get the HttpServletRequest/HttpServletResponse pair from the MessageContext
After a while searching its as simple as this:
//After your _call.invoke(...);
//Request
String request = _call.getMessageContext().getRequestMessage().getSOAPPart().getEnvelope().getBody().toString();
//Response
String response = _call.getMessageContext().getResponseMessage().getSOAPPart().getEnvelope().getBody().toString();
where _call is org.apache.axis.client.Call
Then you can save it in a file where you want...
Why don't you write a server side soap handler, get hold of MessageContext and I believe there is a way to get hold of the payload from there. If you want to pass it to downstream then put it in thread local. See e.g. of handler here
I end up using the solution described in this question
Basically, I use it to get a hold of the HttpServletRequest and from there I set the proper item in the session.
I have a Java WebService setup which consumes an xml file and want to be able to produce either xml or json based on what the client requests. I know that this is possible through reading up on Jersey REST methods but it does not show how to extract this information. I have also looked on google all over but can't seem to find any examples of this.
http://wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features is the site that I was initially referencing which shows that it is possible, I was just wondering if anyone would be able to help me find out how to actually distinguish the client's request. Is it in the html header? body? And if so what is the proper way to extract it?
This is what my method currently looks like, I do not have any issues with connection, just finding out what the client requests as a return type.
#POST
#Path("getStatisticData")
#Produces ({"application/xml","application/json"})
#Consumes ("application/xml")
public String getStatisticData(#FormParam("xmlCoords") String xmlFile) throws Exception{
Thanks in advance.
You can extract it using the #HeaderParam annotation:
...
public String getStatisticData(#HeaderParam("Accept") String accept,
#FormParam("xmlCoords") String xmlFile) throws Exception {
...
}
The Accept header in the request is used for the client to indicate to the server what methods it supports.
If the client can set HTTP headers, the proper way to do it is to use the Accept header:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
IF this is not possible, the type requested could be passed in as an argument.
Alternatively, expose two different web services: one that returns XML, one that returns JSON. Each web service would call the same code but with a parameter specifying which format to use.