Kurzanleitung zu Federreglern

1. Einleitung

In diesem Artikel konzentrieren wir uns auf ein Kernkonzept in Spring MVC - Controllers.

2. Übersicht

Beginnen wir mit einem Schritt zurück und werfen einen Blick auf das Konzept des Front Controllers in der typischen Spring Model View Controller- Architektur .

Auf einem sehr hohen Niveau sind hier die Hauptaufgaben, die wir betrachten:

  • Fängt eingehende Anfragen ab
  • Konvertiert die Nutzdaten der Anforderung in die interne Struktur der Daten
  • Sendet die Daten zur weiteren Verarbeitung an Model
  • Ruft verarbeitete Daten aus dem Modell ab und überträgt diese Daten zum Rendern in die Ansicht

Hier ist ein kurzes Diagramm für den Hochleistungsfluss in Spring MVC :

Wie Sie sehen können, spielt das DispatcherServlet die Rolle des Front Controllers in der Architektur.

Das Diagramm gilt sowohl für typische MVC-Controller als auch für RESTful-Controller - mit einigen kleinen Unterschieden (siehe unten).

Beim herkömmlichen Ansatz sind MVC- Anwendungen nicht serviceorientiert, daher gibt es einen View Resolver , der endgültige Ansichten basierend auf den von einem Controller empfangenen Daten rendert .

RESTful- Anwendungen sind serviceorientiert und geben Rohdaten zurück (normalerweise JSON / XML). Da diese Anwendungen kein View-Rendering durchführen, gibt es keine View-Resolver. Im Allgemeinen wird vom Controller erwartet, dass er Daten direkt über die HTTP-Antwort sendet.

Beginnen wir mit den MVC0-Controllern.

3. Maven-Abhängigkeiten

Um mit Spring MVC arbeiten zu können , müssen wir uns zunächst mit den Maven-Abhängigkeiten befassen:

 org.springframework spring-webmvc 5.0.6.RELEASE 

Um die neueste Version der Bibliothek zu erhalten, schauen Sie sich spring-webmvc auf Maven Central an.

4. Project Web Config

Bevor wir uns die Controller selbst ansehen, müssen wir zunächst ein einfaches Webprojekt einrichten und eine schnelle Servlet- Konfiguration durchführen.

Lassen Sie uns zunächst sehen, wie das DispatcherServlet ohne Verwendung von web.xml eingerichtet werden kann - stattdessen mit einem Initialisierer:

public class StudentControllerConfig implements WebApplicationInitializer { @Override public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.register(WebConfig.class); root.refresh(); root.setServletContext(sc); sc.addListener(new ContextLoaderListener(root)); DispatcherServlet dv = new DispatcherServlet(new GenericWebApplicationContext()); ServletRegistration.Dynamic appServlet = sc.addServlet("test-mvc", dv); appServlet.setLoadOnStartup(1); appServlet.addMapping("/test/*"); } }

Um Dinge ohne XML einzurichten, stellen Sie sicher, dass Servlet-API 3.1.0 in Ihrem Klassenpfad ist.

So würde die web.xml aussehen:

 test-mvc  org.springframework.web.servlet.DispatcherServlet  1  contextConfigLocation /WEB-INF/test-mvc.xml   

Wir legen hier die Eigenschaft contextConfigLocation fest und verweisen auf die XML- Datei, die zum Laden des Spring-Kontexts verwendet wird. Wenn die Eigenschaft nicht vorhanden ist, sucht Spring nach einer Datei mit dem Namen {servlet_name} -servlet.xml .

In unserem Fall ist die servlet_name ist Test-mvc und so, in diesem Beispiel die DispatcherServlet würde nach einer Datei suchen namens Test-mvc-servlet.xml .

Zum Schluss richten wir das DispatcherServlet ein und ordnen es einer bestimmten URL zu, um unser Front Controller- basiertes System hier fertigzustellen:

 test-mvc /test/* 

In diesem Fall würde das DispatcherServlet also alle Anforderungen innerhalb des Musters / test / * abfangen .

5. Spring MVC Web Config

Schauen wir uns nun an, wie das Dispatcher-Servlet mit Spring Config eingerichtet werden kann :

@Configuration @EnableWebMvc @ComponentScan(basePackages= { "com.baeldung.controller.controller", "com.baeldung.controller.config" }) public class WebConfig implements WebMvcConfigurer { @Override public void configureDefaultServletHandling( DefaultServletHandlerConfigurer configurer) { configurer.enable(); } @Bean public ViewResolver viewResolver() { InternalResourceViewResolver bean = new InternalResourceViewResolver(); bean.setPrefix("/WEB-INF/"); bean.setSuffix(".jsp"); return bean; } }

Schauen wir uns nun das Einrichten des Dispatcher-Servlets mithilfe von XML an . Ein Snapshot der DispatcherServlet-XML- Datei - der XML- Datei, die das DispatcherServlet zum Laden von benutzerdefinierten Controllern und anderen Spring- Entitäten verwendet :

    /WEB-INF/   .jsp  

Basierend auf dieser einfachen Konfiguration initialisiert das Framework natürlich alle Controller-Beans, die es im Klassenpfad findet.

Beachten Sie, dass wir auch den View Resolver definieren, der für das Rendern der Ansicht verantwortlich ist. Hier verwenden wir den InternalResourceViewResolver von Spring . Dies setzt voraus, dass der Name einer Ansicht aufgelöst wird. Dies bedeutet, dass eine entsprechende Seite mithilfe von Präfix und Suffix gefunden wird (beide in der XML- Konfiguration definiert).

Wenn der Controller beispielsweise eine Ansicht mit dem Namen " welcome" zurückgibt, versucht der View Resolver , eine Seite mit dem Namen "welcome.jsp" im Ordner " WEB-INF " aufzulösen .

6. Der MVC-Controller

Lassen Sie uns nun endlich den MVC-Style-Controller implementieren.

Beachten Sie, wie wir ein ModelAndView- Objekt zurückgeben, das eine Modellzuordnung und ein Ansichtsobjekt enthält . Beide werden vom View Resolver für die Datenwiedergabe verwendet:

@Controller @RequestMapping(value = "/test") public class TestController { @GetMapping public ModelAndView getTestData() { ModelAndView mv = new ModelAndView(); mv.setViewName("welcome"); mv.getModel().put("data", "Welcome home man"); return mv; } }

Also, was genau haben wir hier eingerichtet.

Zuerst haben wir einen Controller namens TestController erstellt und ihn dem Pfad "/ test" zugeordnet . In der Klasse haben wir eine Methode erstellt, die ein ModelAndView- Objekt zurückgibt und einer GET- Anforderung zugeordnet ist. Daher wird jeder URL-Aufruf, der mit " test " endet, vom DispatcherServlet an die getTestData- Methode im TestController weitergeleitet .

And of course we're returning the ModelAndView object with some model data for good measure.

The view object has a name set to “welcome“. As discussed above, the View Resolver will search for a page in the WEB-INF folder called “welcome.jsp“.

Below you can see the result of an example GET operation:

Note that the URL ends with “test”. The pattern of the URL is “/test/test“.

The first “/test” comes from the Servlet, and the second one comes from the mapping of the controller.

7. More Spring Dependencies for REST

Let's now start looking at a RESTful controller. Of course, a good place to start is the extra Maven dependencies we need for it:

  org.springframework spring-webmvc 5.0.6.RELEASE   org.springframework spring-web 5.0.6.RELEASE   com.fasterxml.jackson.core jackson-databind 2.9.5   

Please refer to jackson-core, spring-webmvc and spring-web links for the newest versions of those dependencies.

Jackson is of course not mandatory here, but it's certainly a good way to enable JSON support. If you're interested to dive deeper into that support, have a look at the message converters article here.

8. The REST Controller

The setup for a Spring RESTful application is the same as the one for the MVC application with the only difference being that there is no View Resolvers and no model map.

The API will generally simply return raw data back to the client – XML and JSON representations usually – and so the DispatcherServlet bypasses the view resolvers and returns the data right in the HTTP response body.

Let's have a look at a simple RESTful controller implementation:

@Controller public class RestController { @GetMapping(value = "/student/{studentId}") public @ResponseBody Student getTestData(@PathVariable Integer studentId) { Student student = new Student(); student.setName("Peter"); student.setId(studentId); return student; } }

Note the @ResponseBody annotation on the method – which instructs Spring to bypass the view resolver and essentially write out the output directly to the body of the HTTP response.

A quick snapshot of the output is displayed below:

The above output is a result of sending the GET request to the API with the student id of 1.

One quick note here is – the @RequestMapping annotation is one of those central annotations that you'll really have to explore in order to use to its full potential.

9. Spring Boot and the @RestController Annotation

The @RestController annotation from Spring Boot is basically a quick shortcut that saves us from always having to define @ResponseBody.

Here's the previous example controller using this new annotation:

@RestController public class RestAnnotatedController { @GetMapping(value = "/annotated/student/{studentId}") public Student getData(@PathVariable Integer studentId) { Student student = new Student(); student.setName("Peter"); student.setId(studentId); return student; } }

10. Conclusion

In diesem Handbuch werden die Grundlagen der Verwendung von Controllern in Spring sowohl aus der Sicht einer typischen MVC-Anwendung als auch einer RESTful-API erläutert.

Natürlich ist der gesamte Code im Artikel auf GitHub verfügbar.