You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by krizsan <iv...@mailhaven.com> on 2008/09/17 16:38:33 UTC

UriInfo object in Sub-Resource

Hello!
I have spent some days trying to figure out how to get sub-resources working
as I want them to to no avail. I want every resource, including
sub-resources, to contain an attribute which value is the URI of the
resource.

I have an example program where a User can be associated (one-way) to zero
or more Roles.
Consequently, I have an UserResource and a RoleResource.
To retrieve the data of a specific user, I use
http://localhost:8080/CXF_REST_Webservice/users/2/
To list the roles of the same user, I would use
http://localhost:8080/GWT_REST_Webservice/users/2/roles/
So, in my UserResource class, I have a method that is to retrieve the roles
of a user:
(annotations copied from the interface to condense things)

@WebService
@Path("/users/")
@ProduceMime({"application/xml", "application/json"})
public class UserResourceImpl implements UserResource
{
    // A lot of other stuff...

    @Path("{id}/roles/")
    public RoleResource getUserRoles(
        @PathParam("id") final Long inUserId,
        @QueryParam("expandLevel") @DefaultValue("1") final int
inExpandLevel)
        throws UserNotFoundFault
    {
        /* The RoleResource is injected into the UserResource by Spring. */
        return mRoleResource;
    }
}

Both the UserResource and the RoleResource have an instance variable of the
type UriInfo, which is annotated with the @Context annotation. The problem
that occurs is that the UriInfo in the RoleResource returned from the above
method is empty, that is, calling getAbsolutePath() on the UriInfo fails
with a NullPointerException.
When retrieving role resources directly, using an URI like
http://localhost:8080/CXF_REST_Webservice/roles/2, the UriInfo object is not
empty and the call to getAbsolutePath() causes no problems.

One place I suspect I have made a mistake is in the application context file
for the services:
...
    <jaxrs:server id="CXF_REST_Service" address="/">
        <jaxrs:serviceBeans>
            <ref bean="userServiceBean" />
            <ref bean="roleServiceBean" />
        </jaxrs:serviceBeans>
    </jaxrs:server>
...

I tried to run the code on Jersey, the reference implementation of JSR-311,
and there, the UriInfo objects in the UserResource and the RoleResource were
correctly set. There were, however, other problems with Jersey that makes me
prefer CXF, if I only can get the above problem solved.
Many thanks for all the effort people put into CXF and for any help I might
receive!

-- 
View this message in context: http://www.nabble.com/UriInfo-object-in-Sub-Resource-tp19533573p19533573.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: UriInfo object in Sub-Resource

Posted by krizsan <iv...@mailhaven.com>.
Dear list,
Please ignore my previous message, I found the cause to the exception and it
is mine and all mine.
The conclusion is that moving the UriInfo injection to parameter of methods
works very well and the sub-resource also receives an UriInfo. This way I
also have two resource classes that can act as either parent-resources or
sub-resource.
-- 
View this message in context: http://www.nabble.com/UriInfo-object-in-Sub-Resource-tp19533573p19545412.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: UriInfo object in Sub-Resource

Posted by krizsan <iv...@mailhaven.com>.

Sergey Beryozkin wrote:
> 
> The only JAX-RS standard way to get UriInfo (or any other @Context
> annotated) values into subresources is to inject them as method parameters
> :
> ...
> Perhaps we'll need to come up with some sort of CXF-private subresource
> injection technique - Jersey does some tricks in this regard I believe.
> 

Thank for the very fast reply!
First some words on CXF-private sub-resource injection: Personally, I
usually do not advocate solutions that deviate from standards.

Second, to my problem: I tried to move the UriInfo injection to a method
parameter in all the methods where I need an UriInfo object.
It works well for everything except when I try to retrieve a sub-resource,
in which case I get an exception like this:
Sep 18, 2008 10:38:30 AM org.apache.cxf.phase.PhaseInterceptorChain
doIntercept
INFO: Interceptor has thrown exception, unwinding now
java.lang.NullPointerException
	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:148)
	at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:63)
	at
org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:56)
	at
org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
	at
org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:92)
	at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:220)
	at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)
	at
org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:92)
	at
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:283)
	at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:128)
	at
org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:174)
	at
org.apache.cxf.transport.servlet.AbstractCXFServlet.doGet(AbstractCXFServlet.java:156)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
	at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
	at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
	at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Thread.java:613)
Sep 18, 2008 10:38:30 AM
org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose
INFO: Outbound Message

The code in my sub-resource class is never even executed, the exception
happens in CXF.

My next attempt will be to forward the UriInfo received by the sub-resources
parent to the sub-resource. I'll get back on how that works.
-- 
View this message in context: http://www.nabble.com/UriInfo-object-in-Sub-Resource-tp19533573p19545081.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: UriInfo object in Sub-Resource

Posted by Sergey Beryozkin <se...@iona.com>.
Hi

The only JAX-RS standard way to get UriInfo (or any other @Context annotated) values into subresources is to inject them as method
parameters :
void foo(@Context UriInfo ui);
One of the problems with injecting @Context fields in subresources is that subresources are detected dynamically, while @Context
values have to be thread-safe and as such the intial injection actually happens at the very start-up.

Perhaps we'll need to come up with some sort of CXF-private subresource injection technique - Jersey does some tricks in this regard
I believe.

Actually, the other approach is to back-reference userResource from a role resource (roleResource.setUserResource(this) at the 
spring injection time) and then simply have getUriInfo() on the UserResource. Do you reckon it can work ?

Cheers, Sergey


>
> Hello!
> I have spent some days trying to figure out how to get sub-resources working
> as I want them to to no avail. I want every resource, including
> sub-resources, to contain an attribute which value is the URI of the
> resource.
>
> I have an example program where a User can be associated (one-way) to zero
> or more Roles.
> Consequently, I have an UserResource and a RoleResource.
> To retrieve the data of a specific user, I use
> http://localhost:8080/CXF_REST_Webservice/users/2/
> To list the roles of the same user, I would use
> http://localhost:8080/GWT_REST_Webservice/users/2/roles/
> So, in my UserResource class, I have a method that is to retrieve the roles
> of a user:
> (annotations copied from the interface to condense things)
>
> @WebService
> @Path("/users/")
> @ProduceMime({"application/xml", "application/json"})
> public class UserResourceImpl implements UserResource
> {
>    // A lot of other stuff...
>
>    @Path("{id}/roles/")
>    public RoleResource getUserRoles(
>        @PathParam("id") final Long inUserId,
>        @QueryParam("expandLevel") @DefaultValue("1") final int
> inExpandLevel)
>        throws UserNotFoundFault
>    {
>        /* The RoleResource is injected into the UserResource by Spring. */
>        return mRoleResource;
>    }
> }
>
> Both the UserResource and the RoleResource have an instance variable of the
> type UriInfo, which is annotated with the @Context annotation. The problem
> that occurs is that the UriInfo in the RoleResource returned from the above
> method is empty, that is, calling getAbsolutePath() on the UriInfo fails
> with a NullPointerException.
> When retrieving role resources directly, using an URI like
> http://localhost:8080/CXF_REST_Webservice/roles/2, the UriInfo object is not
> empty and the call to getAbsolutePath() causes no problems.
>
> One place I suspect I have made a mistake is in the application context file
> for the services:
> ...
>    <jaxrs:server id="CXF_REST_Service" address="/">
>        <jaxrs:serviceBeans>
>            <ref bean="userServiceBean" />
>            <ref bean="roleServiceBean" />
>        </jaxrs:serviceBeans>
>    </jaxrs:server>
> ...
>
> I tried to run the code on Jersey, the reference implementation of JSR-311,
> and there, the UriInfo objects in the UserResource and the RoleResource were
> correctly set. There were, however, other problems with Jersey that makes me
> prefer CXF, if I only can get the above problem solved.
> Many thanks for all the effort people put into CXF and for any help I might
> receive!
>
> -- 
> View this message in context: http://www.nabble.com/UriInfo-object-in-Sub-Resource-tp19533573p19533573.html
> Sent from the cxf-user mailing list archive at Nabble.com.

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

Re: Cannot create operation : not request-response or one-way

Posted by Daniel Kulp <dk...@apache.org>.

You could move the type into the element:
<element name="MyParameter">
<complexType>
<sequence/>
</complexType>
</element>

That's about all you can do.   Either that or switch to rpc/literal and use an 
empty message:
<wsdl:message name="myRequestParameter"/>

When the request comes in on the wire, we need someway to know what operation 
to call.   In doc/lit, the only stuff on the wire is what you put in the 
element.   There isn't an operation name in method if you don't put one 
there.

Dan


On Thursday 18 September 2008 3:32:16 am Maxime Orain wrote:
> Thanks for your response.
>
> Is there any way to not define input types? (in order to have a void
> like in Java)
>
> I succeed to create the void but with types. So I need to create input
> element as empty like this?
>
> Types:
> -----
> 	<element name="MyParameter" type="tns:voidType"/>
> 	<element name="MyResponse" type="tns:TheResponse"/>
> 	<complexType name="TheResponse">
> 		<sequence>
> 			<element minOccurs="0" name="return"
> type="xsd:string"/>
> 		</sequence>
> 	</complexType>
> 	<complexType name="voidType">
> 		<sequence/>
> 	</complexType>
>
> Message:
> --------
> 	<wsdl:message name="myRequestParameter">
> 		<wsdl:part name="myParameter"
> element="tns:MyParameter"/>
> 	</wsdl:message>
> 	<wsdl:message name="myRequestResponse">
> 		<wsdl:part name="myResponse" element="tns:myResponse"/>
> 	</wsdl:message>
>
> PortType:
> ---------
>
> 	<wsdl:operation name="myRequest">
> 		<wsdl:input name="myRequestParameter"
> 				message="tns:myRequestParameter"/>
> 		<wsdl:output name="myRequestResponse"
> 				 message="tns:myRequestResponse"/>
> 	</wsdl:operation>
>
> Binding:
> --------
> 	<wsdl:operation name="myRequest">
> 		<soap:operation soapAction=""/>
>
> 		<wsdl:input name="myRequestParameter">
> 			<soap:body use="literal"/>
> 		</wsdl:input>
>
> 		<wsdl:output name="myRequestResponse">
> 			<soap:body use="literal"/>
> 		</wsdl:output>
>
> 	</wsdl:operation>
>
>
>
> -----Original Message-----
> From: Daniel Kulp [mailto:dkulp@apache.org]
> Sent: 17 September 2008 21:44
> To: users@cxf.apache.org
> Cc: Maxime Orain
> Subject: Re: Cannot create operation : not request-response or one-way
>
>
> This is still a "request + response" interaction, just the request
> wouldn't
> contain any data.   You would need to add an "input" message to the
> operation
> that points to either a message with no parts, or one part pointing to
> an
> empty sequence.
>
> Dan
>
>
>
> On Wednesday 17 September 2008 11:14:02 am Maxime Orain wrote:
> Hello to all,
>
> I want to create a Java method like this from a WSDL definition: (The
> relevant WSDL information is below)
>
> 	MyResponse myRequest()
>
> The problem is when I try to generate the Java code I obtain this
> message:
>
>      [java] WSDLToJava Error:
>      [java]  Summary:  Failures: 1, Warnings: 0
>      [java]  <<< ERROR!
>      [java] Invalid WSDL, Operation myRequest in PortType
> {http://service}MyService not request-response or one-way
>
> I don't understand because the inverse works ex:
>
> 	void myRequest(MyParameter parameter)
>
>
> If someone can help me it would be very appreciated!
>
> WSDL definition used to create:  MyResponse myRequest()
>
> Types:
> -----
>
> 	<element name="MyResponse" type="tns:TheResponse"/>
> 	<complexType name="TheResponse">
> 		<sequence>
> 			<element minOccurs="0" name="return"
> type="xsd:string"/>
> 		</sequence>
> 	</complexType>
>
>
> Message:
> --------
> 	<wsdl:message name="myRequestResponse">
> 		<wsdl:part name="myResponse" element="tns:myResponse"/>
> 	</wsdl:message>
>
> PortType:
> ---------
>
> 	<wsdl:operation name="myRequest">
> 		<wsdl:output name="myRequestResponse"
> message="tns:myRequestResponse"/>
> 	</wsdl:operation>
>
> Binding:
> --------
> 	<wsdl:operation name="myRequest">
> 		<soap:operation soapAction=""/>
>
> 		<wsdl:output name="myRequestResponse">
> 			<soap:body use="literal"/>
> 		</wsdl:output>
> 	</wsdl:operation>
>
>
>
> This email was sent to you by Thomson Reuters, the global news and
> information company. Any views expressed in this message are those of
> the
> individual sender, except where the sender specifically states them to
> be
> the views of Thomson Reuters.



-- 
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog

RE: Cannot create operation : not request-response or one-way

Posted by Maxime Orain <Ma...@thomsonreuters.com>.
Thanks for your response.

Is there any way to not define input types? (in order to have a void
like in Java)

I succeed to create the void but with types. So I need to create input
element as empty like this? 

Types:
-----
	<element name="MyParameter" type="tns:voidType"/>
	<element name="MyResponse" type="tns:TheResponse"/>
	<complexType name="TheResponse">
		<sequence>
			<element minOccurs="0" name="return"
type="xsd:string"/>
		</sequence>
	</complexType>
	<complexType name="voidType">
		<sequence/>
	</complexType>

Message:
--------
	<wsdl:message name="myRequestParameter">
		<wsdl:part name="myParameter"
element="tns:MyParameter"/>
	</wsdl:message>
	<wsdl:message name="myRequestResponse">
		<wsdl:part name="myResponse" element="tns:myResponse"/>
	</wsdl:message>

PortType:
---------

	<wsdl:operation name="myRequest">
		<wsdl:input name="myRequestParameter"
				message="tns:myRequestParameter"/>
		<wsdl:output name="myRequestResponse"
				 message="tns:myRequestResponse"/>
	</wsdl:operation>

Binding:
--------
	<wsdl:operation name="myRequest">
		<soap:operation soapAction=""/>

		<wsdl:input name="myRequestParameter">
			<soap:body use="literal"/>
		</wsdl:input>

		<wsdl:output name="myRequestResponse">
			<soap:body use="literal"/>
		</wsdl:output>

	</wsdl:operation>



-----Original Message-----
From: Daniel Kulp [mailto:dkulp@apache.org] 
Sent: 17 September 2008 21:44
To: users@cxf.apache.org
Cc: Maxime Orain
Subject: Re: Cannot create operation : not request-response or one-way


This is still a "request + response" interaction, just the request
wouldn't 
contain any data.   You would need to add an "input" message to the
operation 
that points to either a message with no parts, or one part pointing to
an 
empty sequence.

Dan



On Wednesday 17 September 2008 11:14:02 am Maxime Orain wrote:
Hello to all,
>
I want to create a Java method like this from a WSDL definition: (The
relevant WSDL information is below)
>
	MyResponse myRequest()
>
The problem is when I try to generate the Java code I obtain this
message:
>
     [java] WSDLToJava Error:
     [java]  Summary:  Failures: 1, Warnings: 0
     [java]  <<< ERROR!
     [java] Invalid WSDL, Operation myRequest in PortType
{http://service}MyService not request-response or one-way
>
I don't understand because the inverse works ex:
>
	void myRequest(MyParameter parameter)
>
>
If someone can help me it would be very appreciated!
>
WSDL definition used to create:  MyResponse myRequest()
>
Types:
-----
>
	<element name="MyResponse" type="tns:TheResponse"/>
	<complexType name="TheResponse">
		<sequence>
			<element minOccurs="0" name="return"
type="xsd:string"/>
		</sequence>
	</complexType>
>
>
Message:
--------
	<wsdl:message name="myRequestResponse">
		<wsdl:part name="myResponse" element="tns:myResponse"/>
	</wsdl:message>
>
PortType:
---------
>
	<wsdl:operation name="myRequest">
		<wsdl:output name="myRequestResponse"
message="tns:myRequestResponse"/>
	</wsdl:operation>
>
Binding:
--------
	<wsdl:operation name="myRequest">
		<soap:operation soapAction=""/>
>
		<wsdl:output name="myRequestResponse">
			<soap:body use="literal"/>
		</wsdl:output>
	</wsdl:operation>
>
>
>
This email was sent to you by Thomson Reuters, the global news and
information company. Any views expressed in this message are those of
the
individual sender, except where the sender specifically states them to
be
the views of Thomson Reuters.



-- 
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog


This email was sent to you by Thomson Reuters, the global news and information company.
Any views expressed in this message are those of the individual sender, except where the sender specifically states them to be the views of Thomson Reuters.



Re: Cannot create operation : not request-response or one-way

Posted by Daniel Kulp <dk...@apache.org>.
This is still a "request + response" interaction, just the request wouldn't 
contain any data.   You would need to add an "input" message to the operation 
that points to either a message with no parts, or one part pointing to an 
empty sequence.

Dan



On Wednesday 17 September 2008 11:14:02 am Maxime Orain wrote:
> Hello to all,
>
> I want to create a Java method like this from a WSDL definition: (The
> relevant WSDL information is below)
>
> 	MyResponse myRequest()
>
> The problem is when I try to generate the Java code I obtain this
> message:
>
>      [java] WSDLToJava Error:
>      [java]  Summary:  Failures: 1, Warnings: 0
>      [java]  <<< ERROR!
>      [java] Invalid WSDL, Operation myRequest in PortType
> {http://service}MyService not request-response or one-way
>
> I don't understand because the inverse works ex:
>
> 	void myRequest(MyParameter parameter)
>
>
> If someone can help me it would be very appreciated!
>
> WSDL definition used to create:  MyResponse myRequest()
>
> Types:
> -----
>
> 	<element name="MyResponse" type="tns:TheResponse"/>
> 	<complexType name="TheResponse">
> 		<sequence>
> 			<element minOccurs="0" name="return"
> type="xsd:string"/>
> 		</sequence>
> 	</complexType>
>
>
> Message:
> --------
> 	<wsdl:message name="myRequestResponse">
> 		<wsdl:part name="myResponse" element="tns:myResponse"/>
> 	</wsdl:message>
>
> PortType:
> ---------
>
> 	<wsdl:operation name="myRequest">
> 		<wsdl:output name="myRequestResponse"
> message="tns:myRequestResponse"/>
> 	</wsdl:operation>
>
> Binding:
> --------
> 	<wsdl:operation name="myRequest">
> 		<soap:operation soapAction=""/>
>
> 		<wsdl:output name="myRequestResponse">
> 			<soap:body use="literal"/>
> 		</wsdl:output>
> 	</wsdl:operation>
>
>
>
> This email was sent to you by Thomson Reuters, the global news and
> information company. Any views expressed in this message are those of the
> individual sender, except where the sender specifically states them to be
> the views of Thomson Reuters.



-- 
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog

Cannot create operation : not request-response or one-way

Posted by Maxime Orain <Ma...@thomsonreuters.com>.
Hello to all,

I want to create a Java method like this from a WSDL definition: (The
relevant WSDL information is below)

	MyResponse myRequest()

The problem is when I try to generate the Java code I obtain this
message:

     [java] WSDLToJava Error: 
     [java]  Summary:  Failures: 1, Warnings: 0
     [java]  <<< ERROR! 
     [java] Invalid WSDL, Operation myRequest in PortType
{http://service}MyService not request-response or one-way

I don't understand because the inverse works ex:
	
	void myRequest(MyParameter parameter)


If someone can help me it would be very appreciated!

WSDL definition used to create:  MyResponse myRequest()

Types:
-----

	<element name="MyResponse" type="tns:TheResponse"/>
	<complexType name="TheResponse">
		<sequence>
			<element minOccurs="0" name="return"
type="xsd:string"/>
		</sequence> 
	</complexType>


Message:
--------
	<wsdl:message name="myRequestResponse">
		<wsdl:part name="myResponse" element="tns:myResponse"/>
	</wsdl:message>

PortType:
---------

	<wsdl:operation name="myRequest">
		<wsdl:output name="myRequestResponse"
message="tns:myRequestResponse"/>
	</wsdl:operation>

Binding:
--------
	<wsdl:operation name="myRequest">
		<soap:operation soapAction=""/>

		<wsdl:output name="myRequestResponse">
			<soap:body use="literal"/>
		</wsdl:output>
	</wsdl:operation>



This email was sent to you by Thomson Reuters, the global news and information company.
Any views expressed in this message are those of the individual sender, except where the sender specifically states them to be the views of Thomson Reuters.