What is more efficient - rest

I have a schema, which will result in an XML like this
<root-element>
<element_1>value_a<element_1>
<element_2>value_b<element_2>
<element_3>value_c<element_3>
<element_1>value_a<element_1>
<element_2>value_b<element_2>
<element_3>value_c<element_3>
</root-element>
Now, in my REST Method, there are two different methods which receives input call
#POST
#Path(PATH+"/{" + PATH_2 + "}/query-by-list." + XML)
#Consumes (MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
public Response getShipmentListXML (String xmlRequest)
and other we can do is like
#POST
#Path(PATH+"/{" + PATH_2 + "}/query-by-list." + XML)
#Consumes (MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
public Response getShipmentListXML (JAXBElement<ShipmentListType> jaxbShipmentListType)
in short, the first method is getting the "raw" request and the second one is marshalling the request into appropriate jaxb element type.
Question is, which one would be faster ? The one which is taking raw request or the one which is marshalling ... or ... would that making any request ?
P.S:
The raw request is marshalling the input raw string into jaxbobject anyways. the only difference is that the input request (xml body) is used somewhere else too. which can be converted from those jaxb object.

If you don't need to read or store the XML payload, then it shouldn't make any difference from a performance standpoint whether you do the unmarshalling manually or via Jersey, but the latter will make for less code and work.
If you do need to read or store the XML payload, then letting Jersey do the unmarshalling for you is less efficient as it will require you to remarshall it later on. In this case, you might as well just get the raw String.

Related

Jersey and javax.rs - Accepting separate content types

On my REST API, I've got a POST that did not previously need any input expect from a path parameter. However, I now want to expand by accepting an optional form parameter. I tried this out with #FormParam, but it turns out that (at least) one of the clients are not setting content type application/x-www-form-urlencoded, and Jersey fails with this:
The #FormParam is utilized when the content type of the request entity
is not application/x-www-form-urlencoded
Can I solve this? I want to allow the new clients to send in the form and still accept whatever content type the old clients are setting.
A bad solution would be to use query parameter.
Edit:
Tried adding a new resource with a separate #Consumes
#POST
#Path("/something")
#Consumes(MediaType.WILDCARD)
public Response thisDoesNotWork(){
and
#POST
#Path("/something")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response thisWorks(#FormParam("input") String input){
In my tests, when actually sending a form, it works. When I don't send set a content type, it fails with the same error as above. So it seems it selects the thisWorks(..) resource.
Edit2:
I figured out a work-around
#POST
#Path("/something")
#Consumes(MediaType.WILDCARD)
public Response thisDoesNotWork(
MultivaluedMap<String, String> formParams
){
Using this as the only resource, formParam will be null if no content type is set, and will contain the form parameters if form is set. It will mess up the documentation probably but at least it will work.

Aggregation Correlation Strategy based on XML Payload

Issue: How to correlate messages for an aggregator based on a XML value in the payload? I have a scenerio where I call a third party application and it only gives back an xml response. Based on an xml value in the payload I would like to correlate the messages to produce a single response back to the consumer.
Example using Header Attribute
#CorrelationStrategy
public Object correlate(Message message) throws JMSException {
return message.getHeaders().get("JMSXUserID");
}
Solution Notes:
As described below and referenced in the spring documentation for xml payload support.
http://docs.spring.io/spring-integration/reference/html/xml.html#xpath-spel-function
Sample Config Applied:
<aggregator
id="agg"
input-channel="jmsInChannel"
output-channel="outputChannel"
ref="AggregatorPOJO"
method="combineResponesMessages"
correlation-strategy-expression="#xpath(payload, '/test/name')"
release-strategy="AggregatorPOJO"
release-strategy-method="isComplete"/>
This will correlate the following xml.
<test><name>test1</name></test>
Take a look if #xpath() SpEL function can help you, for example:
correlation-strategy-expression="#xpath(payload, '/name')"
where payload is a payload in some XML representation of messages to correlated and /name is an XPath against that payload.
You should be sure that spring-integratrion-xml jar is on your CLASSPATH.
You would have to parse the XML; you might be able to use a simple regex Pattern or you might have to convert the payload to a DOM for more complex situations.

Sending Files and Metadata in Jersey Rest Service

I need to create a ReST service using Jersey 2.0. I need to send multiple documents and metadata to the client.
What is the best approach do to the achieve this.
I was able to send a MultiPart response from the server , but not sure how to read this from the client code
Let's say you have a document called "document1" which you want to get via your client.
In your REST-API your unique identifier for the document (the resource) could be:
http://example.com/restapi/documents/document1
As you want to READ data you do a HTTP-GET Request to that uri.
And here comes the important part for you: A resource can have multiple representations - meta data and binary data in your case.
So the client has to tell the server which representation type to get (content negotiation). This information can be set in the ACCEPT Header of the client request for instance.
You can use the content type "application/json" as a representation for the meta data.
Unfortunately you didn't tell us what kind of binary data you want to send.
If they are PDFs the content type would be "application/pdf" for instance. If the binary data doesn't have a specific type you can use "application/octet-stream".
Of course there is work to be done on the server side too. Here an example:
#Path("/documents/{documentname}")
public class docResource {
#GET #Produces("application/json")
public Response getDocumentMetaData(#PathParam("documentname") String docName) {
// Create a Response containing a json
}
#GET #Produces("application/pdf")
public Response getDocumentBinaryData(#PathParam("documentname") String docName) {
// Create a response containing the binary data
}
...
}
Jersey will check the accept header of the client and will run the appropriate method.
Also see: https://jersey.java.net/documentation/latest/jaxrs-resources.html
If you are using jersey with jackson you can also easily marshal a POJO to JSON and visa versa:
http://examples.javacodegeeks.com/enterprise-java/rest/jersey/json-example-with-jersey-jackson/
If you are not sure what to do in the "getDocumentBinaryData"-Method - checkout this simple example from mkyong:
http://www.mkyong.com/webservices/jax-rs/download-excel-file-from-jax-rs/

gwt sending an object via post request

I need to do a post request from a gwt app to a server. So far this works fine. However, originally I used an object that contained all the parameters send over to the server via a rpc request so I did not have to manage the serialization and deserialization myself. Now I send this stuff via a post request and on the server side I get something like username=blabla&location=blabla
I'd rather like to do something like this (pseudo code):
String serializedObject = parameterObject.serialize();
sendPostRequestWithContent(serializedObject);
and on the server side:
doPost(...)
String serializedObject = request.getContent();
ParameterObject parameterObject = ParameterObject.deserialize( serializedObject );
Any idea how I could do this?
There are different ways.
For simple objects manually serialize and deserialize (field1=123123&field2=1232)
Use JSON as payload.
For solution 2 you can use a JSON parser on the beackend (Jackson, Gson, etc) and on the client you can either manually serialize the object to JSON or one of these methods.

Parsing response from the WSDL

I've generated the web service client in eclipse for the OpenCalais WSDL using the "develop" client type. Actually I was following this post so not really going in detail. Now when I get the results this way: new CalaisLocator().getcalaisSoap().enlighten(key, content, requestParams);, I get the String object, containing the response XML. Sure it's possible to parse that XML, but I think there must be some way to do it automatically, e.g. getting the response object in the form of some list whatsoever?
The response from the SOAP interface is already parsed. The englighten() method returns an XML string. When you call it with SOAP, this response is wrapped within even more XML. The SOAP library already parses the outer SOAP XML and returns the result of the enlighten() method, which is also XML.