DispatcherServlet

With Spring MVC, you don't have to create servlets. You can create a class and annotate it with the @Controller annotation and use the @RequestMapping annotation to map it to a certain URI pattern. By convention, the name of this class usually ends with Controller.

Spring uses a central servlet, the DispatcherServletto accept requests. This DispatcherServlet needs to be configured to process all requests and, based on the URI pattern specified in the @RequestMapping annotation, Spring will find a matching controller to handle a request.

The following diagram shows the request/response flow when using Spring MVC:

Figure 3.2: Spring DispatcherServlet and controllers

Now, let's turn the Messages App into a web application and add a controller to accept HTTP requests. To do that, let's add Spring Boot dependencies to the pom.xml file.

In this book, all of the web applications that we build will be based on Spring Boot. And, by default, we use the Tomcat application server in embedded mode, which doesn't require the installation of Tomcat manually. Spring Boot will handle all of the heavy liftings.

Here is the change made to the pom.xml file:

...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
...

The <parent> tag inherits the project artifacts from Spring Boot's parent starter. And the spring-boot-starter-web dependency includes the spring-context module we used previously. At the time of writing, Spring Boot 2.0 is still in release candidates, but we will need to specify the Spring's own Maven repository to download it.

Now, if you run mvn install, you can see that Maven will also download a bunch of dependencies that Spring Boot requires. And if you run the java -jar target/messages-jar-with-dependencies.jar command, you will see the debug information Spring printed out and, at the end of the output, is our message "Saved message: Hello, Spring!".

By now, our application is still not running as a web application. Let's change our Application.java to make it a Spring Boot web application.

Here is what it looks like:

1. package app.messages;
2. import org.springframework.boot.SpringApplication;
3. import org.springframework.boot.autoconfigure.SpringBootApplication;
4. @SpringBootApplication
5. public class Application {
6. public static void main(String[] args) {
7. SpringApplication.run(Application.class, args);
8. }
9. }

In line 4, we apply the @SpringBootApplication annotation to the Application class so that Spring will do the magic autoconfiguration. And in line 7, we bootstrap our application using SpringApplication.run(), which will spin up the Spring container. We remove the MessageService saving message code because we will use controllers to handle HTTP requests.

Now, let's create a controller to accept HTTP requests. We will name it MessageController because we want to handle all message-related requests in this controller. For now, let's just add an API to display a hello message.

Here is how MessageController appears:

1. package app.messages;
2. import org.springframework.stereotype.Controller;
3. import org.springframework.web.bind.annotation.GetMapping;
4. import org.springframework.web.bind.annotation.RequestMapping;
5. import org.springframework.web.bind.annotation.ResponseBody;
6. @Controller
7. @RequestMapping("/messages")
8. public class MessageController {
9. @GetMapping("/welcome")
10. public String welcome() {
11. return "Hello, Welcome to Spring Boot!";
12. }
13. }

In line 6, we apply the @Controller annotation to make the MessageController class an actual Spring MVC controller. In line 7, we use the @RequestMapping annotation to map the controller to handle requests that match the URI pattern "/messages". In line 9, we use the @GetMapping annotation to map the welcome() handler method to handle requests that match the URI pattern; "/messages/welcome". The @GetMapping annotation is a shortcut variant of @RequestMapping to map an HTTP GET request. You can replace it with @RequestMapping(value = "/welcome", method = RequestMethod.GET). But @GetMapping is more succinct. In lines 10 to 12, the welcome() handler method returns a simple message that should be sent back in HttpServletResponse.

Now, if you run mvn install and then the java -jar target/messages-jar-with-dependencies.jar command, you can see that it won't work. You will see an error in the output saying Application run failed. This is because maven-assembly-plugin cannot run a Spring Boot application. Let's remove it from the <build> section and add spring-boot-maven-plugin, which is for running Spring Boot applications using Maven. Here is what the updated <build> section looks like:

<build>
<finalName>messages</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

Now, let's run the following command to start the application. With this command, you don't need to run mvn install:

mvn spring-boot:run

Once the application has started, you can see the following message in the output:

...
Mapped "{[/messages/welcome],methods=[GET]}" onto public java.lang.String app.messages.MessageController.welcome()
...
Tomcat started on port(s): 8080 (http) with context path ''
...

It means that Spring has registered our welcome() handler with the "/messages/welcome" path for HTTP GET requests. And Tomcat server has started and is listening to HTTP requests that come in from port 8080.

Let's open the http://localhost:8080/messages/welcome URL in Chrome browser to test it out. Wait, it is an error page, saying HTTP 404 Not Found, like the following:

Figure 3.3: Whitelabel HTTP 404 error page

That shouldn't be right. We have registered our welcome() handler correctly, as shown in the start-up output. Well, there is something else that we missed here. We haven't told Spring what to do with our return value, "Hello, Welcome to Spring Boot!". And, by default, without any other configuration, Spring thinks of a String type return value as the path that the request should be forwarded internally. In our case, it tries to find a handler for the "/Hello, Welcome to Spring Boot!" path, which doesn't exist. And that's why the error message is HTTP 404.

To fix this, let's add the @ResponseBody annotation to the handler method, as follows:

@GetMapping("/welcome")
@ResponseBody
public String welcome() {
return "Hello, Welcome to Spring Boot!";
}

With the @ResponseBody annotation, Spring will take the return value as the body of the HTTP response, and it will find a corresponding HttpMessageConverter to write the value to the response. You can also apply the annotation to the MessageController class that has the same effect of applying the annotation to all of the methods in this class.

Now, if you terminate the application and run mvn spring-boot:run again, you should see the hello message in the browser after refreshing it.

To build a RESTful API, you can also apply the @RestController annotation to controllers. The @RestController annotation is a combination of @Controller and @ResponseBody. We will talk about this more when we discuss RESTful APIs.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.203.96