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">
<property>
<props>
<prop key="/hallo">halloController</prop>
</props>
</property>
</bean>
<bean name="halloController"/>
Ü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;
@Controller
public class HalloWeltController {
@RequestMapping(value = "/hallo")
public @ResponseBody 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 />
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;
@Autowired
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;
@Controller
@RequestMapping("/editUser")
@SessionAttributes("userForm")
public class UserController {
private static final String VIEW_TEMPLATE_USER = "user";
private UserService userService;
@RequestMapping(method = RequestMethod.POST)
public String onSubmit(@ModelAttribute("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;
}
@RequestMapping(method = RequestMethod.GET)
public String setupForm(Model model) {
UserForm userForm = new UserForm();
model.addAttribute("userForm", userForm);
return VIEW_TEMPLATE_USER;
}
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}