Skip to main content

What do you think about writing an Web application almost without XML?

Posted by urubatan on July 27, 2006 at 7:34 PM PDT

Yes, it is possible, and this is the main goal of the project spring-annotation here at Java.net.

After the initial setup of the application (configuring the database access, and some config at the web.xml), all you need to do is use the provided annotations to setup your beans, and even this way, you can use all the power of the spring framework.

The project has now support for development using Spring MVC and JSF, and even using JSF, if you accept to use "Configuration by exception", you do not need to touch your faces-config.xml file.

To create a Spring-MVC application, all the XML you need, for the entire development cycle of your application is:
an applicationContext.xml with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
    default-autowire="byName" default-lazy-init="false">
   
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName">
            <value>org.postgresql.Driver</value>
        </property>
        <property name="url">
            <value>jdbc:postgresql://localhost:5432/example</value>
        </property>
        <property name="username">
            <value>postgres</value>
        </property>
        <property name="password">
            <value>1111</value>
        </property>
    </bean>
   
    <bean id="sessionFactory" class="net.java.dev.springannotation.hibernate.AutomaticAnnotationSessionFactoryBean">
       <property name="configLocations" value="classpath*:hibernate.cfg.xml" />
       <property name="hibernateProperties">
          <props>
             <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
          </props>
       </property>
       <property name="dataSource">
          <ref bean="dataSource" />
       </property>
    </bean>   
   
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" />
    <tx:annotation-driven />
   
    <!-- ************************ Configuration ******************************** -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
        <property name="prefix"><value>/</value></property>
        <property name="suffix"><value>.jsp</value></property>
    </bean>
   
    <bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
        <property name="paramName"><value>action</value></property>
        <property name="defaultMethodName"><value>init</value></property>
    </bean>
   
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename"><value>messages</value></property>
    </bean>   
</beans>

setup your web.xml file with the following:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/applicationContext.xml,classpath*:applicationContext.xml</param-value>
    </context-param>
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>net.java.dev.springannotation.web.TOAnnotationXmlWebApplicationContext</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
   
    <listener>
       <listener-class>org.springframework.web.context.scope.RequestContextListener</listener-class>
    </listener>
   
    <filter>
        <filter-name>HibernateSpringFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>HibernateSpringFilter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
   
    <display-name>Spring-Annotations-Examples</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

an almost blank spring-servlet.xml (this is needed because of the spring servlet dependency on it)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
</beans>

and after that, you do not need to touch any XML file, not even the hibernate.cfg.xml to register your persistent classes, because the spring-annotation will detect all of then to you.

create a blank to.properties in the root of your classpath, copy the needed jar files to your WEB-INF/lib, and start coding.

you can, for example, create a class like the following:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.java.dev.springannotation.annotation.Bean;
import net.java.dev.springannotation.annotation.UrlMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

@Bean
@UrlMapping("/test.do")
public class TestController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return new ModelAndView("myJspName");
    }
}

and access it using the URL:
http://yourAddress:thePort/appPath/test.do

without the need for all that XML stuff.

if you want to work with JSF, all the beans registered within the spring context will be available to the JSF EL.
You get an @DataModel, @DataModelSelection and @DataModelIndex like the ones in the JBoss Seam
and You get two extra scopes for your beans:
flash - the same as RoR, where yout objects live until the next reqest.
conversation - your beans live until you call a JSF Action method annotated with @ConvEnd (yes, this idea is from JBoss Seam too)

I think it already makes the web development a lot easier.

The pproject is almost reaching it`s 1.0 release, there is missing documentation, the examples are almost finished, and some features implemented as JSF only will be backported to the Spring-MVC too.

I hope you like this project.
There are already some companies at brazil using it in development and production environments.

If some of you are interested in start using it, just use the project mailing lists as a support channel.

Related Topics >>