Monday, October 15, 2012

Customize Spring JSON output

Spring uses Jackson JSON from http://jackson.codehaus.org/ to serialize an object for json output. To change the default strategy to serialize/format a field in a bean, you can easily create your own serializer. Following is an example to customize date format in json oupt

1. Creat serializer

public class CustomDateSerializer extends JsonSerializer {
 public static Log logger=LogFactory.getLog(CustomDateSerializer.class);
 
 @Override
 public void serialize(Date value, JsonGenerator gen, SerializerProvider arg2) throws IOException, JsonProcessingException {
  
  SimpleDateFormat formatter = new SimpleDateFormat("MM-dd-yyyy");
                String formattedDate = formatter.format(value);

  gen.writeString(formattedDate);

 }
}

2. Annotate bean property to use the serializer


public class TransactionHistoryBean{
  private Date date;

  @JsonSerialize(using = CustomDateSerializer.class)
  public Date getDate() {
      return date;
  }
}

Monday, June 11, 2012

Spring Session Scope Bean

Since HTTP stateless, in a web application, a typical way to keep an user states across multiple requests is through HttpSession. However, doing it this way makes your application has tight dependency on HttpSession and its application container. With Spring, carrying states through multiple request can be done through its session scoped bean. It is cleaner and more flexible. Spring session scoped bean is very easy setup, I will try to explain it in a couple steps.

Scenario: Whenever an user enters your site, he is asked to pick a theme to use when navigating your site.
Solution: Store user's selection using Spring Session scoped bean

1. Annotate your bean

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserSelection{
   private String selectedTheme;
   //and other session values

   public void setSelectedTheme(String theme){
        this.selectedTheme=selectedTheme;
   }

   public String getSelectedTheme(){
       return this.selectedTheme;
   }

}

2. Inject your session scoped bean

@Controller
@RequestMapping("/")
public class SomeController{
   private UserSelection userSelection;

   @Resource
   public void setUserSelection(UserSelectio userSelection){
         this.userSelection=userSelection;
   }

   @RequestMapping("saveThemeChoice")
   public void saveThemeChoice(@RequestParam String selectedTheme){
        userSelection.setSelectedTheme(selectedTheme);
   }

   
   public String doOperationBasedOnTheme(){
          String theme=userSelection.selectedTheme();
 
          //operation codes
   }

}
In above code snippet, Although 'SomeController' has scope of singleton(default scope of Spring bean), each session will have its own instance of UserSelection. Spring will make the judgement, and inject a new instance of UserSelection if the request is a new session.

Required jars

Besides spring library, aopalliance and cglib jar are also required
http://mvnrepository.com/artifact/cglib/cglib-nodep
http://mvnrepository.com/artifact/aopalliance/aopalliance

Monday, June 4, 2012

Spring Custom Converter

Recently I ran into a problem where Spring would automatically convert comma separated String into String array, and quick search in google, I found people have the same problem on stackoverflow.com
http://stackoverflow.com/questions/4998748/how-to-prevent-parameter-binding-from-interpreting-commas-in-spring-3-0-5

Read more about Spring Converter http://static.springsource.org/spring/docs/current/spring-framework-reference/htmlsingle/spring-framework-reference.html#core-convert

Just a summary of the solution.

1. Create Custom Converter for String to String[]

import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;

public class CustomStringToArrayConverter implements Converter{
   @Override
    public String[] convert(String source) {
        return StringUtils.delimitedListToStringArray(source, ";");
    }
}

2. Register the Custom Conveter.

specify this conversion service bean in your configuration:


    
        
            
        
    

Thursday, May 3, 2012

Configure log4j for Spring MVC

1. Add following to web.xml


    log4jConfigLocation
    
    classpath:log4j.properties


    log4jExposeWebAppRoot
    false




    org.springframework.web.util.Log4jConfigListener

2. Create log4j factory bean in applicationContext.xml


3. Use it


@Component
public class SomeComponent{
    private Log logger;
  
    @Resource
    public void setLogger(Log logger){
       this.logger=logger;
    }


}

Sample log4j.properties
Spring MVC Sample Project

Wednesday, April 25, 2012

log4j.properties

Following is a sample log4j.properties, which output all logs to console and writes INFO+ level log to a file
#default log level is set to 'debug' it will output all log to console 
log4j.rootLogger=debug,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %5p %c{1}:%L - %m%n

#log level that is >=INFO, will use defaultLog definition for packagename
log4j.category.packagename=INFO, defaultLog

#define the log file directory
log.dir=/some/directory/logname.log

datestamp=yyyy-MM-dd/HH:mm:ss.SSS/zzz
roll.pattern.daily=.yyyy-MM-dd

#defines defaultLog, log file is rotated daily
log4j.appender.defaultLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.defaultLog.DatePattern=${roll.pattern.daily}
log4j.appender.defaultLog.File=${log.dir}
log4j.appender.defaultLog.layout=org.apache.log4j.PatternLayout
log4j.appender.defaultLog.layout.ConversionPattern=%d{${datestamp}} [%t] %-5p %m%n

Friday, April 20, 2012

Create Spring MVC maven project

Recently, I was working on a project that requires Spring MVC with maven. Following are the steps that guide you setting up the project. Before you start, make sure you have maven installed in your machine, or follow this link to maven download page.

Create a basic maven project 

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=com.mycompany.app -DartifactId=my-app

With couple other prompts such as choosing version number, maven should then create a basic maven project structure.


Create Web Application structure

open up the folder that maven has created, and under src/main, create two new folders, 'resources' and 'webapp'. Your folder structure should looks like following

./pom.xml
./src
./src/main
./src/main/java
./src/main/resources
./src/main/webapp
./src/main/webapp/WEB-INF
./src/test
./src/test/java
At the root of the directory structure is a XML file (always called pom.xml) that Maven expects. The pom.xml (POM is short for Project Object Model) describes the things specific to your project that can't be inferred automatically like dependencies, the name of the project, etc.

DirectoryDescription Directory's Contents (relative to the project root)
src/main/javaContains the Java source code for your project
src/main/resourcesContains any classpath-relative resources for your project (like, a Spring application context .xml file)
src/main/webappthe root web context folder for your web application files, such as WEB-INF, jsp,etc
src/test/javaContains the java source code for your test classes. This directory will not be included in the final build. All tests herein will be compiled and all tests will be run. If the tests fail, it aborts the build.




Modify pom.xml

replace pom.xml with http://codesfusion.blogspot.com/2012/04/spring-mvc-maven-pom_19.html which already includes the most basic dependencies for spring mvc project


Build your war

go to the root of your application folder
mvn clean package

this will build your project and package it into a war file, which you can then deploy to your web application server


Following is a complete spring mvc setup using the instructions above. You can download it and revise for your mvc application
Sample Spring MVC Project
To import the project into your eclipse, you can use m2eclipse for your Eclipse IDE. http://www.sonatype.org/m2eclipse/

Thursday, April 19, 2012

Spring MVC maven pom