You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by dilunika <ka...@aepona.com> on 2013/07/08 10:16:51 UTC
Consume "application/x-www-form-urlencoded" Content-Type in REST
Web Service (cxf:rsServer)
Please provide your kind advice to get me solve following problem
My REST web service services have to provide the support for the
content-type "application/x-www-form-urlencoded". So, I have developed my
service as follows.
Contract Definition :
--------------------------
> public class PaymentSandboxService {
>
> @POST
> @Consumes({"application/json", "application/x-www-form-urlencoded"})
> @Produces({"application/json", "application/x-www-form-urlencoded"})
> @Path("/2_1/payment/{endUserId}/transactions/amount")
> public Response charge(@Body
> final AmountTransaction amountTransaction, @PathParam("endUserId")
> final String endUserId) throws IOException {
>
> return null;
> }
> }
Bean Definitions :
-----------------------
> <cxf:rsServer id="rsServer" address="/{{publicAddress}}"
> serviceClass="org.jkd.lrn.PaymentSandboxService"
> loggingFeatureEnabled="true">
> <cxf:providers>
> <ref bean="jsonProvider" />
> <ref bean="formUrlEncodeProvider" />
> </cxf:providers>
> </cxf:rsServer>
> <bean id="jsonProvider"
> class="org.apache.cxf.jaxrs.provider.JSONProvider">
> <property name="marshallAsJaxbElement" value="true" />
> </bean>
>
> <bean id="formUrlEncodeProvider"
> class="org.apache.cxf.jaxrs.provider.FormEncodingProvider" />
When I send a request with Content-Type 'application/json' everything works
fine. But when a request is sent with the Content-Type
'application/x-www-form-urlencoded', request hits the server but it failed
while converting body to the data type AmountTransaction. Following is a
part of log I am getting in fuse.log.
> ID: 17
> Address:
> http://cnb69:8181/cxf/paymentsandbox/2_1/payment/tel:+916309700000/transactions/amount
> Encoding: ISO-8859-1
> Http-Method: POST
> Content-Type: application/x-www-form-urlencoded
> Headers: {Accept=[application/json], accept-encoding=[gzip,deflate],
> Authorization=[Basic a2FzdW5wYXlzYW5kYm94OnBANTV3MHJk],
> connection=[keep-alive], Content-Length=[670],
> content-type=[application/x-www-form-urlencoded], Host=[cnb69:8181],
> User-Agent=[Apache-HttpClient/4.1.1 (java 1.5)]}
> Payload: {
> "amountTransaction": {
> "clientCorrelator": "54321",
> "endUserId": "tel:+916309700000",
> "paymentAmount": {
> "chargingInformation": {
> "amount": "10.2662",
> "currency": "USD",
> "description": [
> "Alien Invaders Game"
> ]
> },
> "chargingMetaData": {
> "onBehalfOf": "Example Games Inc",
> "purchaseCategoryCode": "Game",
> "channel": "SMS",
> "taxAmount": "0"
> }
> },
> "referenceCode": "REF-12345",
> "transactionOperationStatus": "CHARGED"
> }
> }
> --------------------------------------
> 2013-07-05 13:44:27,477 | WARN | qtp1316166688-257 |
> org.apache.cxf.jaxrs.utils.JAXRSUtils | No message body reader has been
> found for request class AmountTransaction, ContentType :
> application/x-www-form-urlencoded.
> 2013-07-05 13:44:27,478 | INFO | qtp1316166688-257 |
> org.apache.cxf.interceptor.AbstractLoggingInterceptor | Outbound Message
> ---------------------------
> ID: 17
> Response-Code: 415
> Content-Type: text/xml
> Headers: {Date=[Fri, 05 Jul 2013 08:14:27 GMT], Content-Length=[0]}
> --------------------------------------
What have I done wrong? Is
"org.apache.cxf.jaxrs.provider.FormEncodingProvider" not the correct
provider for this case? If so, what is the correct way of implementation?
Thanks,
Kasun
--
View this message in context: http://cxf.547215.n5.nabble.com/Consume-application-x-www-form-urlencoded-Content-Type-in-REST-Web-Service-cxf-rsServer-tp5730399.html
Sent from the cxf-user mailing list archive at Nabble.com.
Re: Consume "application/x-www-form-urlencoded" Content-Type in REST
Web Service (cxf:rsServer)
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
Default FormEncodingProvider will not be able to inject a sequence of
name/value pairs into a bean.
So your original idea of sending a JSON payload kind of works, except
that JSONProvider does not understand a form media type.
Let me summarize the options:
- send JSON payload as before, with a form format, and then change a
content-type on a server to 'application/json'
- send JSON payload as before, with a form format, and configure
JSONProvider to accept a form format, see
http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml
(search for a bean named 'jsonProvider', 'consumeMediaTypes' property)
will work in this case, but will affect name/value payloads
- have a Form or MultivaluedMap parameter instead of AmountTransaction
and populate AmountTransaction manually
- have a custom provider (as you suggested)
- use a cxf extension @FormParam("") with AmountTransaction
- use JAX-RS 2.0 @BeanParam and have AmountTransaction properties
annotated with FormParam
Plenty of options :-), hope one of them will work for you
Sergey
On 09/07/13 07:31, dilunika wrote:
> Hi Sergey,
>
> But when I send content with form-url-encoded type, still I am getting the
> same error. Do, I need to implement a un-marshaller to convert body content
> to my Data Structure (AmountTransaction) ?
>
> Part of Log:
> =========
> ID: 17
> Address:
> http://cnb69:8181/cxf/paymentsandbox/2_1/payment/tel:+916309700000/transactions/amount
> Encoding: ISO-8859-1
> Http-Method: POST
> Content-Type: application/x-www-form-urlencoded
> Headers: {Accept=[application/json], accept-encoding=[gzip,deflate],
> Authorization=[Basic a2FzdW5wYXlzYW5kYm94OnBANTV3MHJk],
> connection=[keep-alive], Content-Length=[267],
> content-type=[application/x-www-form-urlencoded], Host=[cnb69:8181],
> User-Agent=[Apache-HttpClient/4.1.1 (java 1.5)]}
> Payload: clientCorrelator=54321&
> endUserId=tel%3A%2B16309700001&
> amount=10.00&
> currency=USD&
> description=Alien%20Invaders%20Game&
> onBehalfOf=Example%20Games%20Inc&
> purchaseCategoryCode=Game&
> channel=SMS&
> taxAmount=0&
> referenceCode=REF-12345&
> transactionOperationStatus=CHARGED
> --------------------------------------
> 2013-07-09 11:45:37,607 | WARN | qtp1025922771-224 |
> org.apache.cxf.jaxrs.utils.JAXRSUtils | No message body reader has been
> found for request class AmountTransaction, ContentType :
> application/x-www-form-urlencoded.
> 2013-07-09 11:45:37,608 | INFO | qtp1025922771-224 |
> org.apache.cxf.interceptor.AbstractLoggingInterceptor | Outbound Message
> ---------------------------
> ID: 17
> Response-Code: 415
> Content-Type: text/xml
> Headers: {Date=[Tue, 09 Jul 2013 06:15:37 GMT], Content-Length=[0]}
> --------------------------------------
>
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Consume-application-x-www-form-urlencoded-Content-Type-in-REST-Web-Service-cxf-rsServer-tp5730399p5730450.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: Consume "application/x-www-form-urlencoded" Content-Type in
REST Web Service (cxf:rsServer)
Posted by dilunika <ka...@aepona.com>.
Hi Sergey,
But when I send content with form-url-encoded type, still I am getting the
same error. Do, I need to implement a un-marshaller to convert body content
to my Data Structure (AmountTransaction) ?
Part of Log:
=========
ID: 17
Address:
http://cnb69:8181/cxf/paymentsandbox/2_1/payment/tel:+916309700000/transactions/amount
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/x-www-form-urlencoded
Headers: {Accept=[application/json], accept-encoding=[gzip,deflate],
Authorization=[Basic a2FzdW5wYXlzYW5kYm94OnBANTV3MHJk],
connection=[keep-alive], Content-Length=[267],
content-type=[application/x-www-form-urlencoded], Host=[cnb69:8181],
User-Agent=[Apache-HttpClient/4.1.1 (java 1.5)]}
Payload: clientCorrelator=54321&
endUserId=tel%3A%2B16309700001&
amount=10.00&
currency=USD&
description=Alien%20Invaders%20Game&
onBehalfOf=Example%20Games%20Inc&
purchaseCategoryCode=Game&
channel=SMS&
taxAmount=0&
referenceCode=REF-12345&
transactionOperationStatus=CHARGED
--------------------------------------
2013-07-09 11:45:37,607 | WARN | qtp1025922771-224 |
org.apache.cxf.jaxrs.utils.JAXRSUtils | No message body reader has been
found for request class AmountTransaction, ContentType :
application/x-www-form-urlencoded.
2013-07-09 11:45:37,608 | INFO | qtp1025922771-224 |
org.apache.cxf.interceptor.AbstractLoggingInterceptor | Outbound Message
---------------------------
ID: 17
Response-Code: 415
Content-Type: text/xml
Headers: {Date=[Tue, 09 Jul 2013 06:15:37 GMT], Content-Length=[0]}
--------------------------------------
--
View this message in context: http://cxf.547215.n5.nabble.com/Consume-application-x-www-form-urlencoded-Content-Type-in-REST-Web-Service-cxf-rsServer-tp5730399p5730450.html
Sent from the cxf-user mailing list archive at Nabble.com.
Re: Consume "application/x-www-form-urlencoded" Content-Type in
REST Web Service (cxf:rsServer)
Posted by dilunika <ka...@aepona.com>.
Thanks Sergey. It solved my problem.
--
View this message in context: http://cxf.547215.n5.nabble.com/Consume-application-x-www-form-urlencoded-Content-Type-in-REST-Web-Service-cxf-rsServer-tp5730399p5730446.html
Sent from the cxf-user mailing list archive at Nabble.com.
Re: Consume "application/x-www-form-urlencoded" Content-Type in REST
Web Service (cxf:rsServer)
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
Looks like you post a JSON sequence, but use a form media type, and the
form provider expects a sequence of name/value pairs.
I guess what you need is still use the JSON provider to read this
payload. Assuming you can not change the content type at the client side
(it's a form, etc), then you can try:
- add a _ctype query parameter to a request uri, example: /?_ctype=json
- if on CXF 2.7.x - add pre-match ContainerRequestFilter and update a
content type there, otherwise register a CXF interceptor and do
'message.put(Message.CONTENT_TYPE, ""application/json)'
Sergey
On 08/07/13 09:16, dilunika wrote:
> Please provide your kind advice to get me solve following problem
>
> My REST web service services have to provide the support for the
> content-type "application/x-www-form-urlencoded". So, I have developed my
> service as follows.
>
> Contract Definition :
> --------------------------
>> public class PaymentSandboxService {
>>
>> @POST
>> @Consumes({"application/json", "application/x-www-form-urlencoded"})
>> @Produces({"application/json", "application/x-www-form-urlencoded"})
>> @Path("/2_1/payment/{endUserId}/transactions/amount")
>> public Response charge(@Body
>> final AmountTransaction amountTransaction, @PathParam("endUserId")
>> final String endUserId) throws IOException {
>>
>> return null;
>> }
>> }
> Bean Definitions :
> -----------------------
>> <cxf:rsServer id="rsServer" address="/{{publicAddress}}"
>> serviceClass="org.jkd.lrn.PaymentSandboxService"
>> loggingFeatureEnabled="true">
>> <cxf:providers>
>> <ref bean="jsonProvider" />
>> <ref bean="formUrlEncodeProvider" />
>> </cxf:providers>
>> </cxf:rsServer>
>> <bean id="jsonProvider"
>> class="org.apache.cxf.jaxrs.provider.JSONProvider">
>> <property name="marshallAsJaxbElement" value="true" />
>> </bean>
>>
>> <bean id="formUrlEncodeProvider"
>> class="org.apache.cxf.jaxrs.provider.FormEncodingProvider" />
>
> When I send a request with Content-Type 'application/json' everything works
> fine. But when a request is sent with the Content-Type
> 'application/x-www-form-urlencoded', request hits the server but it failed
> while converting body to the data type AmountTransaction. Following is a
> part of log I am getting in fuse.log.
>
>> ID: 17
>> Address:
>> http://cnb69:8181/cxf/paymentsandbox/2_1/payment/tel:+916309700000/transactions/amount
>> Encoding: ISO-8859-1
>> Http-Method: POST
>> Content-Type: application/x-www-form-urlencoded
>> Headers: {Accept=[application/json], accept-encoding=[gzip,deflate],
>> Authorization=[Basic a2FzdW5wYXlzYW5kYm94OnBANTV3MHJk],
>> connection=[keep-alive], Content-Length=[670],
>> content-type=[application/x-www-form-urlencoded], Host=[cnb69:8181],
>> User-Agent=[Apache-HttpClient/4.1.1 (java 1.5)]}
>> Payload: {
>> "amountTransaction": {
>> "clientCorrelator": "54321",
>> "endUserId": "tel:+916309700000",
>> "paymentAmount": {
>> "chargingInformation": {
>> "amount": "10.2662",
>> "currency": "USD",
>> "description": [
>> "Alien Invaders Game"
>> ]
>> },
>> "chargingMetaData": {
>> "onBehalfOf": "Example Games Inc",
>> "purchaseCategoryCode": "Game",
>> "channel": "SMS",
>> "taxAmount": "0"
>> }
>> },
>> "referenceCode": "REF-12345",
>> "transactionOperationStatus": "CHARGED"
>> }
>> }
>> --------------------------------------
>> 2013-07-05 13:44:27,477 | WARN | qtp1316166688-257 |
>> org.apache.cxf.jaxrs.utils.JAXRSUtils | No message body reader has been
>> found for request class AmountTransaction, ContentType :
>> application/x-www-form-urlencoded.
>> 2013-07-05 13:44:27,478 | INFO | qtp1316166688-257 |
>> org.apache.cxf.interceptor.AbstractLoggingInterceptor | Outbound Message
>> ---------------------------
>> ID: 17
>> Response-Code: 415
>> Content-Type: text/xml
>> Headers: {Date=[Fri, 05 Jul 2013 08:14:27 GMT], Content-Length=[0]}
>> --------------------------------------
>
> What have I done wrong? Is
> "org.apache.cxf.jaxrs.provider.FormEncodingProvider" not the correct
> provider for this case? If so, what is the correct way of implementation?
>
> Thanks,
> Kasun
>
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Consume-application-x-www-form-urlencoded-Content-Type-in-REST-Web-Service-cxf-rsServer-tp5730399.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