[Spring Boot] Controllers and routing in SpringBoot

1. SpringBoot controller

In Spring Boot, the controller is a key component in the MVC pattern, responsible for handling user requests and dispatching them to the appropriate service for processing.

1.1 The role of the controller

The main task of a controller in a Spring Boot application is to receive and process requests from users. These requests can be HTTP requests such as GET or POST. Once requests are received, the controller typically interacts with a model (e.g., a data model or a service) to handle the requests and ultimately returns a view so the user can see it or returns the data directly to the requester.

1.2 Create a controller

In Spring Boot, creating a controller is very simple. All you need is a class, and then you can mark the class as a controller by using the @Controller or @RestController annotation on the class. Let's look at a simple example:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    
    
    @GetMapping("/hello")
    public String hello() {
    
    
        return "Hello, Spring Boot!";
    }
}

In the above code, we first imported the required classes. Then, we mark this class as a controller using the @RestController annotation. Next, we define a method hello(), which returns a string. The @GetMapping("/hello") annotation tells Spring Boot that this method should be called when the user accesses the "/hello" URL.

1.3 @Controller与@RestController

In Spring Boot, there are two types of controllers: @Controller and @RestController.

@Controller is a regular controller, which is usually used with a view template (such as Thymeleaf or FreeMarker) to generate an HTML response. Here is a typical example:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
    
    
    @GetMapping("/hello")
    public String hello(Model model) {
    
    
        model.addAttribute("name", "Spring Boot");
        return "hello";
    }
}

In the above code, when the user accesses the "/hello" URL, the hello() method is called and a view named "hello" is returned. The value of "name" ("Spring Boot") will be passed to the view.

On the other hand, @RestController is a special type of controller that only returns data, not views. This is very useful for building REST APIs. The function of @RestController is the same as the combination of @Controller and @ResponseBody annotations. The "Hello, Spring Boot!" example above is an example of @RestController.

Each controller has its purpose, and you can choose which one to use based on your needs.

2. SpringBoot routing

In Spring Boot, routing is a mechanism by which an application can decide how to respond to client requests. The definition of a route usually depends on the requested URL and HTTP method.

2.1 Definition and function of routing

Routing plays a vital role in web applications. They define what should happen when a user visits a specific URL. This usually involves finding and executing the relevant controller method to handle the request and then returning the results to the user.

For example, you might have a blogging application and you might want to display all blog posts when a user visits the "/posts" URL. To do this, you will need to define a route that maps the "/posts" URL to a controller method that can retrieve all blog posts and display them.

2.2 Create and define routes

In Spring Boot, routes are defined by using mapping annotations on methods of controller classes. These annotations tell Spring Boot that the method should be called when the user visits a URL that matches the annotation parameters.

Here is a simple example showing how to define routes in Spring Boot:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    
    
    @GetMapping("/hello")
    public String hello() {
    
    
        return "Hello, Spring Boot!";
    }
}

In this example, we use the @GetMapping annotation on the hello() method and pass it a "/hello" parameter. This tells Spring Boot that this method should be called when the user accesses the "/hello" URL.

2.3 Common routing annotations

Spring Boot provides a series of mapping annotations corresponding to various HTTP methods. Here are some of the most commonly used ones:

  • @GetMapping: Corresponds to the GET method of HTTP, used to obtain resources.
  • @PostMapping: Corresponds to the POST method of HTTP and is used to create new resources.
  • @PutMapping: Corresponds to HTTP's PUT method, used to update existing resources.
  • @DeleteMapping: Corresponds to the DELETE method of HTTP, used to delete resources.

In addition to these, there is a general @RequestMapping annotation that can be used to handle all types of HTTP methods. For example, the following code is equivalent to using @GetMapping("/hello"):

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    
    
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
    
    
        return "Hello, Spring Boot!";
    }
}

Using these annotations, you can create complex routes to meet the needs of your web application.

3. Example demonstration

In this section, we will create a simple Spring Boot application that contains a controller and several routes, which we will then test.

3.1 Create a simple controller and route

First, let's create a simple one HelloControllerthat will contain several routes:

import org.springframework.web.bind.annotation.*;

@RestController
public class HelloController {
    
    

    // GET请求
    @GetMapping("/hello")
    public String hello() {
    
    
        return "Hello, Spring Boot!";
    }

    // POST请求
    @PostMapping("/hello")
    public String helloPost() {
    
    
        return "You posted to /hello!";
    }

    // PUT请求
    @PutMapping("/hello")
    public String helloPut() {
    
    
        return "You put to /hello!";
    }

    // DELETE请求
    @DeleteMapping("/hello")
    public String helloDelete() {
    
    
        return "You deleted /hello!";
    }
}

In this controller, we define four routes, each corresponding to a different HTTP method, and all pointing to the same path: /hello.

3.2 Test controller and routing

There are several ways to test controllers and routes. You can use a browser or a command line tool like curl, or you can use an API testing tool like Postman.

Here is GET /hellothe command to test routing using curl:

curl http://localhost:8080/hello

If everything is fine, you should see output on the command line Hello, Spring Boot!.

To test POST, PUT and DELETE routes, you can use the following curl command:

curl -X POST http://localhost:8080/hello
curl -X PUT http://localhost:8080/hello
curl -X DELETE http://localhost:8080/hello

Each command should return an appropriate message, for example, POST /hello"You posted to /hello!" should be returned.

The process of testing with Postman is similar, except that you need to enter the URL and HTTP method in Postman's user interface, and then click the "Send" button. You should see the returned message in Postman's response area.

4. SpringBoot routing matching rules

In SpringBoot, route matching is a very important topic. Understanding how routes match up, and which routes take precedence over others, is critical to creating and maintaining complex web applications.

4.1 Introduction to routing matching rules

In SpringBoot, routing matching rules mainly depend on the path you define in @RequestMappingor other routing-related annotations (such as @GetMapping, etc.). @PostMappingRoute matching rules mainly have two aspects:

  1. Path matching : SpringBoot uses Ant-style path matching. You can use *, ?and **to match any number of characters, any one character and any number of directories. For example, /users/*it can match /users/123, but not match /users/123/orders; instead, /users/**it can match any /users/path that starts with .

  2. Method matching : SpringBoot can match different processing functions according to the HTTP request method. For example, you could define one that handles GET requests @GetMappingand one that handles POST requests @PostMapping, both on the same path, but calling different handlers based on the type of request.

4.2 Routing priority

When multiple routes match the same request, SpringBoot will select a route based on the following priority rules:

  1. Exact match routes always take precedence over pattern match routes. For example, if you define two routes /users/123and /users/*, then for /users/123the request, SpringBoot will choose the exact matching /users/123route.

  2. For pattern matching routes, the fewer matching patterns, the higher the priority. For example, for both routes and , for /users/*/*requests , SpringBoot will choose the route because it has fewer pattern matches./users/*/users/123/orders/users/*

  3. If two routes have the same number of pattern matches, their priority is determined by the order in which they are defined, with the route defined first taking precedence.

4.3 Frequently asked questions and solutions

When dealing with route matching, you may encounter some common problems, such as:

  • Path conflicts : If you define two routes with the same path but different methods, SpringBoot will treat them as different routes. However, if both routes have the same path and method, then they will conflict and SpringBoot will throw an exception. The way to solve this problem is to avoid defining routes with the same path and method.

  • Route fuzzy matching : If your application has many routes, it may happen that one route mismatches another route. To avoid this, you should try to use exact matching routes and avoid using overly complex pattern matching.

When writing routes, understanding and applying these rules and workarounds can help you create clearer, more maintainable code.

5. How to receive request parameters in SpringBoot controller

In web development, controllers need to handle various HTTP requests, and these requests often contain some parameters. Next we will discuss in detail how to receive these request parameters in SpringBoot.

5.1 Receive query parameters

Query parameters are ?the latter parameters in the URL, usually used for GET requests. In SpringBoot controller, we can use @RequestParamannotations to receive query parameters. For example:

@GetMapping("/users")
public String getUsers(@RequestParam(name = "name", required = false) String name) {
    
    
    // ...
}

In this example, we receive a namequery parameter named. required = falseIndicates that this parameter is optional. If this parameter is not included in the request, namethe value will be set to null.

5.2 Receive form parameters

Form parameters are usually used in POST or PUT requests, and they are in the body of the request. In the SpringBoot controller, we can also use @RequestParamannotations to receive form parameters. However, if the form we want to receive contains many fields, @RequestParamit will be troublesome to use. At this time, we can create a Java Bean to represent this form, and then use @ModelAttributeannotations to receive this form. For example:

@PostMapping("/users")
public String createUser(@ModelAttribute UserForm form) {
    
    
    // ...
}

public static class UserForm {
    
    
    private String name;
    private String email;
    // getters and setters ...
}

5.3 Receive path parameters

The path parameter is a part of the URL that is usually used to specify the ID of the resource. In SpringBoot controller, we can use @PathVariableannotations to receive path parameters. For example:

@GetMapping("/users/{id}")
public String getUser(@PathVariable("id") String id) {
    
    
    // ...
}

In this example, we receive a idpath parameter named. The value of this parameter will be obtained from the URL {id}part.

When handling HTTP requests, it is very important to understand how to receive various types of request parameters. Different request parameter types have different applicable scenarios. Choosing the appropriate parameter type can make your controller simpler and easier to understand.

6. Data return

When building RESTful services, we usually need to return data to the client. SpringBoot provides us with multiple ways to return data.

6.1 Return JSON data

In SpringBoot applications, the most common way to return data is to return JSON data. You just return an object in your controller method and SpringBoot will automatically convert it to JSON. For example:

@GetMapping("/users/{id}")
public User getUser(@PathVariable("id") String id) {
    
    
    User user = //...
    return user;
}

In this example, we return a User object. SpringBoot will automatically convert it to JSON.

6.2 Return to view

In addition to returning JSON data, SpringBoot can also return views. Views are usually returned in response to a GET request, such as displaying an HTML page. You can return a string, which is the name of the view. For example:

@GetMapping("/login")
public String login() {
    
    
    return "login";
}

In this example, we return the view name "login". If you use a template engine (such as Thymeleaf), SpringBoot will automatically render the template named "login" and return it to the client.

6.3 Return file

Sometimes, you may need to return a file to the client. For example, a user requests to download a report. In SpringBoot, you can use ResponseEntity<Resource>. For example:

@GetMapping("/report")
public ResponseEntity<Resource> downloadReport() {
    
    
    // Load file as Resource
    Resource resource = //...

    // Try to determine file's content type
    String contentType = //...

    // Fallback to the default content type if type could not be determined
    if(contentType == null) {
    
    
        contentType = "application/octet-stream";
    }

    return ResponseEntity.ok()
            .contentType(MediaType.parseMediaType(contentType))
            .body(resource);
}

In this example, we return a file. ResponseEntity<Resource>Will tell SpringBoot that we want to return a file, and contentType(MediaType.parseMediaType(contentType))set the MIME type of the file.

7. Summary

In this article, we explain in detail how to use controllers and routing in Spring Boot. First, we explain what a controller is and how to create a controller in Spring Boot. We also discussed the differences between @Controller and @RestController annotations.

We then looked at routing, explaining its definition and role, as well as how to create and define routes in Spring Boot. We also discussed some commonly used routing annotations.

We also demonstrated how to create a simple controller and route through an example and tested it. We elaborate on SpringBoot's route matching rules, including route priorities and common problems and solutions.

In the data return section, we explored how to receive request parameters in Spring Boot controllers, including query parameters, form parameters, and path parameters, and discussed how to return JSON data, views, and files.

I hope this article can help you better understand and use SpringBoot controllers and routing. If you have any questions or need further explanation, please leave a message for discussion.

Guess you like

Origin blog.csdn.net/weixin_52665939/article/details/131885106