You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Sergey Beryozkin <se...@iona.com> on 2009/09/16 11:06:52 UTC

RE: JAX-RS POST method example

Hi

Thanks a lot for posting this step-by-step sequence, our documentation does
need to have something like this ! 

note that you might also want to use CXF Client API for testing the endpoint
:

http://cxf.apache.org/docs/jax-rs.html#JAX-RS-ClientAPI

Sadhana - so do you still have a no match issue ? Can you post some more
info : a test/sample class just with a method which can not be matched,
request URI, jaxrs:server/@address value, name of the web app, CXF Servlet
url pattern value....

cheers, Sergey


Pydipati, Karuna wrote:
> 
> 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: kpydipati@ebay.com
> 
>  
> 
> 
> -----Original Message-----
> From: Sadhana Jain [mailto:Sadhana.Jain@rovicorp.com] 
> Sent: Tuesday, September 15, 2009 12:25 PM
> To: users@cxf.apache.org
> 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 sadhana.jain@rovicorp.com
> rovicorp.com
> 
> 
> Rovi. The new name for Macrovision.
> 
> 
> -----Original Message-----
> From: Sadhana Jain [mailto:Sadhana.Jain@rovicorp.com]
> Sent: Tuesday, September 15, 2009 12:16 PM
> To: users@cxf.apache.org
> 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 sadhana.jain@rovicorp.com
> rovicorp.com
> 
> 
> Rovi. The new name for Macrovision.
> 
> 
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozk@progress.com]
> Sent: Tuesday, September 15, 2009 9:30 AM
> To: Pydipati, Karuna; users@cxf.apache.org; 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 ; users@cxf.apache.org ; 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: kpydipati@ebay.com
> 
> 
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> ------
>   From: Sergey Beryozkin [mailto:sberyozk@progress.com]
>   Sent: Tuesday, September 15, 2009 2:32 AM
>   To: Pydipati, Karuna; users@cxf.apache.org; 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: users@cxf.apache.org ; 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": "xxxx@xxxx.com", "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: kpydipati@ebay.com
> 
> 
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/CXF--Strange-HTTP-PUT-%28REST%29-behavior-tp25448003p25468621.html
Sent from the cxf-user mailing list archive at Nabble.com.