Category Archives: spring

Error while running junit with Spring 3.2


My first attempt of upgrading project to use spring 3.2.0.RELEASE.

I was trying to run bunch of Junit test cases (which run fine with 2.5.6 ) , i got following error


java.lang.NoSuchFieldError: NULL
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:532)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)

 

After searching google couple of suggestions people suggested

Spring 3.2 may not be compatible with old version of spring, so make sure about it.
Junit should be 4.5 + . I changed to 4.10
It didnt work then I found the class “TypeValue” is part of spring-expression jar file. So i added it explicitly with version 3.2 and it worked .

Happy Coding !!

Resolving Spring error: No unique bean of type is defined expected single matching bean but found 2


Error for ServeChild1Controller: No unique bean of type [com.service.ParentService] is defined: expected single matching bean but found 2 child1service, child2service

This error occurs if there are two beans implementing the same interface and referenced.

public interface ParentService{}
@Service("child1service")    
public class Child1 implements ParentService{}

@Service("child2service")
public class Child2 implements ParentService{}
public class ServeChild1Controller extends AbstractController{

 @Autowired
 public ServeChild1Controller(@Qualifier("child1service") ParentService child1service){
 super(child1service)
  } 

The following problem can be resolved using @Qualifier

@Service("child1service")
@Qualifier("child1service")
public class Child1 implements ParentService{}

@Service("child2service")
@Qualifier("child2service")
public class Child2 implements ParentService{}

Load property file outside the war file using Spring 3


At times it is required to load properties not present in the war file. Typical usage can be have a war/jar file bundled and having property file for different environment such as dev, QA and PROD. It easy to put outside the war so that everytime build is not required. Fortunately is pretty simple in Spring 3.

Just mention this in spring config

<bean id="placeholderConfigConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName">
    <value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
<property name="ignoreUnresolvablePlaceholders">
    <value>true</value>
</property>
<bean
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="file:${config}" />
</bean>

The value of config can be set a -Dconfig in runtime environment. Like it project is run using maven it can be set as MAVEN_OPTS parameter.

It you want smarter way then

 <context:property-placeholder location="file:${config}"/>

Spring 3 MVC Annotations tutorial


This post will give brief idea about creating views, controller in Spring.

Note: The code can be downloaded. URL for download is present at the end.

A simple example : Store the information of a person. The property of a person is Name and City with a unique id.
The model class will be


public class PersonForm {

	private String name;
	private String city;
	private int id = -1;
	
	public PersonForm(int id,String name, String city ) {
		this.name = name;
		this.city = city;
		this.id = id;
	}
	public PersonForm() {
		// TODO Auto-generated constructor stub
	}
	// include getters and setters
}

Following functionalities can be defined:

  • Create a user
  • Edit a user
  • Delete a user
  • Show all users

The url mappings can be defined

URL Function jsp page
/person , Request Type = GET Show all users show.jsp
/person , Request Type = POST Save a user user.jsp
/person/newuser , Request Type = GET/td>

Show a blank form to enter user details user.jsp
/person/delete/{id} , Request Type = POST Delete a user show.jsp
/person/update/{id} , Request Type = POST Update a user user.jsp

Note: The user is stored simply using a HashMap ( for simplicity) . Ideally all calls should go to DB.
Lets create the Controller where all the actions happen.

@RequestMapping("/person")
@Controller
/** Displaying CRUD functionality. **/
public class PersonController {
	
	Map<Integer, PersonForm> personList = new HashMap<Integer, PersonForm>();
	static int  id = 0;
	
	/**
	 * Save a user and return back to display all users
	 */
	@RequestMapping(method=RequestMethod.POST)
	public ModelAndView save(PersonForm form,BindingResult errors, HttpServletRequest request, HttpServletResponse response){
		if(form.getId() == -1){
		id++;
		form.setId(id);
		personList.put(id,form);
		}else{
			personList.put(form.getId(), form);
		};
		ModelMap map = new ModelMap();
		Iterator iter = personList.keySet().iterator();
		List<PersonForm> newMap = new ArrayList<PersonForm>();
		while(iter.hasNext()){
			Object key = iter.next();
			if(key != null)
				newMap.add(personList.get(key));
		}
		map.put("persons",newMap);
		return new ModelAndView("show",map);
	}
	
	@RequestMapping(value="/newuser",method=RequestMethod.GET)
	public ModelAndView newUser(){
		PersonForm form = new PersonForm();
		ModelMap map = new ModelMap();
		map.put("person", form);
		return new ModelAndView("user",map);
	}
	
	/**
	 * 
	 * Display all users
	 */
	@RequestMapping(method=RequestMethod.GET)
	public String displayAll( HttpServletRequest request){
		ModelMap map = new ModelMap();
		Iterator iter = personList.keySet().iterator();
		List<PersonForm> newMap = new ArrayList<PersonForm>();
		while(iter.hasNext()){
			Object key = iter.next();
			if(key != null)
				newMap.add(personList.get(key));
		}
		map.put("persons",newMap);
		request.setAttribute("persons", newMap);
		return "show";
	}
	/** Delete a user and return back to all list **/
	@RequestMapping(value="/delete/{id}")
	public String delete(@PathVariable String id, HttpServletRequest request){
		personList.remove(Integer.parseInt(id));
		Iterator iter = personList.keySet().iterator();
		List<PersonForm> newMap = new ArrayList<PersonForm>();
		while(iter.hasNext()){
			Object key = iter.next();
			if(key != null)
				newMap.add(personList.get(key));
		}
		request.setAttribute("persons", newMap);
		return "show";
	}
	/** Update a user and return back to all list **/
	@RequestMapping(value="/update/{id}")
	public ModelAndView update(@PathVariable String id){
		ModelMap map = new ModelMap();
		map.put("person", personList.get(Integer.parseInt(id)));
		return new ModelAndView("user",map);
	}
}

Here all the actions happen:

  • @Controller: is used to tell Spring that PersonController is a controller
  • @RequestMapping(class-level): Annotation for mapping web requests onto specific handler classes and/or handler methods.All urls inside this controller should precede with the url mentioned as the value.
  • @RequestMapping(method-level): The function will be called if the url maps the given value. Other attributes can be set as RequestType(GET or POST etc) .
  • ModelAndView: This class merely holds both(Model and view) to make it possible for a controller to return both model and view in a single return value. The object tell which view to resolve and what model object should be passed.
  • ModelMap: Implementation of Map(LinkedHashMap),building model data for use with UI tools.Basically replacement of setting values as request attribute.
  • Method such as delete and displayAll returns the String. The return value is mapped to view name. The view name is resolved using InternalResourceViewResolver configured in mvc-dispatcher-servlet.xml.
  • The update or delete url are mapped as /update/{id}.. Any parameter defined in {} can be accessed using @PathVariable
  • Note: I have defined controller to view mapping in couple of ways. There are more ways to define.

Now its the turn of views:
user.jsp

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form:form commandName="person" method="post" action="/SpringMVC/person">
<form:hidden path="id" id="id" />
<table>
	<tr>
		<td><label>Name</label></td>
		<td><form:input path="name" id="name"/></td>
	</tr>
	<tr>
		<td><label>City</label></td>
		<td><form:input path="city" id="city"/></td>
	</tr>
	<tr>
		<td><input type="submit" name="save" value="save"/></td>
	</tr>
</table>	
</form:form>
</body>
</html>

This view is used to save and update the users.

index.jsp

<%@ page language="java" errorPage="/error.jsp" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<body>
	<h1>List Of People</h1>
	<table>
	<tr>
		<th>Name</th>
		<th>City</th>
	</tr>
	<c:forEach items="${persons}" var="person">
	<tr>
		<td>${person.name}</td>
		<td>${person.city}</td>
		<td>
			<a href="/SpringMVC/person/delete/${person.id}">DELETE</a>
		</td>
		<td>
			<a href="/SpringMVC/person/update/${person.id}">EDIT</a>
		</td>
	</tr>
	</c:forEach>
	</table>	
</body>
</html>

Now the configuration:
The web.xml is pretty basic .. Declaring the org.springframework.web.servlet.DispatcherServlet and loading the spring servlet.xml. The code can be downloaded at the end.

mvn-dispatcher-servlet.xml is very basic for this example

<context:component-scan base-package="com.common.controller" />
	<context:annotation-config />
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/pages/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>

This <context:annotation-config /> tells that spring in annotation enabled.
This <context:component-scan base-package> tells where beans are configured.
And InternalResourceViewResolver resolve view names to jsp pages present in WEB-INF/pages.

Download Code

Intergrating Twitter OAuth using java/spring/Twitter4j


The comprehensive link about Twitter approach for using Oauth (its same for other cases too ) can be found
TwitterOAuth
To cut it short following are the important steps:

Get the consumer key and consumer secret.Dev Twitter

Twitter API

Note: If you are going to make an webapp dont forget to put a valid url in the “CallBack Url” field. The valid url can be back to your localhost. But dont put “localhost” as twitter doesnt provide support. I had put http://127.0.0.1:8080/SpringMVC/callback for this application. The value of url can be changed at runtime.

Following are the steps using browser.. My homepage url is

http://localhost:8080/SpringMVC/welcome


When a user clicks on the hyperlink an oauth authorize request is sent to twitter by sharing the token key and token secret and user is redirected to twitter page.

After login into Twitter the user will be redirected to the callback url and the username will be displayed.

I am using Twitter4j for connecting with Twitter.

@RequestMapping("/welcome")
@Controller
public class WelcomeController {
        @Autowired
	private OAuthToken oauthToken;
        Twitter twitter = new TwitterFactory().getInstance();

	@Autowired
	private MyAccessToken accestoken;
	@RequestMapping(method = RequestMethod.GET)
	
	public String printWelcome(HttpServletResponse response,HttpServletRequest request) {

		twitter.setOAuthConsumer(oauthToken.getConsumerKey(),
		oauthToken.getConsumerSecret());
		RequestToken requestToken;
		try {
			
			String callbackURL = "http://127.0.0.1:8080/SpringMVC/callback";
             requestToken = twitter.getOAuthRequestToken(callbackURL);
             String token = requestToken.getToken();
 			String tokenSecret = requestToken.getTokenSecret();
			accestoken.setTokensecret(tokenSecret);
			accestoken.setToken(token);
			String authUrl = requestToken.getAuthorizationURL();
			request.setAttribute("authUrl", authUrl);
		} catch (TwitterException e) {
			e.printStackTrace();
		} 
		
		return "login";
	}
}

The callback url can be set as shown above. The MyAcessToken is used to persist the token for the request.

My login.jsp is

 <a href='<%=request.getAttribute("authUrl") %>'>Sign in with Twitter</a>

So when the user enters http://127.0.0.1/SpringMVC/welcome , they will be redirected to login.jsp.

When the user clicks on the “Sign in” link , it will be redirected to Twitter login site and then will be redirected to the callback url set. The controller to handle callback url is

@Controller
@RequestMapping("/callback")
public class CallBackController extends AbstractController{</code>

	@Autowired
	private OAuthToken oauthToken;
	
	@Autowired
	private MyAccessToken accessToken; 
	@Override
	@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
	protected ModelAndView handleRequestInternal(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
			Twitter twitter = new TwitterFactory().getInstance();
			
			twitter.setOAuthConsumer(oauthToken.getConsumerKey(), oauthToken.getConsumerSecret());
			String verifier = request.getParameter("oauth_verifier");
	       RequestToken requestToken = new RequestToken(accessToken.getToken(), accessToken.getTokensecret());
	       AccessToken accessToken = twitter.getOAuthAccessToken(requestToken,verifier);
	       twitter.setOAuthAccessToken(accessToken);
	       User user = twitter.verifyCredentials();
	       System.out.println(user.getName());
	       ModelAndView model = new ModelAndView("hello");
	       model.addObject("message", user.getName());
	       return model;
	}
}

Once the user comes back it will be redirected to “hello.jsp” with user name displayed.Note the MyAccessToken set for user before request is made is used here.

<html>;
<body>
<h1>Twitter Login successful for : ${message}</h1>
</body>
</html>

The oauthtoken is stored and configured in dispatcher-servlet xml which is loaded using web.xml

<bean>
<context:component-scan base-package="com.common.controller" />

<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="oauthToken" class="com.common.OAuthToken">
<property name="consumerKey" value="yourconsumerkey"/>
<property name="consumerSecret" value="yourconsumersecret"/>
</bean>
<bean id="accessToken" class="com.mkyong.common.MyAccessToken"/>
</beans>

The other model classes OAuthToken and MyAccessToken :

public class OAuthToken {

	public String consumerKey;
	public String consumerSecret;
	public String getConsumerKey() {
		return consumerKey;
	}
	public void setConsumerKey(String consumerKey) {
		this.consumerKey = consumerKey;
	}
	public String getConsumerSecret() {
		return consumerSecret;
	}
	public void setConsumerSecret(String consumerSecret) {
		this.consumerSecret = consumerSecret;
	}
}
public class MyAccessToken {

	private String token;
	private String tokensecret;
	public String getTokensecret() {
		return tokensecret;
	}
	public void setTokensecret(String tokensecret) {
		this.tokensecret = tokensecret;
	}
	public String getToken() {
		return token;
	}
	public void setToken(String token) {
		this.token = token;
	}
	
}

Download Source Code