ICE09 . playing with java, scala, groovy and spring .

Playing with Spring

Archive for August, 2008

Consuming Services – the Spring Web Service Client

Posted by ice09 on August 25, 2008

There is a downloadable zipped Eclipse project at the end of this post.

Having created a sample (mail) web service some posts ago, we would like to have a client consuming this service.

With Spring Web Services, this can easily be done by using the ubiquitous Template Pattern and, in this special case, the WebServiceTemplate . As the project structure can be downloaded, only the two important snippets are shown here:

The application-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="mailclient" class="de.mail.MailClient">
    	<property name="webServiceTemplate" ref="webServiceTemplate"/>
    </bean>

    <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

    <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
        <constructor-arg ref="messageFactory"/>
        <property name="marshaller" ref="marshaller"/>
        <property name="unmarshaller" ref="marshaller"/>
        <property name="defaultUri" value="http://localhost:8080/mailservice"/>
    </bean>

    <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
		<property name="classesToBeBound">
			<list>
				<value>org.mail.mailschema.MailRequest</value>
				<value>org.mail.mailschema.MailResponse</value>
			</list>
		</property>
	</bean>

</beans>

and the actual Web Service client:

package de.mail;

import org.mail.mailschema.MailRequest;
import org.mail.mailschema.MailResponse;
import org.springframework.ws.client.core.WebServiceTemplate;

public class MailClient {

	private WebServiceTemplate webServiceTemplate;

	public void setWebServiceTemplate(WebServiceTemplate webServiceTemplate) {
		this.webServiceTemplate = webServiceTemplate;
	}

	public boolean send(String user, String password, String from, String to, String subject, String content) {
		MailRequest request = new MailRequest();
		request.setFrom(from);
		request.setTo(to);
		request.setUser(user);
		request.setPassword(password);
		request.setContent(content);
		request.setSubject(subject);
		return ((MailResponse)webServiceTemplate.marshalSendAndReceive(request)).isResult();
	}

}

The servlet sample is not shown, since it is just for demonstration and not a nice piece of code. However, it exemplifies some Spring antipatterns, because DI is not used and the servlet is not Springified at all. But it’s only a sample showing how to use the Web Service client.
By deploying the servlet (or using mvn jetty:run again), a mail can be send by calling http://server/mailwebapp/Mailer?user=USER&password=PASSWORD&to=RECIPIENT@BLA.DE&from=me&subject=SUBJECT&content=MAILTEXT
But the actual code could be much nicer (also, it is definitely not safe – just a counter and a whitelist is added to prevent immediate abuse :))

Sample Mail Web Service client project:

Instructions:

  1. Download the wsclient-sample
  2. Download the mailwebapp-sample
  3. Download the maildatabinding

If correctly imported as Eclipse projects, the dependencies should be automatically resolved.
The mailwebapp can be deployed as a usual Web application which uses the Web Service client to call the Mail Web Service, which must be already deployed (compare the Spring Web Service post).

Posted in Mail, Maven, Spring Web Services | Tagged: , | 7 Comments »

Patters (cont’d): The Observer Pattern

Posted by ice09 on August 9, 2008

Download Eclipse project

I implemented the Observer Pattern with a central registry which is synchronized and uses WeakHashMaps, thereby trying to omit memory leaks.

The Notification Manager:

package observer;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class NotificationManager implements Observable {

	private Map<Integer, List<Observer>> observers = new WeakHashMap<Integer, List<Observer>>();

	private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	private final Lock read = readWriteLock.readLock();
	private final Lock write = readWriteLock.writeLock();

	public void notifyObservers(Object source, Object arg) {
		List<Observer> obs = null;
		read.lock();
		try {
			if (!observers.containsKey(source.hashCode())) {
				return;
			} else {
				obs = observers.get(source.hashCode());
			}
			for (Observer observer : obs) {
				observer.update(arg);
			}
		} finally {
			read.unlock();
		}
	}

	public void register(Object target, Observer observer) {
		List<Observer> obs = null;
		write.lock();
		try {
			if (!observers.containsKey(target.hashCode())) {
				obs = new ArrayList<Observer>();
			} else {
				obs = observers.get(target.hashCode());
			}
			if (!obs.contains(observer)) {
				obs.add(observer);
			}
			observers.put(target.hashCode(), obs);
		} finally {
			write.unlock();
		}
	}

	public void remove(Object target, Observer observer) {
		List<Observer> obs = null;
		write.lock();
		try {
			if (!observers.containsKey(target.hashCode())) {
				return;
			} else {
				obs = observers.get(target.hashCode());
			}
			if (!obs.contains(observer)) {
				return;
			}
			obs.remove(observer);
		} finally {
			write.unlock();
		}
	}

	public String toString() {
		return "#Observers: ".concat(String.valueOf(observers.entrySet().size()));
	}

}

The Observer interface:

package observer;

public interface Observer {

	public void update(Object arg);

}

The Observable interface implemented by the NotificationManager:

package observer;

public interface Observable {

	public void register(Object target, Observer observer);
	public void remove(Object target, Observer observer);

	public void notifyObservers(Object source, Object arg);

}

The unit test class extending AbstractDependencyInjectionSpringContextTests:

package observer;

import org.springframework.test.AbstractDependencyInjectionSpringContextTests;

public class ObserverTest extends AbstractDependencyInjectionSpringContextTests implements Observer {

	protected NotificationManager notificationmanager;

	public ObserverTest() {
		setPopulateProtectedVariables(true);
	}

	public ObserverTest(String s) {
		super(s);
		setPopulateProtectedVariables(true);
	}

	public void testNM() {
		ObservableObject oo = new ObservableObject();
		notificationmanager.register(oo, this);
		oo.notifyObs();
		notificationmanager.remove(oo, this);
		oo.notifyObs();
	}

	@Override
	protected String[] getConfigLocations() {
		return new String[]{"applicationContext-test.xml"};
	}

	public void update(Object arg) {
		System.out.println("called with " + arg);
	}

	private class ObservableObject {

		public void notifyObs() {
			notificationmanager.notifyObservers(this, "bla");
		}

	}

}

The config, the notificationmanager is injected into the protected variable in the junit test:

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

	<bean id="notificationmanager" class="observer.NotificationManager"/>

</beans>

Posted in Patterns | Tagged: , | Leave a Comment »

Patterns with Spring

Posted by ice09 on August 4, 2008

Download Eclipse project

There are several articles about Patterns with Spring in “Enterprise” context, ie. on the server side and simulating more or less typical JEE Patterns. These are important, however, Spring has its use in small, batch and client side apps as well.
Therefore, it makes sense to recall old school Design Patterns, which can be used independently of the programming context, just to reuse good solutions for old problems.
However, working with Spring, it’s easy to recognize that Patterns must be adapted to Spring, since some of them do not make sense when working with Spring.
I will elaborate the most important and famous ones here in the context of Spring usage.

Factory Method Pattern

For two reasons, the Factory Method Pattern is not really useful in the Spring context:

  1. Spring’s BeanFactory implements a kind of Factory Pattern itself. It is easy to use different BeanFactories and therefore create different beans according to context. For example, using several XML-configurations and instantiating them in different ApplicationContexts gives you several bean factories configured with XML.
  2. Since with Spring injecting different beans is done by XML-configurations and pseudo-Singletons are used, the advantage of having a single point of changing bean instantiation is inherent to Spring.

Nevertheless, I implemented the almost original Factory Method Pattern below.

Usually, the beans-factory-lookup-method-injection is referred as the factory method implementation in spring. Thought this is certainly true with respect to the actual pattern, it is difficult to see the advantage of this approach in contrast to just injecting a bean. This is even more transparent and there is no magic in it.
To actually make use of creating different objects, I made up the following scenario, which allows for creating different objects during runtime. There is nothing special in it, just plain usage of Spring, magic excluded.

package sample.factory;

public enum Type {

	FIRST, SECOND;

}

An interface to identifying the objects:

package sample.factory;

public interface ClassType {

	Type getId();

}

First type of object:

package sample.factory;

public class FirstType implements ClassType {

	@Override
	public Type getId() {
		return Type.FIRST;
	}

	@Override
	public String toString() {
		return getId().toString();
	}

}

Second type of object:

package sample.factory;

public class SecondType implements ClassType {

	@Override
	public Type getId() {
		return Type.SECOND;
	}

	@Override
	public String toString() {
		return getId().toString();
	}

}

The factory itself, objects will be injected:

package sample.factory;

import java.util.Map;

public class FactorySample {

	private Map<Type, ClassType> identifiers;

	public void setConcreteClasses(Map<Type, ClassType> i) {
		this.identifiers = i;
	}

	public ClassType createClassOfType(Type type) {
		switch (type) {
			case FIRST : return identifiers.get(type);
			case SECOND : return identifiers.get(type);
			default : return null;
		}
	}

}

Main class which retrieves factory bean and creates a object of second type:

package sample.factory;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
		FactorySample factory = (FactorySample) app.getBean("factory");
		ClassType i = factory.createClassOfType(Type.SECOND);
		System.out.println(i);
	}

}

Finally, the spring config (entry key Strings are converted automagically by Spring):

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

	<bean id="factory" class="sample.factory.FactorySample">
		<property name="concreteClasses">
			<map>
				<entry key="FIRST">
					<ref local="FirstType" />
				</entry>
				<entry key="SECOND">
					<ref local="SecondType" />
				</entry>
			</map>
		</property>
	</bean>
	
	<bean id="FirstType" class="sample.factory.FirstType"/>
	
	<bean id="SecondType" class="sample.factory.SecondType"/>

</beans>

Posted in Patterns | Tagged: , | Leave a Comment »