Live stock quote listing using GWT and Spring

In two of the previous posts (XML response, JSON response) I shared my learning about implementing a spring based client application that interacts with yahoo finance API using YQL(Yahoo Query Language), gets finance quotes from the web server for a given symbol.

In this post i would like to share how i use the Google Web Toolkit (GWT) as the front end to display the stock quotes, retrieved by the spring based client application from yahoo finance API. By integrating GWT front end with my spring client application i am showing live stock listing and updates every few minutes for stock symbols entered by the user. Check out my live stock listing application at work that is hosted on google appengine.

Assuming you already have a GWT application with the UI design as per your needs(look at GWT for guidance), the specific steps taken in integrating GWT with the spring application that knows to retrieve stock quotes are shown below:

Step1: Dependency: Add “gwtrpcspring-.jar” to the libraries folder in the project, and make sure CLASSPATH can access this libraries folder. This dependency helps me to use the GWT RPC mechanism to talk to the Spring implementation.

Step2: Define an interface to retrieve stock quotes that extends RemoteService (from GWT) both synchronous and Asynchronous version on GWT client side. The actual implementation of this interface is provided by the spring client application on the GWT server side. Edit the spring client implementation to implement this interface. Also make sure the spring implementation is exported as a service with the “@service” annotation.
Code is shown below with all the required annotations.

Define RPC service to retrieve stock quotes on the GWT Client side

package <packageName>.client
import com.google.gwt.user.client.rpc.RemoteService;

@RemoteServiceRelativePath("stockRetrieve")
public interface StockRetrieveService extends RemoteService{
  Query retrieve(String[] symbols);
}

NOTE: @RemoteServiceRelativePath annotation associates the service identified by “stockRetrieve” with a default path relative to GWT module base URL. Supporting configuration needed for this in web.xml and applicationContext.xml, explained below.

Define Asynchronous service:

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface StockRetrieveServiceAsync {
  void retrieve(String[] symbols, AsyncCallback<Query> callback);
}

NOTE: As part of the GWT client module, the callback procedure has to be implemented for its success and failure scenarios. The sucess scenario will be able to unwrap the Query object to populate the UI with stock quote data.

RPC service implementation to retrieve stock quotes on GWT Server side

package <packageName>.server
@Service
public class StockRetrieveServiceImpl implements StockRetrieveService {
  private final RestTemplate rTemplate;
  private XPathOperations xpathTemplate;
	  
  @Autowired
  StockRetrieveServiceImpl(RestTemplate restTpl) {
    rTemplate = restTpl;  
  }
	  
  @Autowired
  public void setXPathTemplate(XPathOperations xpTemplate) {
    xpathTemplate = xpTemplate;
  }
	
  @Override
  public Query retrieve(String[] symbols) {
  ....
  
  }

Step 3: web.xml in the GWT project:
Edit web.xml in the GWT application to add listener to listen to Spring application context

    <listener>
    org.springframework.web.context.ContextLoaderListener
    </listener>

Edit web.xml in GWT application to define GWT RemoteServiceDispatcher servlet and its servlet mappings. Here the url-pattern shows the GWT module base URL followed by the service

  <!-- Servlets -->
  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.gwtrpcspring.RemoteServiceDispatcher</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/stockquotegwt/stockRetrieve</url-pattern> 
  </servlet-mapping> 

Step 4:applicationContext.xml in GWT project:
Edit applicationContext.xml to add the annotation-config and component-scan elements so the annotations will get picked up automatically by spring.

  <context:annotation-config/>
  <context:component-scan base-package="<packageName>.server"/>

Leave a comment