views:

553

answers:

2

Hi,

My application architecture looks like this. GWT in the UI layer -> Calls GWT RPC service (servlets) -> Looksup Spring Beans -> Calls the DAO layer which is implemented in JPA (EclipseLink).

I have successfully tested the application with GWT rpc services directly calling the JPA layer. But I am having trouble integrating spring into the mix. (Primary usage of Spring is transaction management).

I tried googling, but could not find any good article on the topic. (Most of the articles refers to using Spring MVC within GWT, which is not what I am looking for) Could you please point me to some article/tutorial?

Thanks in advance!

Manoj

A: 

If you're looking for something really simple, why don't you just call a bean from the application context from your service implementation? Something like:

public class GreetingServiceImpl extends RemoteServiceServlet implements
    GreetingService {

  public String greetServer(String input) throws IllegalArgumentException {
    return WebApplicationContextUtils.getRequiredWebApplication(getServletContext()).
      getBean(GreetingService .class).greetServer(input);
  }
}

The backing application context must provide a "real" implementation of GreetingService.

Seee also this article.

lexicore
I followed the post (http://pgt.de/2008/02/14/non-invasive-gwt-and-spring-integration/) and with some help from -> (http://code.google.com/p/gwt-spring-starter-app/), I got my app integrated with Spring. Thank you!!John,Thanks for the reply. It makes sense but I am a little reluctant to add another layer in between. Hence went ahead with the approach suggested by lexicore.
MVK
A: 

One of the interesting problems that I've found is that I often want my servlet to be a Spring-managed bean. That way, it can do all the dependency injection etc. But normally, you have to specify your servlets in web.xml, and that means your container (eg. Tomcat), not Spring, will create the servlet.

There is a way around this, using the HttpRequestHandlerServlet. My web.xml file includes these lines:

<servlet>
    <servlet-name>dataProvider</servlet-name>
    <servlet-class>
        org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet>
    <servlet-name>documentCreator</servlet-name>
    <servlet-class>
        org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dataProvider</servlet-name>
    <url-pattern>/dataProvider/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>documentCreator</servlet-name>
    <url-pattern>/documentCreator/*</url-pattern>
</servlet-mapping>

This tells Spring that it's going to use two of its beans as servlets, one called dataProvider, and the other called documentCreator. It will have to work out what those beans are, either using the xml configuration file or the annotations. I prefer the annotations, such as @Controller.

So what happens when Tomcat receives a request, eg GET /dataProvider/test From the servlet-mapping section, it knows that it has to give that request to the first HttpRequestHandlerServlet that it created. That class knows that it has the name dataProvider, and it looks in the Spring context for a bean called dataProvider. Then it calls the handleRequest method on that bean.

My DataProvider class looks like this:

@Controller
public class DataProvider extends HttpServlet implements HttpRequestHandler {

  @Autowired
  private OtherBeanType otherBean

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    // my doGet method
  }

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) {
    // my doPost method
  }

  @Override
  public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if (request.getMethod().equalsIgnoreCase("GET")) {
      doGet(request, response);
    } else if (request.getMethod().equalsIgnoreCase("POST")) {
      doPost(request, response);
    }
  }

}

I think it's a little unfortunate that we need that handleRequest() method (and if you use anything other than Get and Post, you'll need to add them in there). It would be nicer if the HttpRequestHandlerServlet could do that work for you, but that's just how it works for now.

John