Techblog

Herzlich Willkommen im Communardo Techblog, dem Entwickler-Weblog von Communardo. An dieser Stelle werden Ideen, Problemlösungen, Tipps und Problemstellungen rund um die Entwicklung webbasierter Software vorgestellt.

techblog-teaser

Liferay 6.1 mit Spring 3.2 : Programmatisches Hochladen von Dateien in Dokumentenbibliothek

, von

Das programmatische Hochladen von Dateien in die Dokumentenbibliothek, mit den Hilfsmitteln die durch Spring zur Verfügung gestellt werden, ist nicht ohne Weiteres mit Liferay möglich. Dieser Beitrag zeigt wie ein Dateiupload in das Liferay Portal im eigenen Portlet umgesetzt werden kann.  Artikel vollständig lesen

Annotaion in Spring 3.0

, von

Annotations erfreuen sich immer größerer Beliebtheit. Egal wo man hinsieht, fast alles kann man mittlerweise damit machen (Caching, Persistenz, deklarative Services in OSGi, …). Seit Spring 3.0 gibt es nun auch im Springframework Annotations.

Ohne Annotations

Als Beispiel soll ein einfacher HalloWellt-Controller dienen. Klassen, die bei SpringMVC als Controller-Klassen fungieren, müssen das Interface Controller implementieren oder einfach von einer bestehenden Implementierungsklasse ableiten (z.B. SimpleFormController).

<bean id="urlMapping" class="org.springframework…SimpleUrlHandlerMapping">
  <property>
    <props>
      <prop key="/hallo">halloController</prop>
    </props>
  </property>
</bean>
<bean name="halloController" class="de.communardo.spring.mvc.HalloWeltController"/>

Über das URL-Mapping werden Conroller-Klassen unter einer URL registriert. Dieses wird durch das DispatcherServlet bei eingehenden Requests ausgewertet. In unserem Beispiel wird bei /hallo der HalloControlleraufgerufen.

Mit Annotations

Mit Spring 3.0 wird durch Einführung von Annotations vieles einfacher. Zum einen fällt das Implementieren oder Ableiten von Controller-Interfaces oder Klassen weg. Jede Klasse kann ein Controller sein. Entscheidend ist die Annotation @Controller.

package de.communardo.spring.mvc;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

<strong>@Controller</strong>
public class HalloWeltController {

  <strong>@RequestMapping</strong>(value = "/hallo")
  public <strong>@ResponseBody</strong> String helloWorld() {
    return "Hallo Welt";
  }
}

Über die Annotation @RequestMapping werden URL-Pfade auf Methoden gemappt. Über @ResponseBody wird der Rückgabewert String (="Hallo Welt") auf Response.out geschrieben.

Damit Spring die Klassen mit Annotation (er)kennt, müssen folgende 2 Zeilen in der Spring-XML-Konfiguration aufgenommen werden.

<mvc:annotation-driven />
<context:component-scan base-package= " de.communardo.spring.mvc" />

Dependency Injection

Eines der zentralen Themen bei Spring ist Dependency Injection – Abhängigkeiten zwischen Komponenten werden durch den Container per Setter injiziert. Bei Klassen, die per Spring-XML erzeugt werden, gibt es da eine spezielle Notation für das Injizieren von benötigten Komponenten.

<bean name="halloController">
  <property name="serviceLocater" ref="serviceLocater"/>
</bean>

<bean   class="de.communardo.spring.service.ServiceLocaterImpl"/>

Für Klassen, die per Annotation erzeugt werden, gibt es dafür entsprechende Annotation. Über die Annotation @Autowired werden per Setter eine Implementierung des Interfaces ServiceLocater injiziert.

package de.communardo.spring.mvc;

import org.springframework.beans.factory.annotation.Autowired;
import de.communardo.spring.service.ServiceLocater;

public class HalloWeltController {
  private ServiceLocater serviceLocater;

  <strong>@Autowired</strong>
  public void setServiceLocater(ServiceLocater serviceLocater) {
    this.serviceLocater = serviceLocater;
  }
}

FormController

Für das Formularhandling kommen weitere Annotations hinzu. @ModelAttribute definiert die Formbean, die an das Formular gebunden wird. Im Beispiel ist das userForm, die im Template per <form:form modelAttribute="userForm"> benutzt wird.

import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import de.communardo.spring.domain.User;
import de.communardo.spring.service.UserService;

<strong>@Controller</strong>
<strong>@RequestMapping</strong>("/editUser")
<strong>@SessionAttributes</strong>("userForm")
public class UserController {

  private static final String VIEW_TEMPLATE_USER = "user";
  private UserService userService;

  <strong>@RequestMapping</strong>(method = RequestMethod.POST)
  public String onSubmit(<strong>@ModelAttribute</strong>("userForm") UserForm userForm, BindingResult result, SessionStatus status) {

    new UserValidator().validate(userForm, result);
    if (result.hasErrors()) {
      return VIEW_TEMPLATE_USER;
    }
    userService.storeUser(new User(userForm.getFirstName(), userForm.getLastName(), userForm.getEmail()));
    return VIEW_TEMPLATE_USER;
  }

  <strong>@RequestMapping</strong>(method = RequestMethod.GET)
  public String setupForm(Model model) {
    UserForm userForm = new UserForm();
    model.addAttribute("userForm", userForm);
    return VIEW_TEMPLATE_USER;
  }

  <strong>@Autowired</strong>
  public void setUserService(UserService userService) {
    this.userService = userService;
  }
}

Ldap Schnittstelle mit Spring und iBatis

, von

Die Realisierung einer Schnittstelle zu einem Ldap Respository ist nach wie vor mit einem erheblichen Implementierungsaufwand verbunden und gestaltet sich oft als sehr unflexibel z.B. gegenüber Änderungen am Ldap Schema.

Beispiel für ein Ldap Schema und einen Ldap Eintrag:

Im Folgenden wird eine Lösung vorgestellt, wie sich mit Hilfe eines Jdbc-Ldap Treibers und einem Persistenzframework relativ schnell eine flexible Ldap Schnittstelle realisieren lässt.

Artikel vollständig lesen

Transactions mit dem Atlassian PluginFramework

, von
1 Kommentar

Auch bei der Pluginentwicklung für Confluence kommt irgendwann der Zeitpunkt, an dem man sich mit komplexeren Abläufen bei der Persistierung von Daten beschäftigen muss. Um die Integrität dieser Daten sicherstellen zu können, ist man dann auf den Einsatz von Transactions angewiesen. Da Confluence das Spring Framework verwendet, bietet sich hierfür die Nutzung des TransactionTemplate an. Dieses ermöglicht es, wie in der Spring Dokumentation beschrieben, auf einfache Weise kritischen Code unter Verwendung eines Callbacks in eine Transaction zu verpacken. Dazu benötigt man jedoch noch einen PlatformTransactionManager. Dieser implementiert die Strategie für die Transaktionsbehandlung, die im Fall von Confluence auf Hibernate basiert. Auch hierzu können weitere Informationen und ein Codebeispiel auf den Seiten von Spring gefunden werden. Der PlatformTransactionManager ist als Bean im Application Context von Confluence vorhanden und kann über den ComponentContainer referenziert werden:

public PlatformTransactionManager getTransactionManager(){
    return (PlatformTransactionManager) ComponentContainer.get("transactionManager");
}

Allerdings funktioniert dieses Codebeispiel nach einer Umstellung auf V2-Plugins nicht mehr. Der Grund: Da diese Plugins in OSGI-Bundles umgewandelt werden, welche eine andere Spring Version verwenden als die Kern-Applikation, kommt es bei der Referenzierung der transactionManager-Bean über den ComponentContainer zu einer ClassCastException.

Bei der Suche nach einer Lösung für dieses Problem bin ich über ein Ticket im Issue Tracker von Atlassian gestolpert, in dessen Kommentaren eine Alternative beschrieben wird: Abhilfe schafft die Verwendung der Shared Access Layer (SAL), einer einheitlichen Service-Schicht für alle Atlassian Anwendungen. Sie stellt neben verschieden anderen Services auch ein TransactionTemplate bereit, das für Confluence bereits den auf Hibernate basierenden PlatformTransactionManager gesetzt hat und auf folgende Weise referenziert werden kann.

Zunächst muss das Template als Komponente (Spring-Bean) im Plugin-Descriptor (atlassian-plugin.xml) importiert werden:

<component-import name="SAL Transaction Template" key="salTransactionTemplate">
    <interface>com.atlassian.sal.api.transaction.TransactionTemplate</interface>
</component-import>

Dann kann man sich die Komponente per Spring Autowiring in fast alle Plugin Modultypen (z. B. Actions und Components ) injizieren lassen. Der Name der zu injizierenden Bean entspricht dem Key des component-import Elementes im Plugin-Descriptor (in diesem Beispiel also “salTransactionTemplate” ):

public void setSalTransactionTemplate(TransactionTemplate template){
    this.transactionTemplate = template;
}

Nun kann das Template wie  oben beschrieben verwendet werden.

Noch ein Hinweis: SAL wird erst ab Confluence 3.0 mit ausgeliefert. Für Confluence 2.10 muss man also eine andere Lösung finden.

&lt;

Anbindung des OpenBenno Mailarchivs an ein Active Directory

, von
8 Kommentare

OpenBenno ist eine unter GPL lizenzierte E-Mail Archivierungslösung. Damit ist es möglich, die gesetzlichen Anforderungen zur Archivierung elektronischer Kommunikation umzusetzen. Soll diese Software im Unternehmen eingesetzt werden, ist zumeist eine Anbindung an ein vorhandenes Nutzerrepository via LDAP notwendig. Dieser Artikel beschreibt die notwendige Konfiguration der Anbindung an CAS und das Active Directory. Die zusätzlich notwendige Library, deren Sourcen und eine Beispielkonfiguration können am Ende des Artikels heruntergeladen werden.

Artikel vollständig lesen

Diese Webseite basiert auf Wordpress. © 2014 Communardo Software GmbH / Kleiststraße 10 a / D-01129 Dresden / Fon +49 (0) 351/8 33 82-0 / info@communardo.de