How to read Gzipped payload in a POST request in SpringBoot - rest

I need to read gzipped json payload in a POST request in my SPringBoot app which accepts json data. How to do that in order to keep the application generic as there may be other clients in future sending data in plain json or other compression formats? I suppose this should be handled by the server itself so is there any way to instruct the embedded Tomcat to unzip the payload?
My SpringBoot application runs on embedded Tomcat 9.0.17.
The controller accepts JSON payload in a POST request.
#RequestMapping(value = "/update/v1", method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
public ResponseEntity<String> receiveUpdates(#RequestBody String update) {
We recently changed our content provider and the new one is sending payload in "gzip" format (with header content-encoding=gzip) and without any content-type header. As a result it gives the following error
'error': 'Unsupported Media Type', 'message': "Content type '' not supported"
If I change my consume type to MediaType.ALL_VALUE, my controller starts receiving the request but the payload itself is gzipped. I can handle it in my service layer but that would make it specific to gzipped data.
This problem could be solved by introducing a Filter to handle gzipped payload as mentioned here and here.
But I believe there should be a way to instruct the Tomcat to handle this and serve unzipped data.

Related

How do I send a JSON body as part of multipart/form-data with Paw?

I have a REST request that accepts multipart/form-data. This request is already working with an Angular front-end. It expects both an array of files in a parameter called files[] and a JSON body in a parameter with the name body. In Paw, it seems like I can get the multipart files to be recognized by my endpoint but the body doesn't appear to be the correct content type (application/json). Is there any way to specify the content type for each part of a multipart POST in Paw?
Details:
The error message I'm getting on the server-side is:
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported
The config for the body in Paw is:

Camel does not set 'Transfer-Encoding chunked' in case response is prepared by exception handler processor

I am implementing REST services using Apache-CXF running on servicemix and for that I have a camel route that does some processing, sends the message over queue, process some more and send back the reply. Something like this:
from("direct:start")
.process(A)
.process("activemq:abc")
.process(B);
On this route I have applied some basic validation and exception handler and when I have to stop the route in both cases, I use something like this:
exchange.getOut().setBody(response);
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
I use soap UI, restclient-UI and putty to make http requests and I get proper response body displayed in all of them. Now I wanted to preserve request headers so I made a little change everywhere in the code so that response bodies are set in exchange.getIn() only. For example: in case of validation failure I do:
exchange.getIn().setBody(response);
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
Just with this little change, the rest clients I am using to make request stopped displaying the response body. As per the server logs, response is being generated and also as per the logs in rest client, I am getting the proper response but they are unable to display the response body only in case when I stop the route in between. Normal response is displaying just fine. Only the restclient-UI was considerate enough to show the error as to why they are not displaying body and the error is:
Byte array conversion from response body stream failed.
Diggin deeper, I found the only response header which was there in success response but missing in error response:
Transfer-Encoding chunked
Error response is around 1000 characters long and contains a header called content-length. I am not sure but I think the problem has something to do with this itself. I would really like to play with exchange.getIn but these different kind of responses prepared by camel are confusing me. How can I make sure my camel responses are always displayed properly?
The Content-Length header will be preserved from the original request so you need to remove it so that camel cxf can work out the new body length on the response and set Content-Length with that.

How to create a SOAP message from JSON payload in mule

I need to transform the following json payload into a soap message and send the message to a consumer, the consumer edits the data and sends back the soap message.
I haven't done much in soap. I only have REST experience. what steps do I need to take in a process like this?
what is the best approach?
[{"salesOrderId":"00004-5-6","saleName":"House Sale","status":"processing"}, {"salesOrderId":"00001-2-3","saleName":"Car Sale","status":"processing"}]
There are various way to perform this transformation, for example:
PATH - 1
Json To XML (with transformer or string set payload)
Xml To SOAP Request using XSLT, transformer or string set payload.
Send SOAP Request sobre HTTP (POST / Content-type: applicacion/xml / soapAction)
PATH - 2
Json To SOAP Request using Groovy, XSLT or string set payload.
Send SOAP Request sobre HTTP-OUTBOUND (POST / Content-type: applicacion/xml / soapAction)
PATH - 3
Json To SOAP Request Proxy (WSDL To Java).
Send SOAP Request sobre HTTP-OUTBOUND (POST / Content-type: applicacion/xml / soapAction)
The easiest way of doing it is extract the JSON elements from the JSON payload by using <json:json-to-object-transformer/>and store each node value in variables like flow variable in Mule.
Then You can create the SOAP request using XSLT and passing the flow variables value into XSLT as <mulexml:context-property/>
ref:- https://developer.mulesoft.com/docs/display/current/XSLT+Transformer
Once your SOAP XML is created, you can simply post them to your HTTP outbound endpoint pointing to your external web service you need to consume
Try using Mule DataMapper. That helps you to convert a JSON to XML in the more easier way. You can try it in Anypoint Studio of Mule.

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/

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.