Monday, May 5, 2014

Spring form tag : ModelAttribute VS CommandName

Take a look at the source code of FormTag below

/**
 * Set the name of the form attribute in the model.
 * <p>May be a runtime expression.
 */
public void setModelAttribute(String modelAttribute) {
    this.modelAttribute = modelAttribute;
}

/**
 * Get the name of the form attribute in the model.
 */
protected String getModelAttribute() {
    return this.modelAttribute;
}

 
/**
 * Set the name of the form attribute in the model.
 * <p>May be a runtime expression.
 * @see #setModelAttribute
 */
public void setCommandName(String commandName) {
    this.modelAttribute = commandName;
}

/**
 * Get the name of the form attribute in the model.
 * @see #getModelAttribute
 */
protected String getCommandName() {
    return this.modelAttribute;
}

 
The code from form tag shows that they are both referring to the same field/property.

Thursday, May 1, 2014

Setting up logging in Spring based project

Jakarta Commons Logging API (JCL) is the only mandatory external dependency in spring framework.  Spring framework is compiled against Jakarta Commons Logging (JCL). If you are using Maven for example for your spring based project, and wondering where you picked up the dependency on commons-logging, then it is from Spring and specifically from the central module called spring-core. 

Image

Spring documentation says 
Unfortunately, the runtime discovery algorithm in commons-logging, while convenient for the end-user, is problematic.  
If we could turn back the clock and start Spring now as a new project it would use a different logging dependency. The first choice would probably be the Simple Logging Facade for Java (SLF4J) 

Switching off commons-logging  

In this blog I will explain how to switch off commons-logging and use sl4j for logging. 
 Switching off commons-logging is easy. In Maven terms you exclude the dependency 

<dependency> 
<groupId>org.springframework</groupId> 
<artifactId>spring-context</artifactId> 
<version>${spring-framework.version}</version> 
<exclusions> 
<exclusion> 
<groupId>commons-logging</groupId> 
<artifactId>commons-logging</artifactId> 
</exclusion> 
</exclusions> 
</dependency> 

SLF4J is a cleaner dependency and more efficient at runtime than commons-logging because it uses compile-time bindings instead of runtime discovery of the other logging frameworks it integrates. 
SLF4J provides bindings to many common logging frameworks, so you can usually choose one that you already use, and bind to that for configuration and management. 

Adding SLF4J-JCL bridge dependency 

In order to use SLF4J with Spring you need to add the SLF4J-JCL bridge dependency. 

<dependency> 
<groupId>org.slf4j</groupId> 
<artifactId>jcl-over-slf4j</artifactId> 
<version>${slf4j.version}</version> 
<scope>runtime</scope> 
</dependency> 

Once you have done that then logging calls from within Spring will be translated into logging calls to the SLF4J API 

SLF4J to Logback Binding 


Next step is to provide explicit binding from SLF4J to Logback 
Logback is intended as a successor to the popular log4j project and logback-classic natively implements the SLF4J API 
Add following dependencies to do the SLF4J to Logback binding 

<dependency> 
<groupId>org.slf4j</groupId> 
<artifactId>slf4j-api</artifactId> 
<version>${slf4j.version}</version> 
<scope>compile</scope> 
</dependency> 
<dependency> 
<groupId>ch.qos.logback</groupId> 
<artifactId>logback-classic</artifactId> 
<version>${logback.version}</version> 
<scope>runtime</scope> 
</dependency> 

Logback configuration 


Last step is to drop a logback.xml in your projects src/main/resources folder. 
Add following xml in the logback.xml and then edit it to your need 

<?xml version="1.0" encoding="UTF-8"?> 
<!-- configuration file for LogBack (slf4J implementation) 
<configuration scan="true" scanPeriod="30 seconds">  
    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> 
        <resetJUL>true</resetJUL> 
    </contextListener>  
    <!-- To enable JMX Management --> 
    <jmxConfigurator/>  
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> 
        <encoder> 
            <pattern>%-5level %logger{0} - %msg%n</pattern> 
        </encoder> 
    </appender>  
  <!--<logger name="org.hibernate" level="debug"/> --> 
   <!-- Uncomment and add your logger here: 
    <logger name="org.springframework.samples.service.service" level="debug"/> --> 
    <logger name="org.springframework" level="debug"/> 
          
    <root level="debug"> 
        <appender-ref ref="console"/> 
    </root> 
</configuration> 
  

To Use Log4J instead Logback 

If you want to use Log4j then add following 4 dependencies 

<dependency> 
 <groupId>org.slf4j</groupId> 
 <artifactId>jcl-over-slf4j</artifactId> 
 <version>1.5.8</version> 
 <scope>runtime</scope> 
</dependency> 
<dependency> 
 <groupId>org.slf4j</groupId> 
 <artifactId>slf4j-api</artifactId> 
 <version>1.5.8</version> 
 <scope>runtime</scope> 
</dependency> 
<dependency> 
 <groupId>org.slf4j</groupId> 
 <artifactId>slf4j-log4j12</artifactId> 
 <version>1.5.8</version> 
 <scope>runtime</scope> 
</dependency> 
<dependency> 
 <groupId>log4j</groupId> 
 <artifactId>log4j</artifactId> 
 <version>1.2.14</version> 
 <scope>runtime</scope> 
</dependency> 

and the log4j.xml on your projects classpath