Tuesday, July 7, 2015

Using Thrift with Java servlet

Today we will see how can we use Thrift for webservice call in Java. 

We will start with our Thrift Servlet. This will be a very simple class which will be used to delegate our http request

public class ThriftDelegateServlet extends TServlet {

private static final long serialVersionUID = 5744887369513855991L;

public ThriftDelegateServlet(TProcessor processor, TProtocolFactory protocolFactory) {
super(processor, protocolFactory);
}

@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        super.doPost(request, response);
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        super.doGet(request, response);
    }

}

As you can see, we are just extending org.apache.thrift.server.TServlet class and then overriding doPost and doGet method.

Next we will create our servlet class which will be used as end point of our service. 

public class TestServlet extends HttpServlet {

private static final long serialVersionUID = -8777659712204723236L;
private ThriftDelegateServlet thriftServlet;

    @Override
    public void init() throws ServletException {

            Iface serviceHandler = BeanFactoryHolder.getBean("serviceImpl");

            Processor<Iface> processor = new Processor<Iface>(serviceHandler);
            thriftServlet = new ThriftDelegateServlet(processor, new TBinaryProtocol.Factory());
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

            if (thriftServlet == null) {
                init();
            }
            thriftServlet.doPost(req, resp);

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        this.doPost(req, resp);
    }

}


Self explanatory, but couple of points to add here:
  • In the init(), we are using Bean Factory to get bean of "serviceImpl". serviceImpl is basically our service implemented code i.e Implementation of your Thrift IDL. Hence it will give you an object of <Class>.Iface
  • Next we will create a Thrift Processor of Iface type
  • And finally create an object of ThriftDelegateServlet using processor and thrift protocol (TBinary protocol in our case)
  • When ever we get a request (doPost()) we just see if thriftdelegate is initialised and pass the request to thriftDelegate
Finally we will see how our web.xml should look:
  • Add SpringContext
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
            classpath*:context.xml
</param-value>
</context-param>
  • Add Spring listner

<!-- Spring Listeners -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

  • Add Servlet details

<!-- Start: Servlet for starting thrift over http protocol -->
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.test.tutorial.service.thrift.common.TestServlet</eservlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/service</url-pattern>
</servlet-mapping>

That's it, we are good to go now. We can now create thrift HTTP client and hit webservice. This is how we can create client:

private final String serviceUrl = "/dummy/service";
protected Client getClient() {

THttpClient transport = null;
try {
transport = new THttpClient("http://" + serverIP + ":" + serverPort
+ serviceUrl);
} catch (TTransportException e) {
throw new RuntimeException(e);
}
TProtocol protocol = new TBinaryProtocol(transport);
return new Client(protocol);
}

Before we wrap this is what happens in a nut shell:

  • We create a servlet which is our end point for webservice
  • Whenever a request comes it will first call its init() where we initialise thriftDelegateServlet by passing Thrift Processor and Protocol. To create Processor we get an object of Service Implemented Class
  • ThriftDelegateServlet simply passes the call to thrift Servlet
Will come back with more posts, do let me know your thought and till then Happy Coding :)

No comments:

Post a Comment