You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Ryan Zoerner <ry...@gmail.com> on 2011/05/12 09:20:11 UTC

demo.jaxrs.server.CustomInvoker

In the course of the assignment that Sergey provided me with, I augmented
the http-demo, which I talked a bit here:

http://cxf.547215.n5.nabble.com/Basic-Http-Demo-and-the-refactoring-that-I-did-in-the-course-of-figuring-out-how-it-worked-td4389413.html

Now, the purpose of this customInvoker was for the Server to print a message
to
the the terminal each time a method was invoked.

Here is the code:

demo.jaxrs.server.CustomInvoker.java
--------------------------------------------------------------------------------------------------
package demo.jaxrs.server;

import java.lang.reflect.Method;

import org.apache.cxf.jaxrs.JAXRSInvoker;
import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.jaxrs.utils.InjectionUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Exchange;


public class CustomInvoker extends JAXRSInvoker
{

    public CustomInvoker()
    {
        super();
    }

    @Override
    public Object invoke(Exchange exchange, Object request)
    {
        ResourceProvider provider = getResourceProvider(exchange);
        Object rootInstance = getServiceObject(exchange);
        Object serviceObject = getActualServiceObject(exchange,
rootInstance);
        OperationResourceInfo ori =
exchange.get(OperationResourceInfo.class);
        ClassResourceInfo cri = ori.getClassResourceInfo();

        /*
         * This is where the method to be invoked upon is gotten from.
         */
        Method methodToInvoke =

InjectionUtils.checkProxy(cri.getMethodDispatcher().getMethod(ori),
                serviceObject);

        /*
         * This prints the message to the terminal about which method will
now
         * be invoked upon through the server code.
         */
        System.out.println(
            "\n" +
            "***" +
            "\n" +
            "The method about to be invoked" +
            "\n" +
            "by the CustomInvoker" +
            "\n" +
            "is named" +
            "\n" +
            "--->" +
            "  " +
            methodToInvoke.getName() +
            "\n" +
            "***" +
            "\n"
            );

        /*
         * This calls the invoke method of the
org.apache.cxf.jaxrs.JAXRSInvoker
         * which invokes upon the method which is obtainable from the
         * exchange Object, as demonstrated by this method of this
sub-class.
         */
        return super.invoke(exchange, request);
    }

    /*
     * Because this method was private, I had to copy-and-paste it from the
     * superclass. Another thing that I just thought of is that if you need
     * to throw exceptions from, say, JAXRSInvoker, you won't get all of the

     * resources that you need if you just copy-and-paste and change the
     * package name. Therefore, you could, instead, make a subclass and just

     * @Override what you have copied and pasted, then insert your
exceptions.
     */
    private ResourceProvider getResourceProvider(Exchange exchange)
    {
        Object provider = exchange.remove(JAXRSUtils.ROOT_PROVIDER);
        if (provider == null)
        {
            OperationResourceInfo ori =
                exchange.get(OperationResourceInfo.class);
            ClassResourceInfo cri = ori.getClassResourceInfo();
            return cri.getResourceProvider();
        }
        else
        {
            return (ResourceProvider) provider;
        }
    }
}
--------------------------------------------------------------------------------------------------


This helped me see, better, what the invoker is actually doing with its
code, and how simple it
is to do surgical alterations of coded applications, without having to know
much about what else
is actually happening.

This has application to the integration because EJB needs to have its
resources injected at the
time of Construction, according to JAX-RS 1.1, and EJB annotations must be
processed, during
any method invokation, which is what the invoker is doing here is calling
the method of a
resource whose lifecycle is being governed by a
org.apache.cxf.jaxrs.lifecycle.ResourceProvider.
In this case,  org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider. I
also had to create a
CustomResourceProvider, which I may also publish to the list in a subsequent
email.

Ryan

Re: demo.jaxrs.server.CustomInvoker

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Ryan

Your analysis is good, I'm not entirely sure why you had to copy the
code for retrieving the resource provider, but
overall it looks fine, so yes, you are right, the combination of
custom resource provider and/or invoker should help us with the EJB
integration. Perhaps some of JAXRSInvoker code may need to be split
into functions for subclasses   be able to do the customization easier
- we'll see what needs to be done once the actual EJB integration
effort goes ahead.

I'm glad you are seeing now how important it is to understand the
JAX-RS mechanics for the integration project to succeed

thanks, Sergey

On Thu, May 12, 2011 at 8:20 AM, Ryan Zoerner <ry...@gmail.com> wrote:
> In the course of the assignment that Sergey provided me with, I augmented
> the http-demo, which I talked a bit here:
>
> http://cxf.547215.n5.nabble.com/Basic-Http-Demo-and-the-refactoring-that-I-did-in-the-course-of-figuring-out-how-it-worked-td4389413.html
>
> Now, the purpose of this customInvoker was for the Server to print a message
> to
> the the terminal each time a method was invoked.
>
> Here is the code:
>
> demo.jaxrs.server.CustomInvoker.java
> --------------------------------------------------------------------------------------------------
> package demo.jaxrs.server;
>
> import java.lang.reflect.Method;
>
> import org.apache.cxf.jaxrs.JAXRSInvoker;
> import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
> import org.apache.cxf.jaxrs.model.ClassResourceInfo;
> import org.apache.cxf.jaxrs.model.OperationResourceInfo;
> import org.apache.cxf.jaxrs.utils.InjectionUtils;
> import org.apache.cxf.jaxrs.utils.JAXRSUtils;
> import org.apache.cxf.message.Exchange;
>
>
> public class CustomInvoker extends JAXRSInvoker
> {
>
>    public CustomInvoker()
>    {
>        super();
>    }
>
>    @Override
>    public Object invoke(Exchange exchange, Object request)
>    {
>        ResourceProvider provider = getResourceProvider(exchange);
>        Object rootInstance = getServiceObject(exchange);
>        Object serviceObject = getActualServiceObject(exchange,
> rootInstance);
>        OperationResourceInfo ori =
> exchange.get(OperationResourceInfo.class);
>        ClassResourceInfo cri = ori.getClassResourceInfo();
>
>        /*
>         * This is where the method to be invoked upon is gotten from.
>         */
>        Method methodToInvoke =
>
> InjectionUtils.checkProxy(cri.getMethodDispatcher().getMethod(ori),
>                serviceObject);
>
>        /*
>         * This prints the message to the terminal about which method will
> now
>         * be invoked upon through the server code.
>         */
>        System.out.println(
>            "\n" +
>            "***" +
>            "\n" +
>            "The method about to be invoked" +
>            "\n" +
>            "by the CustomInvoker" +
>            "\n" +
>            "is named" +
>            "\n" +
>            "--->" +
>            "  " +
>            methodToInvoke.getName() +
>            "\n" +
>            "***" +
>            "\n"
>            );
>
>        /*
>         * This calls the invoke method of the
> org.apache.cxf.jaxrs.JAXRSInvoker
>         * which invokes upon the method which is obtainable from the
>         * exchange Object, as demonstrated by this method of this
> sub-class.
>         */
>        return super.invoke(exchange, request);
>    }
>
>    /*
>     * Because this method was private, I had to copy-and-paste it from the
>     * superclass. Another thing that I just thought of is that if you need
>     * to throw exceptions from, say, JAXRSInvoker, you won't get all of the
>
>     * resources that you need if you just copy-and-paste and change the
>     * package name. Therefore, you could, instead, make a subclass and just
>
>     * @Override what you have copied and pasted, then insert your
> exceptions.
>     */
>    private ResourceProvider getResourceProvider(Exchange exchange)
>    {
>        Object provider = exchange.remove(JAXRSUtils.ROOT_PROVIDER);
>        if (provider == null)
>        {
>            OperationResourceInfo ori =
>                exchange.get(OperationResourceInfo.class);
>            ClassResourceInfo cri = ori.getClassResourceInfo();
>            return cri.getResourceProvider();
>        }
>        else
>        {
>            return (ResourceProvider) provider;
>        }
>    }
> }
> --------------------------------------------------------------------------------------------------
>
>
> This helped me see, better, what the invoker is actually doing with its
> code, and how simple it
> is to do surgical alterations of coded applications, without having to know
> much about what else
> is actually happening.
>
> This has application to the integration because EJB needs to have its
> resources injected at the
> time of Construction, according to JAX-RS 1.1, and EJB annotations must be
> processed, during
> any method invokation, which is what the invoker is doing here is calling
> the method of a
> resource whose lifecycle is being governed by a
> org.apache.cxf.jaxrs.lifecycle.ResourceProvider.
> In this case,  org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider. I
> also had to create a
> CustomResourceProvider, which I may also publish to the list in a subsequent
> email.
>
> Ryan
>



-- 
Sergey Beryozkin

Application Integration Division of Talend
http://sberyozkin.blogspot.com