Previously (in Play 2.1.3) we were always able to call:
request().body().asRaw()
to access the request body content regardless of what the content type was
set to.
As of Play 2.2.1, request().body().asRaw() returns null if a content type
that Play recognizes is set. For example, if the content type header is set
to "application/xml", anything other than a call to
request().body().asXml() fails. The problem here is that this removes the
ability for us to handle raw requests if the content type is wrong or if it
is otherwise malformed. It seems that the original behavior of always
allowing request().body().asRaw() is a better behavior because it allows us
to parse requests that Play fails to handle.
Another problem is that, it forces us to have to use the Play default
parsers for any content type that Play recognizes in a fairly painful way.
For example, if we want to implement a method that accepts multiple
encoding types, we have to do a bunch asJson(), asText(), asXml(), ... and
null check each one every time rather than just handling it as raw.
Here's another scenario that is now broken for us:
In some situations, we need to "forward" a request that we receive to
another endpoint. Redirects are not allowed. We receive this request as an
XML POST (content type of application/xml) in one of our controller
methods. Now, when we receive such a request, what we used to do was get
the body using asRaw() and then make a new request using that body's
content. Unfortunately now we are forced to use asXml(). The problem is,
either the XML is malformed or the Play XML parser just... well... sucks
because we have not found any way that allows us to access full request
body (i.e. the raw XML data as a String). Caling
request().body().asXml().toString() or
request().body().asXml().getTextContent() doesn't give us this content and
no other methods seem applicable.
Following the documentation (
http://www.playframework.com/documentation/2.2.x/JavaBodyParsers), I have
attempted several workarounds such as:
@BodyParser.Of(BodyParser.AnyContent.class)
public static Result foo() {
String[] type = request().headers().get("Content-Type");
logger.info("type[{}]", type[0]);
AnyContent body = request().body().as(BodyParser.AnyContent.class);
logger.info("request[{}]", body); // outputs request[null]
return ok();
All workarounds are to no avail and Play will not let us use anything other
than it's default body parser.
Play is being too helpful and is now getting in the way by restricting us
from accessing some fundamental properties of HTTP request/responses. I
don't see why we can't have the asJson() etc... functionality be an
optional helper rather than the required method for accepting request body
content.
request().body().asRaw()
to access the request body content regardless of what the content type was
set to.
As of Play 2.2.1, request().body().asRaw() returns null if a content type
that Play recognizes is set. For example, if the content type header is set
to "application/xml", anything other than a call to
request().body().asXml() fails. The problem here is that this removes the
ability for us to handle raw requests if the content type is wrong or if it
is otherwise malformed. It seems that the original behavior of always
allowing request().body().asRaw() is a better behavior because it allows us
to parse requests that Play fails to handle.
Another problem is that, it forces us to have to use the Play default
parsers for any content type that Play recognizes in a fairly painful way.
For example, if we want to implement a method that accepts multiple
encoding types, we have to do a bunch asJson(), asText(), asXml(), ... and
null check each one every time rather than just handling it as raw.
Here's another scenario that is now broken for us:
In some situations, we need to "forward" a request that we receive to
another endpoint. Redirects are not allowed. We receive this request as an
XML POST (content type of application/xml) in one of our controller
methods. Now, when we receive such a request, what we used to do was get
the body using asRaw() and then make a new request using that body's
content. Unfortunately now we are forced to use asXml(). The problem is,
either the XML is malformed or the Play XML parser just... well... sucks
because we have not found any way that allows us to access full request
body (i.e. the raw XML data as a String). Caling
request().body().asXml().toString() or
request().body().asXml().getTextContent() doesn't give us this content and
no other methods seem applicable.
Following the documentation (
http://www.playframework.com/documentation/2.2.x/JavaBodyParsers), I have
attempted several workarounds such as:
@BodyParser.Of(BodyParser.AnyContent.class)
public static Result foo() {
String[] type = request().headers().get("Content-Type");
logger.info("type[{}]", type[0]);
AnyContent body = request().body().as(BodyParser.AnyContent.class);
logger.info("request[{}]", body); // outputs request[null]
return ok();
All workarounds are to no avail and Play will not let us use anything other
than it's default body parser.
Play is being too helpful and is now getting in the way by restricting us
from accessing some fundamental properties of HTTP request/responses. I
don't see why we can't have the asJson() etc... functionality be an
optional helper rather than the required method for accepting request body
content.