• SEARCH BOX

Combine Jetty and Spring Application Context

Spring's Logo The goal of this post is to use one xml configuration file which is Spring's applicationContext.xml and load it only once for the duration of the application running in an embedded jetty server. Read more...

Tutorial on Android Layout

A thumbnail of adroid. Android is an open source platform for mobile devices. Not a hardware. It is a software stack as defined by Google. Encase your not familiar with the term, software stack is compose of an Operating System(OS), middle-ware and the key applications. Read more...

Hi, my name's Paul Labis.

I'm a developer in Makati City, Philippines. Focused on building online Java/J2EE based applications. I'm interested in freelance or part-time work from home.

Showing posts with label Web Service. Show all posts
Showing posts with label Web Service. Show all posts

Saturday, May 29, 2010

Combine Jetty and Spring Application Context XML Configuration

The goal is to use one xml configuration file which is Spring's applicationContext.xml and load it only once for the duration of the application. Using Embedded jetty as my lightweight server to run my Spring MVC application, I must tell my dispatcher servlets to use spring applicationContext.xml which already been loaded as its parent context. That way, dispatcher servlet will be able to  referenced bean configured on springs application context.

To do that, create a class that extends org.mortbay.jetty.Server and implement org.springframework.context.ApplicationContextAware. This is pretty straight forward, we extend jetty server so we can configure its parent context. We implemented spring application context aware so whenever spring successfully loaded applicatContext.xml bean configuration, it gets the current application context. We then configure it as parent context of servlets.

Code on ServerConfigurer.java:
package com.sample.config;

import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.ServletHandler;
import org.mortbay.jetty.webapp.WebAppContext;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;

public class ServerConfigurer
    extends Server
    implements ApplicationContextAware
{
    private String _webAppDir = null;
    private String _contextPath = null;
    private ServletHandler _servletHandler = null;
    private static ApplicationContext _applicationContext = null;

    public String getContextPath() {
        return _contextPath;
    }
    public ServletHandler getServletHandler() {
        return _servletHandler;
    }
    public String getWebAppDir() {
        return _webAppDir;
    }
    /**
     * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException
    {
        _applicationContext = applicationContext;
    }
    public void setContextPath(String contextPath) {
        _contextPath = contextPath;
    }
    public void setServletHandler(ServletHandler servletHandler) {
        _servletHandler = servletHandler;
    }
    public void setWebAppDir(String webAppDir) {
        _webAppDir = webAppDir;
    }

    @Override
    protected void doStart()
        throws Exception
    {
        final WebAppContext webAppContext = new WebAppContext(getServer(), _webAppDir, _contextPath);
        final GenericWebApplicationContext webApplicationContext = new GenericWebApplicationContext();
        webApplicationContext.setServletContext(webAppContext.getServletContext());
        webApplicationContext.setParent(_applicationContext);
 
webAppContext.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext);
        webApplicationContext.refresh();
        webAppContext.setServletHandler(_servletHandler);
        addHandler(webAppContext);
        super.doStart();

    }
}

Text on bold note: Those are the pieces of code that basically are the most important in the server configurer. The setApplicationContext() method is the one that configures that gets the application context loaded by spring. The method doStart() is the one that does the story telling to web app that a current context has been loaded and it is the context should be used. 

Code on applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" >


    <!-- more beans configured -->
    <bean name="webServer" class="point to your server configurer java file" init-method="start">   
        <property name="connectors">
            <list>
                <bean class="org.mortbay.jetty.nio.SelectChannelConnector">
                    <property name="host" value="${jetty.host}"/>
                    <property name="port" value="${jetty.port}"/>
                </bean>
            </list>
        </property>

        <property name="webAppDir" value="${jetty.webApp.dir}"/>
        <property name="contextPath" value="${jetty.context.Path}"/>
       
        <property name="servletHandler">
            <bean class="org.mortbay.jetty.servlet.ServletHandler">
                <property name="servlets">
                    <list>
                        <bean class="org.mortbay.jetty.servlet.ServletHolder">
                            <property name="name" value="dispatcher" />
                            <property name="servlet">
                                <bean class="org.springframework.web.servlet.DispatcherServlet" />
                            </property>
                        </bean>
                    </list>
                </property>
                <property name="servletMappings">
                    <list>
                        <bean class="org.mortbay.jetty.servlet.ServletMapping">
                            <property name="servletName" value="dispatcher" />
                            <property name="pathSpec" value="*.htm" />
                        </bean>
                    </list>
                </property>
            </bean>
        </property>

        <property name="handlers">
            <list>
                <!-- log handler -->
                <bean class="org.mortbay.jetty.handler.RequestLogHandler">
                    <property name="requestLog">
                        <bean class="org.mortbay.jetty.NCSARequestLog">
                            <property name="append" value="true"/>
                            <property name="filename" value="${http.log.dir}/access.log.yyyy_mm_dd"/>
                            <property name="extended" value="true"/>
                            <property name="retainDays" value="999"/>
                            <property name="filenameDateFormat" value="yyyy-MM-dd"/>
                        </bean>
                    </property>
                </bean>
            </list>
        </property>
    </bean>
               
</beans>

That xml file comprise server configuration of your jetty server pointing dispatcher servlet use  Spring's application context. Your next step is run your application the way you want.
 example:
        _applicationContext = new ClassPathXmlApplicationContext(_resourceLocations);
        _applicationContext.start();


I also did another article related to Spring MVC/IOC-DI and Embedded Jetty utilizing applicationContext .xml of Spring. You might be interested running and configuring jetty through java code and not from applicationContext.xml.

Hope this helps! For suggestion, please feel free to leave your comments.

Wednesday, May 26, 2010

Embedded Jetty in Spring MVC, IoC/DI


I was trying to configure embedded jetty in a spring application that implements MVC(Model View Controller). I want to utilize single spring applicationContext xml file for IoC(Inversion of Control) and DI(Dependency Injection) on dispatcher servlets.

The goal is to be able to use or reference beans configured/located on already been loaded spring application context. Read and understand my resolution below.

This is what my main method look like:
LOG.info("Application starting");
_applicationContext = new ClassPathXmlApplicationContext(_resourceLocations);

_webServer = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setHost("localhost");
connector.setPort(8080);
_webServer.addConnector(connector);

WebAppContext webAppContext = new WebAppContext(_webServer, "path to web app folder", "/");

GenericWebApplicationContext webApplicationContext = new GenericWebApplicationContext();
webApplicationContext.setServletContext(webAppContext.getServletContext());
webApplicationContext.setParent(_applicationContext);

webAppContext.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext);
webApplicationContext.refresh();

ServletHandler servletHandler = new ServletHandler();

ServletHolder servletHolder = new ServletHolder(new DispatcherServlet());
servletHolder.setName("dispatcher");
servletHandler.addServlet(servletHolder);

ServletMapping servletMapping = new ServletMapping();
servletMapping.setServletName(servletHolder.getName());
servletMapping.setPathSpec("*.htm");
servletHandler.addServletMapping(servletMapping);

webAppContext.setServletHandler(servletHandler);
_webServer.addHandler(webAppContext);

RequestLogHandler logHandler = new RequestLogHandler();
NCSARequestLog ncsaLog = new NCSARequestLog();
ncsaLog.setExtended(true);
ncsaLog.setFilename("logs/jetty-yyyy_mm_dd.log");
logHandler.setRequestLog(ncsaLog);
_webServer.addHandler(logHandler);

LOG.info("Starting main application context");
_applicationContext.start();

LOG.info("Starting Jetty Server");

try {
_webServer.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

LOG.info("Application started");
return null;

 The idea is that DispatcherServlet's context is child context of  GenericWebApplicationContext which in turn is a child of ClassPathXmlApplicationContext. Explicitly invoking setParent() gives you the access to all beans from the web application context.

Hope this helps. Feel free to leave your comment or suggestions.

Monday, March 22, 2010

Web Service Tutorial in Java

Web Service is a piece of software that makes a service available on web. It uses a universal standard XML processing. It is interoperable in a sense that it enables a .NET software on a Windows Server to communicate to a JAVA software on a Unix. In other words, its not bound to a specific programming language or an operating system.
  • "Provider agent" implements a Web service
  • "Requester agent" (a.k.a. "client") makes use of that Web service
  • WSD(Web Service Description) represents a "contract"
  • Specifies the message formats, transport protocols, locations 
What we want to do in this article is to create a project where it utilizes a web service online. I plot the step by step way of utilizing a web service through terminal.


Please note that before you start the tutorial, you should make sure that you already setup Java on your ubuntu or linux operating system. Throughout this tutorial, we are not going to use eclipse or any IDE to acomplish our objective of utilizing a remote web service.

1. Find a Remote Web Service/ Webservice

There are a lot of sample remote web services to play on in www.webservicex.net. For the purpose of this tutorial. I would like to utilize Translator Engine Web Service (http://www.webservicex.net/WCF/ServiceDetails.aspx?SID=47). We are going to use wsimport to generates portable JAX-WS artifacts for invoking a web service.

2. Create a dynamic proxy from WSDL(Web Service Description Language)

We will make it structural by creating a directory : ./TranslatorWS
Run generator on terminal by either $JAVA_HOME/Commands or $JAVA_HOME/bin/wsimport URL
In our case that is:
$ /usr/lib/jvm/java-6-sun-1.6.0.16/bin/wsimport -d ./TranslatorWS http://www.webservicex.net/TranslateService.asmx?wsdl
Result: It will generate bunch of .class files under ./TranslatorWS folder

3. Generate a jar file from the generated .class files

Open a terminal and navigate to your project.
Run on terminal:
$ jar cvf TranslatorWS.jar -C ./TranslatorWS/ .
Result: A jar file name TranslatorWS.jar is generated out of the dynamic proxy of the remote Web Service.

4. Write Client code

 Let's structure our code by creating ./src folder and write something like com.client.TranslatorWSClient.java


(Note: Inside src is com folder. Inside com is client folder. Inside client folder is the Java class)
Result: You are able to create the code to utilized the web service.




package com.client;

import net.webservicex.Translate;
import net.webservicex.TranslateService;
import net.webservicex.TranslateServiceSoap;

public class TranslatorWS {
/**
* * @param args
* */
public static void main(String[] args) {
if (args.equals(null) || args.length == 0){
printHelp();
}

TranslateServiceSoap translatorService = new TranslateService().getTranslateServiceSoap();
if ("EnglishTOFrench".equals(args[0])){
System.out.println("Translation:");
System.out.println(translatorService.translate(args[0], args[1]));
}
}
private static void printHelp() {
System.out.println("TranslatorWS <language> <Word To Translate>");
}
}


5. Compile Client Code

Create a directory ./bin where you will store your compiled .class client class.
RUN on terminal:
$ javac -classpath ./TranslatorWS.jar -d ./bin/ -verbose ./src/com/client/TranslatorWS.java
Result : compiled client code under ./bin directory.

6. Run the client to utilize remote web service

Run on Terminal:
$ java -classpath ./bin/:./TranslatorWS.jar com.client.TranslatorWS EnglishTOFrench goodTranslation:
Error occured when translating text please contact support@webservicex.net
Result: A translation of the word. However, on this web service, an error message is sent back instead of the real thing.


NOTE: These are free Web services just made for practice or tutorials therefore they are unreliable, sometimes their response time is quite big and wrong.
 

Author

Followers

Techie Projects

Open Source