Build RESTful Web Service using Spring MVC Framework


The post is about how to build a RESTful web service using Spring MVC framework.The main advantage of using Spring Framework is the modules within the application are loosely coupled achieved by Dependency Injection (Inversion of Control).

Project Structure

  • rest.common – Common classes serve architectural purposes
  • rest.controller – Controllers
  • rest.dao – Data access objects which communicate with database storage
  • rest.model – Domain models
  • – Services provides the public API and act as a transaction boundary
Project Structure

Project Structure


I use log4j as its logging framework. The configuration file is located at src/main/resources/ In order to track all the request, I implement a custom interceptor which extends HandlerInterceptorAdapter. I override the preHandle method to log every request.

Register Interceptor under Spring context configuration:

	<bean class="" />

public class GeneralInterceptor extends HandlerInterceptorAdapter {

	private static final Logger logger = Logger

	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {

		StringBuilder sb = new StringBuilder();
		sb.append(request.getRequestURI() + " user:" + request.getRemoteUser());;

		return super.preHandle(request, response, handler);

Exception Handling

I use @ExceptionHandler and @ControllerAdvice to apply the exception handling across the whole application. The handler currently logs the error and returns HTTP status code 400 (Bad Request).

public class GlobalDefaultExceptionHandler {
	private static final Logger logger = Logger

	void handleBadRequest(HttpServletRequest req, Exception ex)
			throws Exception {

		logger.error(req.getRequestURL().toString(), ex);

		// If the exception is annotated with @ResponseStatus rethrow it and let
		// the framework handle it
		if (AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class) != null)
			throw ex;


I use Basic HTTP Authentication provided by Spring Security framework. In order to enable the basic http authentication, there are three changes need to be made:

  1. Add maven dependency
  2. <!-- Security -->
  3. Register DelegatingFilterProxy as a filter in web.xml
  4. <filter>
  5. Create security-context file stores security configuration. The configuration defines users, roles and access rules for specific url patterns.
  6. <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns=""
        xmlns:xsi="" xmlns:security=""
        <security:http auto-config='true' create-session="stateless">
            <security:intercept-url pattern="/rest/**"
                access="hasRole('ROLE_TEST_USER')" />
            <security:intercept-url pattern="/**" access="denyAll" />
            <security:http-basic />
            <security:csrf disabled="true" />
                    <security:user name="testuser" password="testuserpw"
                        authorities="ROLE_TEST_USER" />

Unit Testing

I utilize Spring MVC Test Framework along with Mockito (for mocking) and JsonPath (for assertions of returned JSON documents) libraries to write JUnit tests.

@ContextConfiguration({ "file:src/test/resources/applicationContext.xml" })
public class RestControllerTest {

	private WebApplicationContext wac;

	private PatientService patientServiceMock;

	private MockMvc mockMvc;

	 * @throws java.lang.Exception
	public void setUp() throws Exception {
		mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();

	public void testGetPatientsMethod() throws Exception {

		Patient fake = new Patient();



	public void testGlobalExceptionHandlerReturn400() throws Exception {

				new SQLException("I am a fake SQL exception"));

	public void testSavePatientMethod() throws Exception {
		Patient fake = new Patient();


Source Code


  1. Exception Handling in Spring MVC
  2. Adding Http Basic Auth to RESTful Services in Java and Spring
  3. Unit Testing of Spring MVC Controllers: REST API
Tagged with: , ,
Posted in Java, Programming

Eclipse hangs at the Android SDK Content Loader

Have you experienced Eclipse hangs at the Android SDK Content Loader? I ran into this problem once in a while. Try this:

  1. Locate your Eclipse executable
  2. Run command “eclipse -clean” to launch Eclipse in “Clean Mode”
  3. Once the Eclipse starts normally, you can go back to use your old shortcut to launch Eclipse next time. …. until it gets stuck again 🙂

The idea behind this is that the “Clean Mode” will wipe out all the cached data created by Eclipse. So hopefully that little dirt blocks your Eclipse will be cleaned up. 

Cheers. Happy coding!

Read more:

Tagged with:
Posted in Android, Programming

How to use cronjob to execute periodical MySQL queries?

For my new project, I needed to aggregate user view counts periodically.  After i googling around, i figured using cronjob probably was the most popular way of doing it. So i wrote my sql queries to a file and schedule a cronjob to execute the script every 30 minutes. Here are the detail steps of how i did it:

1. Write sql queries to a text file named recurring-job.sql. Put it under your user’s home directory /home/[user].

update videos v
set number_of_views = (select count(1) from video_views where video_id = v.video_id),
last_update_time = NOW();

2. Edit cronjob by issuing following commands.

crontab -e [for edit] -l [for display]

3. Add a new line into cronjob configuration. This configuration will execute the sql script every 30 minutes.

# m h dom mon dow command
*/30 * * * * /usr/bin/mysql --user=[user_name] --password=[password] [db_name] < /home/[user]/recurring-job.sql

4. Hit ctrl-X and type “Yes” to save and exit.

That’s it! But how do I make sure the job actually run?

grep CRON /var/log/syslog

Happy Coding!

Tagged with: , ,
Posted in Programming

Back up your MySQL database!

Couple days ago, short after I woke up in the morning, I decided to do some  data cleaning work to my live MySQL database. So I wrote a not so complicated SQL statement based on the logic in my head and hit “Execute”. Wait~ I just deleted all the freaking data, around 50k entries, in that table! Those records are the user-generated data for about 6 months period. Thank god I back up my database once a week. So I recovered my database from the snapshot from 3 days ago and only lost a small portion of data.

Here are the lessons I learned:

  1. Don’t run SQL statement against your production database unless you are fully awake 🙂
  2. Backup your database regularly!

Following are the Unix commands I use to back up and restore my database:

Back up!

mysqldump -u root -p your-database-name | gzip > "/home/username/mysql_backups/your-database-name_`date '+%m-%d-%Y'`.sql.gz"

This command helps you back up your database in compressed format with a nice timestamp in the file name. For example: dbname_11-02-2012.sql.gz

Restore it

gunzip [backupfile.sql.gz]

This command unzips your backup file.

mysql -u root -p your-database-name < [backupfile.sql]

This command restores the database from the unzipped backup file.

Further Readings:

Tagged with: ,
Posted in Programming

Hibernate query optimization

Today I would like to share my experience of Query Optimization. I’ve heard of Query Optimization for a long time, but I’ve never realized how powerful it was until now. Following are some graphs showing how my system performed before and after I optimized my query. Not to mention that it cut my query time by 80%. Isn’t that amazing?

CPU usage before/after query optimization

IO rate before/after query optimization

My web service is using Hibernate in data access layer. At the beginning, I just wrote HQL (Hibernate Query Language) code to retrieve my objects based on business logic. And it worked. So I never thought about looking into the exact SQL query it generated. Until my query became slower and slower while my database grew bigger.

Here are some pointers I learned through the tuning process. (My frameworks: Hibernate + Spring Annotation)

1. Take a look at your actual queries

First make sure you set the show_sql property to true in your Hibernate configuration. Then you will see the Hibernate logs every SQL query in the stderrout.log file. Below is an example:

Hibernate: select photo0_.photo_id as col_0_0_, count(votes1_.vote_id) as col_1_0_, (select count(votes2_.vote_id) from votes votes2_ where photo0_.photo_id=votes2_.photo_id and votes2_.thumbs_up=0) as col_2_0_, (select count(comment3_.comment_id) from comments comment3_ where comment3_.photo_id=photo0_.photo_id) as col_3_0_, photo0_.photo_id as photo1_8_, photo0_.book_id as book2_8_, photo0_.inappropriate as inapprop3_8_, photo0_.thumbnail as thumbnail8_, photo0_.w_id as w5_8_ from photos photo0_ inner join votes votes1_ on photo0_.photo_id=votes1_.photo_id where (photo0_.inappropriate is null or photo0_.inappropriate=0) and votes1_.thumbs_up=1 and votes1_.time_stamp>? group by photo0_.photo_id order by count(votes1_.vote_id) desc limit ?

2. Use explain to analyze your query

Take the query logged by Hibernate and add explain keyword in front of the query. Run it against your database. Then you will get MySQL explains how it will process the query. What type of join? Which index will it use? etc.. Especially pay attention to the extra values from the result. Watch out “Using filesort” and “Using temporary“. Those indicators mean your query consumes higher CPU and memory. At least that was the reason slowed down my query significantly. And It turned out there was other way to achieve the same result without the heavy cost.

Further Reading ..

Tagged with: , ,
Posted in Programming

Monitoring latency in Jetty request log

Are you interested in the response time of your web page/service? As the number of users grows, my web service started to show some performance degradation. But I couldn’t know how slow it was since I didn’t have elapse time measurement. In other words, I need a baseline in order to optimize my server configuration and application. So, I was interested.

The default request log from Jetty is very neat. The default NCSARequestLog logger records pretty much everything that I am interested (client IP, date, method, URL, result, size etc..) except the elapsed time. This is the default request log that it creates: –  –  [25/Jul/2012:23:59:58 +0000] “GET /jetty/tut/XmlConfiguration.html HTTP/1.1” 200 708394

The good news is that NCSARequestLog has an option to include latency in the log entry. Here is how to do it:

My environment (Ubuntu 10.04 + Jetty 6.1.22)

  1. Open [JETTY HOME]/etc/jetty.xml.
  2. Locate <Ref id=”RequestLog”> section.
  3. Add <Set name=”logLatency”>true</Set> to setter list.
  4. Save it and restart Jetty.
<Ref id="RequestLog">
 <Set name="requestLog">
  <New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
   <Set name="filename"><SystemProperty name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log</Set>
   <Set name="filenameDateFormat">yyyy_MM_dd</Set>
   <Set name="retainDays">90</Set>
   <Set name="append">true</Set>
   <Set name="extended">false</Set>
   <Set name="logCookies">false</Set>
   <Set name="LogTimeZone">EST</Set>
   <Set name="logLatency">true</Set>

That’s it. Now latency (in millisecond) is logged at the end of the log line. Enjoy 🙂 –  –  [25/Jul/2012:23:59:58 +0000] “GET /jetty/tut/XmlConfiguration.html HTTP/1.1” 200 708394 888
Tagged with: ,
Posted in Programming

Step-by-step of how to add pinch and double-tap zoom to ImageView

Recently, I added pinch/double-tap zoom feature to one of my projects. I would like to share how I did it in case other people need to do exactly same thing.

There are a couple of solutions out there. But not all of them work for me. After spent some time trying out solutions from StackOverFlow, I found a nice work provided by Alessandro, which works great for me. It supports both pinch and double-tap zoom. Following are the steps I took to integrate his ImageViewTouch class to my app.

1. Check out his code from Github.

2. There are two projects under his repository. ImageViewTouch project is the one that we need. Compile it.

3. After successful compilation. You will get a imageviewtouch.jar file inside the bin folder.

4. Copy the imageviewtouch.jar file to your Android project. You could create a sub-directory named libs under your project and put the jar under it.

5. Right click the jar and choose Build Path > Add to Build Path.

6. Declare ImageViewTouch component in your layout xml. Remember to put the full class name instead of just “ImageViewTouch” in your declaration tag.

android:scaleType="centerCrop" />

7. In your Activity class, do following to assign Bitmap to the ImageViewTouch component.

ImageViewTouch img = (ImageViewTouch) dialog.findViewById(;

8. That’s it. Test it out!


Tagged with: ,
Posted in Android, Programming