Hi Andrei
Indeed there were problems reported before due to the filters (Spring
security, etc) consuming the body and thus JAX-RS form parameters
becoming empty, and that was the reason for the quoted spec update.
You are right it makes sense to optionally disable using query
parameters to populate the form maps if some users find it misleading,
though I'd still keep by default.
I guess populateMapFromString can be updated to check a new contextual
property on JAXRSUtils.getCurrentMessage()
Thanks, Sergey
On 28/06/15 16:02, Andrei Shakirin wrote:
Hi,
See answers below:
-----Original Message-----
From: Валерия Головина [mailto:[email protected]]
Sent: Freitag, 26. Juni 2015 20:15
To: [email protected]
Subject: Small problems with x-www-form-urlencoded requests
Hello.
There is a couple of small problems with x-www-form-urlencoded requests in
CXF 3.1.0.
CXF doesn't make any difference between query and form parameters if
request content type is "application/x-www-form-urlencoded".
My service looks like this
@POST
@Path(/signin)
@Consumes("application/x-www-form-urlencoded")
public Details signIn(
@FormParam("login") String login,
@FormParam("password") String password) { ...
}
and it can be invoked by two kinds of requests:
1) with "application/x-www-form-urlencoded" content type and form
paramaters in request body (as expected)
2) with "application/x-www-form-urlencoded" content type and URL
parameters
(/signin?login=...&password=...)
So if you use URL parameters instead of Form the service still responds.
I'm not sure that it is a bug, but it's kind of unexpected behavior for me.
Or maybe I did something wrong.
In this two cases the parameters are brought from request.parameterMap.
This field contains both query and form parameters.
(see org.apache.cxf.jaxrs.utils.FormUtils : method populateMapFromString(...,
javax.servlet.http.HttpServletRequest request))
I think the behaviour is defined in this way in JAX-RS spec (Servlet Container
section):
"Servlet filters may trigger consumption of a request body by accessing request
parameters. In a servlet
container the @FormParam annotation and the standard entity provider for
application/x-www-form--
urlencoded MUST obtain their values from the servlet request parameters if the
request body has already
been consumed. Servlet APIs do not differentiate between parameters in the URI
and body of a request so
URI-based query parameters may be included in the entity parameter."
I see that Jersey has an option to forbid this behaviour:
https://java.net/jira/browse/JERSEY-2756 .
@Sergei: do you think we can introduce such option in CXF?
There is also a minor problem with logging: LoggingInInterceptor (and
LoggingOutInterceptor too) doesn't log any data about form parameters of a
request. This parameters are valuable so it can cause some inconvenience.
Hmm ... normally form parameters are logged as message payload in
LoggingInInterceptor/LoggingOutInterceptor interceptors.
For instance, this request:
"POST /customerservice/customers HTTP/1.1
Accept: text/xml
User-Agent: Jakarta Commons-HttpClient/3.1
Host: 127.0.0.1:9001
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
status=open"
is logged as :
ID: 9
Address: http://localhost:9000/customerservice/customers
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/x-www-form-urlencoded
Headers: {Accept=[text/xml], Content-Length=[11],
content-type=[application/x-www-form-urlencoded], Host=[localhost:9000],
User-Agent=[Jakarta Commons-HttpClient/3.1]}
Payload: status=open
Could that be the case that entity body of your request was consumed by custom
servlet filters?
Regards,
Andrei.
Thanks
--
Valeria Golovina