You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by dahanhsi <da...@gmail.com> on 2012/10/23 09:21:15 UTC
How to get request body with "application/x-form-urlencoded"
content-header set
We develop a REST service implemtented in Apache CXF for our client exposed
like this:
@PUT
@Path("/process")
public void doProcess(@PathParam("para") String para, String reqBody,
@Context MessageContext context);
The request body is a XML document, and doProcess() will unmarshall the
reqBody String to object itself.
When the request does not set Content-Type header or set Content-Type header
to "application/xml", all this works great. I can get reqBody in
doProcess()
The problem is that the client is not setting the right content-type header
(should be "application/xml" but client sets
"application/x-form-urlencoded").
When request content-type header is "application/x-form-urlencoded", I can
not get reqBody in doProcess() (It's null)
Any ideas?
Regards,
Mark
--
View this message in context: http://cxf.547215.n5.nabble.com/How-to-get-request-body-with-application-x-form-urlencoded-content-header-set-tp5717220.html
Sent from the cxf-user mailing list archive at Nabble.com.
Re: How to get request body with "application/x-form-urlencoded"
content-header set
Posted by Sergey Beryozkin <sb...@gmail.com>.
On 25/10/12 13:30, dahanhsi wrote:
> Sergey Beryozkin-5 wrote
>> On 25/10/12 04:50, dahanhsi wrote:
>>> hi Sergey,
>>>
>>> by following your advice, I added the code below in doProcess() and
>>> finally
>>> got the request body:
>>>
>>> HttpServletRequest request = context.getHttpServletRequest();
>>> Enumeration pNames = request.getParameterNames();
>>> while(pNames.hasMoreElements()){
>>> String name=(String)pNames.nextElement();
>>> String value=servletRequest.getParameter(name);
>>> System.out.println(name + "=" + value);
>>> }
>>>
>>>
>>> But in my another restful operation:
>>> @PUT
>>> @Path("/upload")
>>> public void doUpload(... @Context MessageContext context ...){
>>> ...
>>> HttpServletRequest request = context.getHttpServletRequest();
>>> inputStream = servletRequest.getInputStream();
>>> ...
>>> }
>>>
>>> I also encounter the same problem, and can not write request body from
>>> inputstream.
>>> Client may upload a big file, and exhaust JVM memory if I use above
>>> solution.
>>> How can I fix it?
>>>
>> Calling servletRequest.getInputStream() does not read it into memory, so
>> you can read the stream and save the chunks of the data as needed.
>> Also consider consuming multipart/form-data or similar, CXF will save
>> the data to the temp storage if needed.
>>
>> Sergey
>
> I know that inputStream does not read entire body into memory.
>
> When the request hit my servlet
> ===
> PUT /upload HTTP/1.1
> Host: myhost.com
> Content-Length: length
> Content-Type: application/x-form-urlencoded
> Date: date
>
> {big file in body}
> ===
>
> Because content-type is application/x-form-urlencoded, I can not read
> correct body from request.getInputStream in doUpload(). I also can not read
> it from request.getParameterNames(), because it means that the entire body
> is wrote into memory.
>
This is why I mentioned multipart/form-data - this will prevent the
servlet container from trying to read the stream into the body (note CXF
can not control/prevent it) and will also lead to managing the big data
effectively
Sergey
>
>
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/How-to-get-request-body-with-application-x-form-urlencoded-content-header-set-tp5717220p5717403.html
> Sent from the cxf-user mailing list archive at Nabble.com.
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: How to get request body with "application/x-form-urlencoded"
content-header set
Posted by dahanhsi <da...@gmail.com>.
Sergey Beryozkin-5 wrote
> On 25/10/12 04:50, dahanhsi wrote:
>> hi Sergey,
>>
>> by following your advice, I added the code below in doProcess() and
>> finally
>> got the request body:
>>
>> HttpServletRequest request = context.getHttpServletRequest();
>> Enumeration pNames = request.getParameterNames();
>> while(pNames.hasMoreElements()){
>> String name=(String)pNames.nextElement();
>> String value=servletRequest.getParameter(name);
>> System.out.println(name + "=" + value);
>> }
>>
>>
>> But in my another restful operation:
>> @PUT
>> @Path("/upload")
>> public void doUpload(... @Context MessageContext context ...){
>> ...
>> HttpServletRequest request = context.getHttpServletRequest();
>> inputStream = servletRequest.getInputStream();
>> ...
>> }
>>
>> I also encounter the same problem, and can not write request body from
>> inputstream.
>> Client may upload a big file, and exhaust JVM memory if I use above
>> solution.
>> How can I fix it?
>>
> Calling servletRequest.getInputStream() does not read it into memory, so
> you can read the stream and save the chunks of the data as needed.
> Also consider consuming multipart/form-data or similar, CXF will save
> the data to the temp storage if needed.
>
> Sergey
I know that inputStream does not read entire body into memory.
When the request hit my servlet
===
PUT /upload HTTP/1.1
Host: myhost.com
Content-Length: length
Content-Type: application/x-form-urlencoded
Date: date
{big file in body}
===
Because content-type is application/x-form-urlencoded, I can not read
correct body from request.getInputStream in doUpload(). I also can not read
it from request.getParameterNames(), because it means that the entire body
is wrote into memory.
--
View this message in context: http://cxf.547215.n5.nabble.com/How-to-get-request-body-with-application-x-form-urlencoded-content-header-set-tp5717220p5717403.html
Sent from the cxf-user mailing list archive at Nabble.com.
Re: How to get request body with "application/x-form-urlencoded"
content-header set
Posted by Sergey Beryozkin <sb...@gmail.com>.
On 25/10/12 04:50, dahanhsi wrote:
> hi Sergey,
>
> by following your advice, I added the code below in doProcess() and finally
> got the request body:
>
> HttpServletRequest request = context.getHttpServletRequest();
> Enumeration pNames = request.getParameterNames();
> while(pNames.hasMoreElements()){
> String name=(String)pNames.nextElement();
> String value=servletRequest.getParameter(name);
> System.out.println(name + "=" + value);
> }
>
>
> But in my another restful operation:
> @PUT
> @Path("/upload")
> public void doUpload(... @Context MessageContext context ...){
> ...
> HttpServletRequest request = context.getHttpServletRequest();
> inputStream = servletRequest.getInputStream();
> ...
> }
>
> I also encounter the same problem, and can not write request body from
> inputstream.
> Client may upload a big file, and exhaust JVM memory if I use above
> solution.
> How can I fix it?
>
Calling servletRequest.getInputStream() does not read it into memory, so
you can read the stream and save the chunks of the data as needed.
Also consider consuming multipart/form-data or similar, CXF will save
the data to the temp storage if needed.
Sergey
> thank you for your help!
>
>
>
>
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/How-to-get-request-body-with-application-x-form-urlencoded-content-header-set-tp5717220p5717375.html
> Sent from the cxf-user mailing list archive at Nabble.com.
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: How to get request body with "application/x-form-urlencoded"
content-header set
Posted by dahanhsi <da...@gmail.com>.
hi Sergey,
by following your advice, I added the code below in doProcess() and finally
got the request body:
HttpServletRequest request = context.getHttpServletRequest();
Enumeration pNames = request.getParameterNames();
while(pNames.hasMoreElements()){
String name=(String)pNames.nextElement();
String value=servletRequest.getParameter(name);
System.out.println(name + "=" + value);
}
But in my another restful operation:
@PUT
@Path("/upload")
public void doUpload(... @Context MessageContext context ...){
...
HttpServletRequest request = context.getHttpServletRequest();
inputStream = servletRequest.getInputStream();
...
}
I also encounter the same problem, and can not write request body from
inputstream.
Client may upload a big file, and exhaust JVM memory if I use above
solution.
How can I fix it?
thank you for your help!
--
View this message in context: http://cxf.547215.n5.nabble.com/How-to-get-request-body-with-application-x-form-urlencoded-content-header-set-tp5717220p5717375.html
Sent from the cxf-user mailing list archive at Nabble.com.
Re: How to get request body with "application/x-form-urlencoded"
content-header set
Posted by Sergey Beryozkin <sb...@gmail.com>.
On 23/10/12 12:56, dahanhsi wrote:
> Hi,
> thank you for your reply,
>
> My request is HTTP PUT request with a XML document in it's body, just like
> example bellow:
> ===
> PUT /process HTTP/1.1
> Host: myhost.com
> Content-Length: length
> Content-Type: application/x-form-urlencoded (added by client lib)
> Date: date
>
> <myXmlDocument>
> <myElement>myValue</myElement>
> </myXmlDocument>
> ===
>
> so the request has a XML payload, and has no form payload.
>
> My question is,
> When the Content-Type value is "application/xml" or other values except
> "application/x-form-urlencoded",
> I can get the XML String from reqBody in doProcess().
>
> When the Content-Type value is "application/x-form-urlencoded", I can not
> get the XML String, and reqBody is null. Why?
>
> How to get reqBody when Content-Type is "application/x-form-urlencoded"?
Please refer to my previous message. I think you get 'null' because the
message body is consumed in this case at the servlet level, therefore I
recommend you to introduce a dedicated method for getting the form
payloads properly - to be honest I'm not sure that will work either
given that it is XML after all, not a proper form payload.
So, as the first step, lets explore why you get "null". The method
expects String so as I said, all the String provider does is reads the
input stream, no matter what content-type is there, you get null,
therefore the body is empty already. Now, you can inject
HttpServletRequest (as @Context) and if 'String' method parameter
is null then check
request.getParameterNames()
Perhaps you should return 400 or 415 for this case
Sergey
>
> thanks!
>
>
>
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/How-to-get-request-body-with-application-x-form-urlencoded-content-header-set-tp5717220p5717243.html
> Sent from the cxf-user mailing list archive at Nabble.com.
Re: How to get request body with "application/x-form-urlencoded"
content-header set
Posted by dahanhsi <da...@gmail.com>.
Hi,
thank you for your reply,
My request is HTTP PUT request with a XML document in it's body, just like
example bellow:
===
PUT /process HTTP/1.1
Host: myhost.com
Content-Length: length
Content-Type: application/x-form-urlencoded (added by client lib)
Date: date
<myXmlDocument>
<myElement>myValue</myElement>
</myXmlDocument>
===
so the request has a XML payload, and has no form payload.
My question is,
When the Content-Type value is "application/xml" or other values except
"application/x-form-urlencoded",
I can get the XML String from reqBody in doProcess().
When the Content-Type value is "application/x-form-urlencoded", I can not
get the XML String, and reqBody is null. Why?
How to get reqBody when Content-Type is "application/x-form-urlencoded"?
thanks!
--
View this message in context: http://cxf.547215.n5.nabble.com/How-to-get-request-body-with-application-x-form-urlencoded-content-header-set-tp5717220p5717243.html
Sent from the cxf-user mailing list archive at Nabble.com.
Re: How to get request body with "application/x-form-urlencoded"
content-header set
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
On 23/10/12 08:21, dahanhsi wrote:
> We develop a REST service implemtented in Apache CXF for our client exposed
> like this:
>
> @PUT
> @Path("/process")
> public void doProcess(@PathParam("para") String para, String reqBody,
> @Context MessageContext context);
>
> The request body is a XML document, and doProcess() will unmarshall the
> reqBody String to object itself.
>
> When the request does not set Content-Type header or set Content-Type header
> to "application/xml", all this works great. I can get reqBody in
> doProcess()
>
> The problem is that the client is not setting the right content-type header
> (should be "application/xml" but client sets
> "application/x-form-urlencoded").
>
> When request content-type header is "application/x-form-urlencoded", I can
> not get reqBody in doProcess() (It's null)
>
> Any ideas?
>
I can only think of the form parameters being 'pushed' into
HttpServletRequest parameters/attributes which can happen sometimes at
the servlet level, say, by spring security filters. When a form provider
is used (ex, when @FormParam or MultivaluedMap parameter is available in
the signature), it checks servlet request object if the input stream is
empty. But when you have 'String' - a single attempt by a String
provider to read the input stream is all what is done.
Try adding a method dedicated to consuming form payloads
Cheers, Sergey
> Regards,
> Mark
>
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/How-to-get-request-body-with-application-x-form-urlencoded-content-header-set-tp5717220.html
> Sent from the cxf-user mailing list archive at Nabble.com.
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com