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).
Related
I need to configure a parser which can add few default fields(such as default labels) in the request body of underlying BQ HTTP request whenever any query is run via this bqserv instance (like mentioned in the code snippet below). How to build bqserv?
bqserv.query(QueryJobConfiguration.newBuilder(query).build)
I found BigQueryOptions.newBuilder().setTransportOptions() to set transport options, but I am unable to figure out exactly how to configure/(or set a parser for) HTTP request body ? I came across com.google.cloud.spark.bigquery.repackaged.com.google.api.client.util.ObjectParser as well, but again not sure how to use it and create bqserv (class com.google.cloud.spark.bigquery.repackaged.com.google.cloud.bigquery.BigQueryImpl) object.
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.
After reading the following thread:
Setting a custom Content-Range Header using Restlet
I tried setting a custom unitname in the Range for the entity. This does not solve the Problem.
final Range range = new Range();
range.setUnitName("items");
range.setIndex(0);
range.setSize(20);
[...]
getResponseEntity().setRange(range);
getResponseEntity().setSize(100);
The response now contains the following headers:
Content-Range:"items 0-19/100"
But Restlet also reads the range.size (20 in this case) and puts this as Content-Length automatically. Which results in:
Content-Length:"20"
This causes the client (e.g. Browser to stop reading after 20Bytes. (This also causes a null-pointer exception on the server, since the outputstream gets closed unexpectedly.)
The offical Restlet Documentation: http://restlet.com/technical-resources/restlet-framework/guide/2.3/core/http-headers-mapping
says Content-Length is available as message.entity.size, but this needs to be set to 100 to achieve the desired String in the Content-Range. This looks like a bug to me since range.size is used to calculate the content-length, not the entity size.
I can not set the Content-Length manually, since this is also a standard Header, and any manual changes to the standard headers are ingored.
The "Fix" proposed in the mentioned thread, only changes the Unitname - not the real unit - of the Range specified. It is still interpreted as bytes as is unusable as such.
Using the values in Range twice - for the content-range as well as the content-legth seems to be the problem.
Is there any new way to manually override the headers , or make them dojo compatible?
Manual changes are blocked in the HeaderUtils called by the ServerAdapter, causing the: "WARNING: Addition of the standard header [...] is not allowed..." warning.
support will be added in future 2.3.8 release of Restlet Framework.
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.
I'm working on setting up a RESTful request for the application I'm working on and I wanted to use xml as the request in the uri instead of allowing the client to supply the parameters in the URI itself.
I'm looking to have the URI like so: someurl/service/request
instead of: someurl/service/request?id={id}&name={name}
I have been searching the web to see what the convention should be when creating the POST request. Can anyone kind of help point me in the right direction on how I should set up this POST request allowing the client to use xml?
Not sure if it is relevant but I'm setting up the server side code in JAVA using the SPRING 3.0 framework. Please let me know if I need to supply more details.
Thanks for your help!!
You can put parameters into the body of the request. They are the same format as appending them to the URL. Eg:
POST /path/script.cgi HTTP/1.0
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
home=Cosby&favorite+flavor=flies
You can do that in prototype pretty easily with:
new Ajax.Request('someurl/service', {
method: 'post',
postBody: 'home=Cosby&favorite+flavor=flies',
encoding: 'UTF-8'});
To add your xml file, just append it to your postBody with some sort of delimiter so your cgi knows where parameters end and where xml begins.
I think that's what you were looking for, hope it helps.
You can pass whatever you want in your POST body. So if you want to use XML, you can use XML. Example:
POST /car
Content-Type: text/xml
<car>
<date>10-10-2007<date>
<type>Corvette</type>
</car>
HTTP/1.1 201 CREATED
I think all the REST API frameworks let you easily specify XML in the client request and server response. See Restlet's quick start for an example.