Thank you very much! I have one more question: Is it possible to read Form data in a Map using POST method? That is, is there a Message Body Reader that reads the Map is passed in as parameters to the POST method?
Thanks again for your elaborate reply. Sadhana Sadhana Jain Sr. Software Engineer Rovi Corporation 795 Folsom St, Suite 200 San Francisco, CA 94107 Direct: 415.247.5023 | Mobile: 925.212.6495 [email protected] rovicorp.com Rovi. The new name for Macrovision. -----Original Message----- From: Pydipati, Karuna [mailto:[email protected]] Sent: Tuesday, September 15, 2009 12:56 PM To: [email protected]; Sadhana Jain Subject: RE: JAX-RS POST method example Sadhana- I am doing similar to this. You can follow the same, if you wish (I have not tested this. But, I have a running app like this. I quickly customized this to respond to your question. Sergey and other CXF active developers may have more insights) STEP 1: Write some interface like this. You may or may not need @FormParam depending on whether you use it at web or not. I suggest you start first using no @FormParam method first. import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; @Path("/users") @Consumes({"application/json", "application/xml"}) @Produces({"application/json", "application/xml"}) public interface SomeService { @POST @Path("/createuser") @Consumes({"application/x-www-form-urlencoded"}) @Produces({"application/json", "application/xml"}) public User createUser(@FormParam("UserRequest")UserRequest userRequest) ; //Use this first @POST @Path("/createuser") @Consumes({"application/json", "application/xml"}) @Produces({"application/json", "application/xml"}) public User createUser(UserRequest userRequest) ; } STEP 2: Implement the above class for your app. STEP 3:Your cxf-bean.xml may look like this. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd "> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <cxf:bus> <cxf:features> <cxf:logging/> </cxf:features> </cxf:bus> <bean id="someService" class="SomeServiceImpl" /> <jaxrs:server id="restServices" address="/"> <jaxrs:serviceBeans> <ref bean="someService" /> </jaxrs:serviceBeans> </jaxrs:server> </beans> STEP 4 Then your url may look like http://xxx:8080/web-context/users/createuser STEP 5: Always try to see wadl in browser..before testing. You can see wadl like this (you need cxf-2.2.3.jar file) http://xxx:8080/web-context/?_wadl&_type=xml (see a underscore before wadl and type) STEP 6: Then, you can test this using some client as shown below package com.javaclient.testrest; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; public class JavaClientUserAPI { public static void main(String args[]) throws Exception { String fileName = "C:\\\\createuser.txt"; //This is where your will have json content URL url = null; HttpURLConnection httpURLConnection = null; OutputStreamWriter outputStreamWriter = null; try { url = new URL("http://xxx:8080/web-context/users/createuser"); ); httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setRequestMethod("PUT"); httpURLConnection.setDoOutput(true); httpURLConnection.setUseCaches(false); httpURLConnection.setAllowUserInteraction(false); httpURLConnection.setRequestProperty( JavaClientConstant.CONTENT_TYPE, "application/json"); httpURLConnection.setRequestProperty( JavaClientConstant.CONTENT_LANGUAGE, JavaClientConstant.CONTENT_LANGUAGE_VALUE); //httpURLConnection.setRequestProperty("Accept", "application/*"); outputStreamWriter = new OutputStreamWriter(httpURLConnection .getOutputStream()); outputStreamWriter.write(FileReader.readFile(fileName)); outputStreamWriter.flush(); outputStreamWriter.close(); outputStreamWriter = null; InputStream inputStream = null; BufferedReader bufferedReader = null; inputStream = httpURLConnection.getInputStream(); bufferedReader = new BufferedReader(new InputStreamReader( inputStream)); String line; StringBuilder response = new StringBuilder(); while ((line = bufferedReader.readLine()) != null) { response.append(line); response.append('\r'); } System.out.println(response.toString()); bufferedReader.close(); bufferedReader = null; inputStream.close(); inputStream = null; } catch (Exception e) { e.printStackTrace(); } } } Regards Karuna Pydipati StubHub/eBay - Platform & Services Phone: (415)222-8752 Email: [email protected] -----Original Message----- From: Sadhana Jain [mailto:[email protected]] Sent: Tuesday, September 15, 2009 12:25 PM To: [email protected] Subject: RE: JAX-RS POST method example The error I am getting is ".No operation matching request path...." though @POST is there with the @PATH annotation that should match. Thanks. Sadhana Jain Sr. Software Engineer Rovi Corporation 795 Folsom St, Suite 200 San Francisco, CA 94107 Direct: 415.247.5023 | Mobile: 925.212.6495 [email protected] rovicorp.com Rovi. The new name for Macrovision. -----Original Message----- From: Sadhana Jain [mailto:[email protected]] Sent: Tuesday, September 15, 2009 12:16 PM To: [email protected] Subject: JAX-RS POST method example Hi All, I am new to using JAX-RS and CXF. I was wondering if anyone can point me To an example that uses POST method as I am running into a problem when using POST. Cxf is not able to match to request uri to a method annotated with @POST though @GET works ok. Does anyone know a known issue using POST? Any sample code will be great help. Thanks, Sadhana Sadhana Jain Sr. Software Engineer Rovi Corporation 795 Folsom St, Suite 200 San Francisco, CA 94107 Direct: 415.247.5023 | Mobile: 925.212.6495 [email protected] rovicorp.com Rovi. The new name for Macrovision. -----Original Message----- From: Sergey Beryozkin [mailto:[email protected]] Sent: Tuesday, September 15, 2009 9:30 AM To: Pydipati, Karuna; [email protected]; Sergey Beryozkin Subject: Re: CXF -Strange HTTP PUT (REST) behavior Hi, @FormParams can only be used to refer to field values in form submissions, with application/x-www-form-urlencoded (or similar). In your case you just need to remove @FormParam. A given JAXRS method can refer to a request body (sent as part of POST or PUT. etc) by either not annotating a given parameter with JAXRS param annotations, like this : @PUT @Path("{userGuid}/contacts/{contactId}") @Consumes({"application/json", "application/xml"}) @Produces({"application/json", "application/xml"}) public Response updateContact(@PathParam("userGuid")String userGuid, @PathParam("contactId")String contactId, UserContact contact); or by annotating parameters with @FormParam as in your case but note a different @Consumes value : @Consumes("application/x-www-form-urlencoded") @Produces({"application/json", "application/xml"}) public Response updateContact(@PathParam("userGuid")String userGuid, @PathParam("contactId")String contactId, @FormParam UserContact contact); So if you need to your web app to handle both 'plain' requests and form requests (those meeting application/x-www-form-urlencoded rules, name=value pairs) then you need to have both methods as suggested above, otherwise the updated first method will do. cheers, Sergey ----- Original Message ----- From: Pydipati, Karuna To: Sergey Beryozkin ; [email protected] ; Sergey Beryozkin Sent: Tuesday, September 15, 2009 4:40 PM Subject: RE: CXF -Strange HTTP PUT (REST) behavior Thanks a lot Sergey for your quick response. Yes, you right. We have the following method @PUT @Path("{userGuid}/contacts/{contactId}") @Consumes({"application/json", "application/xml"}) @Produces({"application/json", "application/xml"}) public Response updateContact(@PathParam("userGuid")String userGuid, @PathParam("contactId")String contactId, @FormParam("contact")UserContact contact); What you are suggesting is that we should have another method like this @PUT @Path("{userGuid}/contacts/{contactId}") public Response updateContact(@PathParam("userGuid")String userGuid, @PathParam("contactId")String contactId, @FormParam("contact")UserContact contact); My question is...how is it working..if I package in another buy.ear or cog.ear files ....where as it fails userapi.ear? I am still grappling with this puzzle. Pardon my ignorance on @FormParam and Content-type area. Could you elaborate your answer a bit further? Regards Karuna Pydipati StubHub/eBay - Platform & Services Phone: (415)222-8752 Email: [email protected] ------------------------------------------------------------------------ ------ From: Sergey Beryozkin [mailto:[email protected]] Sent: Tuesday, September 15, 2009 2:32 AM To: Pydipati, Karuna; [email protected]; Sergey Beryozkin Subject: Re: CXF -Strange HTTP PUT (REST) behavior Hi What is most likely happening is that you have a method parameter annotated with @FormParam. In that case no message body readers are checked (which would've prevented the NPE) but the runtime checks if its a application/x-www-form-urlencoded request and if not then it assumes straight away it's a mulltipart/form-data request (so this will have to be fixed so that an unsupported media type exception is thrown instead). So you just need to remove @FormParams from the @PUT-annotated method. If you do need to keep @FormParams, then just introduce another method which accepts PUT and application/json (@Consumes) media type hope it helps, Sergey ----- Original Message ----- From: Pydipati, Karuna To: [email protected] ; Sergey Beryozkin Sent: Tuesday, September 15, 2009 6:28 AM Subject: CXF -Strange HTTP PUT (REST) behavior Hi I posted this in a separate thread today. Sorry. After some investigation, I found this. Please help me. I see a strange behavior in HTTP PUT (REST). When I tried CXF-2.2.2 deploying userapi.ear (with "user" as context-root in jboss), it is failing with following error. If I rename same ear file to something else such as cog.ear (with 'cog' as context-root), it started working. Is 'user' a reserve word in HTTP/CXF/REST world? Can't I use "user' word for my application for "Address"? [in my app, cog.ear contains cog.war. Same way, user.ear contains user.war too] 17:28:54,290 ERROR [STDERR] Sep 14, 2009 5:28:54 PM org.apache.cxf.interceptor.LoggingInInterceptor logging INFO: Inbound Message ---------------------------- ID: 3 Address: /userapi/user/users/6E2D6D23D40D2FC9E04400144F8AE084/contacts/2 Encoding: UTF-8 Content-Type: application/json Headers: {content-length=[536], connection=[keep-alive], cache-control=[no-cache], host=[localhost:28080], user-agent=[J ava/1.5.0_14], pragma=[no-cache], Content-Type=[application/json], content-type=[application/json], Accept=[text/html, i mage/gif, image/jpeg, *; q=.2, */*; q=.2], content-language=[en-US]} Payload: { "UserContact": { "ContactId": 111111, "UserId": 11111, "FirstName": "xxxxxx", "LastName": "xxxxxx", "Street": "Sharynne Ln.", "AptNumber": 5350, "City": "Malibu", "State": "CA", "Zip": 90265, "Phone1": "xxxxxxx", "Phone2": "xxxxxxx", "Company": "Ebay", "Email": "[email protected]", "DateAdded": "24-OCT-02", "Active": 1, "Note": "Note", "Fax": "56356", "Country": "US", "DefaultContact": 1, "PaymentContact": 1, "Title":"Mr.", "LastModifiedDate": "10-SEP-09", "ChkPmtToCo": 0 }} -------------------------------------- 17:28:54,290 ERROR [STDERR] Sep 14, 2009 5:28:54 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept INFO: Interceptor has thrown exception, unwinding now java.lang.NullPointerException at org.apache.cxf.attachment.AttachmentUtil.createAttachment(AttachmentUtil .java:136) at org.apache.cxf.jaxrs.ext.MessageContextImpl.createAttachments(MessageCon textImpl.java:135) at org.apache.cxf.jaxrs.ext.MessageContextImpl.get(MessageContextImpl.java: 58) at org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils.getMultipartBody(At tachmentUtils.java:54) at org.apache.cxf.jaxrs.utils.JAXRSUtils.processFormParam(JAXRSUtils.java:5 90) Regards Karuna Pydipati StubHub/eBay - Platform & Services Phone: (415)222-8752 Email: [email protected]
