Hi,
I did a bit of additional research, implemented the Web Forms 2.0
standalone as an Servlet Filter and have come to following conclusions:
- WebForms 2.0 and (XML, JSON, ATOM) need to be treated differently,
as only Web Forms 2.0 can have Attachments, and only Web Forms 2.0 can
have attachments
- This is why I would implement Web Forms 2.0 at
org.apache.sling.engine.impl.parameters.ParameterSupport (patch will
follow)
- using :import for XML, JSON, ATOM is a good idea, but we have to
make sure it will also work if there are no parameters, only a request
body.
the main advantage of this approach is that you can still use the Web
Forms 2.0 parameters in your own servlets and scripts transparently.
For the output handling of the PostServlet, I am still fond of the
idea of having multiple OutputBuilders that would allow for all kinds
of responses, HTML+Table, HTML+JSON-in-textarea, pure JSON, pure XML,
pure ATOM.
regards,
Lars
On May 25, 2008, at 8:04 , Felix Meschberger wrote:
Hi,
Am Freitag, den 23.05.2008, 12:05 -0400 schrieb Lars Trieloff:
Hi,
I am planning to add support for additional content types to the
SlingPostServlet that would allow processing Web Forms 2.0, JSON
(allowing an effective-round-tripping from Sling.js), XML (in JCR
document notation), ATOM (in terms of the Atom publishing protocol).
As I said in another mail, we might want to separate support for
multiple transfer formats for operation feeding from the ":import"
operation stipulated by the roundtripping of JSON (and XML) exports
--
maybe not. Let's see below
To do this I would like to propose a small API change: extracting a
ResponseBuilder interface from our current HtmlResponse and renaming
HtmlResponse subsequently to HtmlResponseBuilder. This would allow us
to create a doPost method that would start like this (I think we
should OSGi-ify this later to make content type handling pluggable)
protected void doPost(SlingHttpServletRequest request,
SlingHttpServletResponse response) throws IOException {
log.info("content-type: " + request.getContentType());
String responseType;
//try to determine the request content type and set the response
accordingly. Ordinary
//web forms (multipart/form-data or application/x-www-form-
urlencoded) are getting HTML
//response
if (request.getContentType().equals("application/x-www-form
+xml")) {
responseType = "application/x-www-form+xml";
//TODO: handle Web Forms 2.0 POST
} else if (request.getContentType().equals("application/json")||
request.getContentType().equals("text/x-json")) {
responseType = "application/json";
//TODO: handle JSON POST
} else if (request.getContentType().equals("text/xml")) {
responseType = "text/xml";
//TODO: handle XML POST
} else if (request.getContentType().equals("application/atom
+xml")) {
responseType = "application/atom+xml";
//TODO: handle Atom POST
} else {
responseType = "text/html";
}
//check for user-specified override of response type
if (request.getHeader("Accept")!
=null&&request.getHeader("Accept").length()!=0) {
responseType = request.getHeader("Accept");
}
ResponseBuilder responseBuilder;
if (responseType.equals("application/json")) {
responseBuilder = new JsonResponseBuilder();
} else if (responseType.equals("application/x-www-form+xml")) {
responseBuilder = new WebForms20ResponseBuilder();
} else if (responseType.equals("text/xml")) {
responseBuilder = new XmlResponseBuilder();
} else if (responseType.equals("application/atom+xml")) {
responseBuilder = new AppResponseBuilder();
} else {
responseBuilder = new HtmlResponseBuilder();
}
the general idea is not to break the current API, so that
HtmlResponse
stays the default, but that users sending a JSON request will get a
JSON response, unless they explicitly request a different
responseType
using the Accept header.
If this sounds good to you, I would go on by writing the Web Forms
2.0
part first and submitting a patch (on Youtube) including the proposed
API changes.
I think, this sounds interesting -- and I would make it configurable
right from the start. What you are proposing is, that we properly
separate the request data parsing and response data generation from
the
actual processing.
<thinking_loudly>
We would have an input processor selected by the request content type
and defaulting to plain old request parameter support as available
through SlingHttpServletRequest.getParameter (e.a.). The input
processor
would also provide the ResponseBuilder.
Processing would be along these lines:
InputProcessor ip = getInputProcessor(request);
if (ip == null) {
ip = httpInputProcessor;
}
String operation = ip.getOperation();
Operation op = getOperation(operation);
op.execute(ip.getRequestParameters(), ip.getResponseBuilder());
ip.getResponseBuilder.send();
That is the InputProcessor would provide the input data as abstract
parameters for the operations to uniformly access them.
The operations would the operate solely on the parameters and write
back
response data to the ResponseBuilder.
</thinking_loudly>
Now, looking at this mechanism, the ":import" operation being built by
Paul Noden could in fact just be a InputProcessor for JSON (or
whatever
format). In this respect :import is just a content creation/
modification
operation [which in fact it is to a certain extent].
Regards
Felix
regards,
Lars