Der Application Support ist eine Bibliothek mit integrativen Code für JSF2, JSF Ext, Spring Framework und JPA / Hibernate. Ziel ist, häufig verwendete Komponenten für den einfachen Aufbau einer Applikation erfolgreich zu kombinieren. Application Support liefert eine Reihe nützlicher Bausteine.

Context#

Während in JSF-Applikationen der JSF-Context durch FacesContext.getCurrentInstance() geliefert werden kann, stellt der Application Support den Spring- und damit meist den allgemeinen Bean-Support durch die Klasse com.intersult.application.spring.Context zur Verfügung:

MethodeBeschreibung
getContextLiefert den (Spring-)ApplicationContext
createEntityManagerLiefert den EntityManager zum Durchführen von Datenbank-Operationen außerhalb der Spring-Injection, wie zum Beispiel beim Bau von Validators und Converters. Der so erhaltene EntityManager muss in jedem Fall in einem try-finally-Block mit der Methode close geschlossen werden. Andernfalls entsteht ein Speicher- und Ressourcen-Leck.

Bean-Validators#

Die Annotations direkt an Java-Bean-Properties stellen sicher, dass ein Wert nur in einem bestimmten Zustand in die Datenbank geschrieben wird. Bean-Validation in JSF2 validiert die Annotations bereits im Frontend und bietet die Möglichkeit einen Fehler unmittelbar dem Benutzer zu melden. Die Annotations können auch in anderen Beans verwendet werden, die nicht in die Datenbank geschrieben werden. Die saubere Konfiguration wird dabei durch JSF Ext hergestellt.

Spring Custom Injections#

Der Application-Support stellt das Interface InjectionFactory<A extends Annotation> zur Verfügung. Damit können auf sehr einfache Weise eigene Injection-Anntotations erstellt werden.

Beispiel Scope-Injection#

Generell ist es in Spring möglich, durch die @Value-Annotation beliebige Werte durch EL-Expression zu injecten, zum Beispiel durch #{scope.field} einen Wert aus einem JSF Ext Scope. Die Nachteile bestehen in der jeweiligen Angabe der EL-Expression, obwohl der Feldname bereits als Information ausreichend wäre, sowie dass der Wert nicht Null sein darf.

Daher eine ScopeInjectionFactory:

@Component
public class ScopeInjectionFactory implements InjectionFactory<ScopeValue> {
	@Override
	public Class<ScopeValue> getAnnotationType() {
		return ScopeValue.class;
	}
	@Override
	public Object create(Class<?> type, String beanName, ScopeValue annotation) {
		Scopes scopes = Scopes.instance();
		if (scopes == null)
			return null;
		Scope scope = scopes.getScope();
		if (scope == null)
			return null;
		return scope.get(beanName);
	}
}

Die dazugehörige Annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface ScopeValue {
}

Session Events#

In einem Servlet treten neben dem HttpServletRequest auch Events vom Typ HttpSessionEvent auf, wie zum Beispiel bei einem HttpSessionListener. Möchte man darin Spring-Operationen durchführen, braucht man einen ordentlich initialisierten Spring-Context inklusive den RequestAttributes.

Die Klasse EventRequestAttributes stellt diese zur Verfügung:

WebApplicationContext applicationContext =
	WebApplicationContextUtils.getRequiredWebApplicationContext(event.getSession().getServletContext());
EventRequestAttributes request = new EventRequestAttributes(event);
try {
	RequestContextHolder.setRequestAttributes(request);
} finally {
	request.requestCompleted();
	RequestContextHolder.resetRequestAttributes();
}

Die Klasse ContextSessionListener implementiert dies bereits für den HttpSessionListener, sodass sie bequem abgeleitet werden kann:

public class UserListener extends ContextSessionListener {
	@Override
	public void sessionCreated(HttpSessionEvent event, WebApplicationContext applicationContext) {
		Authenticator authenticator = applicationContext.getBean(Authenticator.class);
		authenticator.createSession(event.getSession());
	}
	@Override
	public void sessionDestroyed(HttpSessionEvent event, WebApplicationContext applicationContext) {
		Authenticator authenticator = applicationContext.getBean(Authenticator.class);
		if (authenticator.getCurrentUser() != null)
			authenticator.logout(event.getSession());
	}
}