How to convert a zip file into an octet stream - java

I am working on SOAP web services. I have been given a third party WSDL URL for which I need to generate client code. I need to pass a zip file which contains a bundle of XML, for which the passing parameter should be type octet stream. I don't know how to pass an argument as an octet stream. How can I do this?

A SOAP Web-service needs to return the result in a format defined by SOAP - basically in XML. Octet streams are a different mechanism of file/data transfer, so that's not what you need.
What you need to use is "SOAP with Attachments" or "MTOM (Message Transmission Optimization Mechanism)", where you ZIP file will be attached to the SOAP message in some way. If you're using Java with Axis 2, This article in the Axis documentation describes what you what you need to do.
Remember that your webservice clients will also need to understand MTOM or SwA. So pick the approach that is easily supported by your clients.

Related

How setHeader() works in Apache camel

I was going through some documentation on Apache Camel and not able to understand what setHeader() does in Apache Camel. Does it add a header to the file specified within from. And also suggest some link where I can get tutorial on Apache Camel.
No, it does not add anything to a file. .setHeader() creates a header that exist within the current route. You can create a header like .setHeader("myHeader", "myHeaderValue"). Use headers to access dynamic properties during your route by .getHeader("myHeader") For more long lasting property use exchange properties.
setHeader to a file(message) consumed(from) does not set the header to the file.
Camel File2 check the Message Headers. This lists all the Message Headers supported for produce(to) and consume(from) of File endpoint. For a file consumed, you can access the (getHeader) supported headers in the message. But overwriting these values does not overwrite the meta data of the file though.
Headers and Properties in Apache Camel can be used interchangeably to pass values between processes in a single route, but when you want to carry across different routes the behaviors differs. Headers can be lost at endpoints basically as they usually represent some component specific things. Go through the document to understand further.
Best tutorials for Camel - Apache Camel Books and Apache Cammel Documentation
Keep in mind that in Camel you are working with Exchange object and that object has headers, properties, body.in, body.out etc.
So when you are writing from(“file:...”) content of your file will be putted into your Exchange’s body.in and then you can get your file’s content for example in Processor using exchange.getIn().getBody().
Headers are part of your Exchange, so when you are writing: exchange.setHeader(“headerExample”,”MyHeader”), it will add header of existing Exchange’s headers.
See Message.setHeader(String name, Object value):
Sets a header on the message
Looking at Return Address of the Enterprise Integration Patterns (EIP) we find:
A Return Address is put in the header of a message because it’s not part of the data being transmitted.
We can also look at RFC2045, 3. MIME Header Fields:
MIME defines a number of new RFC 822 header fields that are used to describe the content of a MIME entity.
And we can even look at RFC1866 – Hypertext Markup Language - 2.0, 5.2. Head: HEAD::
The head of an HTML document is an unordered collection of information about the document.
All the same concept: Storing metadata together with the payload.

How can I pass JSON as well as File to REST API in JAVA?

My main question is how can I pass JSON as well as File to post request to REST API? What needs in Spring framework to work as client and wait for response by passing post with JSON and File?
Options:
Do I need to use FileRepresentation with ClientResource? But how can I pass file as well as JSON?
By using RestTemplate for passing both JSON as well as File? How it can be used for posting JSON as well as File?
Any other option is available?
Sounds like an awful resource you're trying to expose. My suggestion is to separate them into 2 different requests. Maybe the JSON has the URI for the file to then be requested…
From a REST(ish) perspective, it sounds like the resource you are passing is a multipart/mixed content-type. One subtype will be application/json, and one will be whatever type the file is. Either or both could be base64 encoded.
You may need to write specific providers to serialize/deserialize this data. Depending on the particular REST framework, this article may help.
An alternative is to create a single class that encapsulates both the json and the file data. Then, write a provider specific to that class. You could optionally create a new content-type for it, such as "application/x-combo-file-json".
You basically have three choices:
Base64 encode the file, at the expense of increasing the data size
by around 33%.
Send the file first in a multipart/form-data POST,
and return an ID to the client. The client then sends the metadata
with the ID, and the server re-associates the file and the metadata.
Send the metadata first, and return an ID to the client. The client
then sends the file with the ID, and the server re-associates the
file and the metadata.

What's the proper way to return a file as the response?

Basically I need to provide REST service that would receive a String param, use that param to fetch a file from another system and then return the fetched file back as the response.
The effect should be the same as when a user clicks on a pdf or any other binary file link and the browser prompts him to save/download that file.
A couple of points:
is it possible to stream the file (to send bytes as I receive them from source system). In other words, how to handle very large files?
also related to streaming, when using regular HttpServletResponse, do I have to wait until a large file is completely read to return response.build()?
How do I go around doing this using Apache Wink?
PS Sorry, this may be trivial for Wink gurus, but I'm just starting to wrap my head around developer guide.
You can just return the java.io.File from your method. You can wrap it with Response if you like. Wink will handle the streaming. The streaming doesn't start when you call to response.build(), but rather when your method finishes.
If you want a correct download dialog, you should return the proper Content-Disposition header. See How to set response header in JAX-RS so that user sees download popup for Excel?

Web service for retrieving chunks of data

I'm planning to develop a webservice, and I like to try the RESTful architecture. The issue is that I don't know if the service is adequate for it, or it is better to use SOAP.
The service is about downloading some data from the server to a device on the local computer. The data will be split into chunks. The service will be run with an ad-hoc client at the local machine that will manage the device the file is gonna be stored in.
I was thinking on having something like:
/files/{id} --> will inform about the details of the file
/files--> list all the files
The problem is for the action. In rest only GET, POST and (PUT DELETE) are defined. But I want to have something like download. My idea, although not fully restful is to create:
/files/{id}/download
This will return something like
{ "chunk" : "base64 string with chunk data"
"next" : "http://XXX/file/id/download?chunk=1
}
When next is empty the whole set of chunks would be downloaded.
What do you think? Is it ok to do it this way or would it be better the traditional way using SOAP and defining functions like getFiles(), getFileChunk(chunkNo, file)?
Any comment is really appreciated.
See you
If using REST, you don't need to define your own "chunking" protocol as the HTTP headers Content-Length, Content-Range and Transfer-Encoding are all used for sending chunked data.
See the RFC for HTTP header fields
As John already mentioned you might want to separate between your file resources and the file resource metadata (any information about your file). Additionally a more RESTful way to access your chunks could look like this:
http://url/files/{id}/chunks
{
"complete" : false,
"chunks": [
"http://url/files/<fileid>/chunks/1",
"http://url/files/<fileid>/chunks/2",
"http://url/files/<fileid>/chunks/3",
]
}
Basically, here, you return a list of RESTFUL URIs to all your file chunks and the information if all chunks of the file are already complete. I don't see that SOAP might have any advantage there since you would define the same methods (getFile and getChunks) that are already covered by the REST verb GET.
It sounds like you really have two different resources: file-metadatas and files. What about something like:
/file/{id} // GET: Retrieve this file's data.
/file-metadata/{id} // GET: Metadata about a particular file. Contains link to file:
// {
// ...
// data: "http://.../file/156", // Where to find file's data.
// }
/file-metadata // GET: List metadata for all files.

Find if InputStream of DataHandler is empty

In my application I develop web service that get attached file.
The file is mapped to DataHandler object via JaxB,
and I have access to the file via DataHandler.getInputStream()
My problem is this:
When the file attribute exist in the web service request, but no file is attached,
I still get the DataHandler object, and its getInputStream().available() = 11 bytes
(a header I guess...??).
So I can I know that the inputStream is empty?
Thanks,
Alon
Read it and parse the data as it should be parsed. The answer is in there.
The InputStream#available() certainly does not return the length of the stream or so as you seem to think. In some cases it (by coincidence) may, but you shouldn't rely on that. It just returns the amount of bytes which are available for read without blocking other threads. Just read the stream the usual Java IO way fully until the last bit returned -1 and then intercept on the whole data you received.

Categories

Resources