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.
Related
How can I set content type of HTTP Put as xxxx+xml?
I was referring to solution in this link Android, sending XML via HTTP POST (SOAP). Its fine when we set content type like this, i mean the xml is came along with the request:
httppost.setHeader("Content-Type","application/soap+xml;charset=UTF-8");
but when i change type soap to something custom, the xml disappear on the request (i saw on the wireshark), like this:
httppost.setHeader("Content-Type","application/vnd.oma-pcc+xml;charset=UTF-8");
then, i tried put the xml only, so the request is ok again:
httppost.setHeader("Content-Type","application/xml;charset=UTF-8");
I want to know what exactly the rules for the content-type than come together with the xml type so that the xml still there.
Thanks.
Assuming you're using HTTPClient of 4.1.3 or greater -
When constructing you're entity, you have the option to specify the content being used for the POST or PUT operation for certain entities.
There is a ContentType object which should be used to specify this.
Using the factory method .create() you can specify the mimetype with a charset - the ContentType will be used by the framework to properly emit the header in question.
Example API call:
ContentType.create("application/vnd.oma-pcc+xml", CharSet.forName("UTF-8"));
NOTE Editing for HttpClient 4.1.2
In the case of 4.1.2, when you create your entity for the post or put operation, set the content type on the entity not the execution (HttpPost or HttpPut) using setContentType(String). This is deprecated in 4.1.3 and beyond.
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.
I'm using restlet 2.0.11 to provide data for a Dojo-based web application via a REST-Web-Interface.
According to the documentation of dojo, pagination is realized using the "content-range" header of HTTP, thus dojo expects a header like:
Content-Range: items 0-19/100
(Source: http://dojotoolkit.org/reference-guide/1.7/dojox/data/JsonRestStore.html)
Which means that the REST-Api provides the first 20 of 100 total items.
Setting the Content-Range header manually like this
getResponse().getAttributes().get("org.restlet.http.headers").add(new Parameter("Content-Range", "FooBar")
Results in the following error:
WARNING: Addition of the standard header "Content-Range" is not allowed. Please use the equivalent property in the Restlet API.
According to restlet's documentation the property is "message.entity.range" (Source: http://wiki.restlet.org/docs_2.0/130-restlet.html)
The direct modification of this hash-map was also without success:
getResponse().getAttributes().put("message.entity.range", "FooBat");
Another way which seemed to be promising is using the "Representation"-object of restlet, since it has a setRange() method, but during request time, the object reference is null:
getResponse().getEntity()
So my question is: How to set a Content-Range header to a Restlet response?
You have to use the equivalent Java properties in the Representation class, so this is getResponse().getEntity().setRange(myRange).
this is a kind of a follow-up question to this one here.
So it is possible to do the http-http routing as described in the above url. Is it also possible to adjust the output, so that only a specific part is returned? E.g. the <title> of the Google-Page if we stick to the mentioned example..or enhance the output with additional info?
You can add to the route and do your transformation, to eg only contain the title of the google page.
pseudo route:
from jetty
to http
to processor
eg just add for example a processor, and in the processor you can change the message body/headers to contain what you want.
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.