Three major functions of SpringMVC

Table of contents

1. Getting to know SpringMVC for the first time

1.1 Definition of MVC

1.2 What is the relationship between MVC and SpringMVC? 

1.3 The importance of SpringMVC

Two, the three major functions of Spring MVC

2.1 Connection function

2.1.1 @RequestMapping annotation introduction

2.1.2 @GetMapping and PostMapping

2.2 Get parameter function

2.2.1 Passing common parameters

2.2.2 Passing Objects

2.2.3 Form parameter passing

2.2.4 Backend parameter renaming (backend parameter mapping)——@RequestParam

2.2.5 Use @RequestBody to accept JSON objects

2.2.6 Use @PathVariable to get the parameters in the base URL (not from the parameters part of the URL)

2.2.7 Difference between @PathVariable and @RequestParam

2.2.8 Upload file @RequestPart

2.2.9 Get Cookie/Session/header

2.3 Return function

2.3.1 Request Forwarding VS Request Redirection


1. Getting to know SpringMVC for the first time

Spring Web MVC is the original web framework built on the Servlet API, included in the Spring framework from the beginning. Its official name "Spring Web MVC" comes from the name of its source module (Spring-WebMVC), but it is often called "Spring MVC".

From the above definitions we can draw two key messages:

  • Spring MVC is a web framework.
  • Spring MVC is built on top of the Servlet API.

But to really understand what is Spring MVC? We must first figure out what is MVC?

1.1 Definition of MVC

MVC (Model-View-Controller) is a common design pattern for building separation of user interface and application logic. The MVC pattern divides the application into three parts:

  • Model (Model): Responsible for maintaining the state and data of the application.
  • View (View): Responsible for presenting model data, usually a user interface.
  • Controller: Receives and processes user input, and delegates requests to models or views for processing.

In the MVC framework, application logic is handled by the controller, which receives user input from the view, then uses the model for state changes and data updates, and finally passes the results back to the view for rendering.

1.2 What is the relationship between MVC and SpringMVC? 

MVC is an idea, and Spring MVC is a concrete realization of the MVC idea.
To sum up, Spring MVC is a web framework that implements the MVC pattern and inherits the Servlet API. Since it is a web framework, when the user enters the url in the browser, our Spring MVC project can perceive the user's request.

1.3 The importance of SpringMVC

Most of the Java projects are now based on Spring (or Spring Boot), and the core of Spring is Spring
MVC. That is to say, Spring MVC is the core module of the Spring framework, and Spring Boot is the scaffolding of Spring, so we can infer that most of the Java projects on the market are about equal to Spring MVC projects. This is our The reason to learn SpringMVC.

When creating the SpringBoot project, the Spring Web framework we chose is actually the Spring MVC framework, as shown in the following figure:

Here I will briefly talk about RESTful. In fact, the actual application scenarios are not based on this set. Many of them use Get to obtain resources, and others use the post method.

Introduction to RESTful

RESTful is a design style or an architectural style for building web services. It is a lightweight style that can communicate via the HTTP protocol and is suitable for distributed hypermedia systems.

The core idea of ​​RESTful is to abstract all web resources into a series of URI (Uniform Resource Identifier), and operate resources through HTTP methods (GET, POST, PUT, DELETE, etc.), to realize the communication between the client and the server. Stateless communication. RESTful emphasizes the representational state transfer of resources (Representational State Transfer, REST for short), which needs to meet certain constraints, including: client-server model, stateless, cache, unified interface, and layered system.

The benefits of a RESTful architecture include:

  • Lightweight, the transmission data format is simple and easy to understand.
  • Easy to expand, because it complies with the HTTP protocol standard, it supports multi-language development and multi-platform interaction.
  • Easy to cache, since each request contains enough information to understand the request itself, the results can be cached to improve performance.
  • The code is readable because each request clearly specifies what to do, so the code is easy to understand and debug.

Two, the three major functions of Spring MVC

In practical applications, RESTful is usually used in Web API design, and data interaction can be performed through HTTP requests.

Below we mainly introduce the three major functions of SpringMV. Mastering the following three functions is equivalent to mastering Spring MVC

  • Connection function: connect the user (browser) with the Java program, that is, accessing an address can call our Spring program.
  • The function of obtaining parameters: the user will bring some parameters when accessing, and find a way to obtain the parameters in the program.
  • The function of outputting data: After executing the business logic, the result of program execution should be returned to the user.

2.1 Connection function

In the SpringMVC project, create a UserController class to realize the interconnection between the user and the Spring program. The specific implementation code is as follows:

package com.example.demo.controller;

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

//@Controller
//@ResponseBody
// 使用以上两个注解或者直接使用RestController去返回一个数据,
@RestController
public class UserController {
    @RequestMapping(value = "/sayHi")//可以是一级路由也可以是n级路由
    public String sayHi() {
        return "say Hi";
    }

}

Analysis: Note that we did not add @RequestMapping to the class, but added this annotation to the method. This approach is possible, because in SpringMVC, the method is the smallest unit and unit of final access.

Enter in the address bar: localhost:8080/sayHi and the following interface appears, which means the access is successful.

Of course, if @RestController is annotated, the following interface will appear:

Analysis: This is because without annotations, this method cannot be started with the startup of the Spring container. Only by adding this annotation can the url address be registered in Spring as Spring starts.

2.1.1 @RequestMapping annotation introduction

@RequestMapping is one of the most commonly used annotations in Spring Web applications, and it is used to register the route mapping of the interface
.

route map

Route mapping: The so-called route mapping refers to the process of mapping the user's request to a certain method
of a certain class in the program when the user visits a url is called route mapping

c basic use:

You can directly modify the method like the above code.

You can also modify classes. When modifying classes and methods, the address to access is the class + method, as shown below:

 Does @RequestMapping support requests such as get and post?

In fact, students who understand the HTTP protocol know that when we enter the url in the browser, we actually send a Get request to the server through the browser. We can view it through the developer mode of the browser:

Here we use PostMan to simulate POST requests: it is found that it can be realized, and PUT, DELETE, etc. are no longer simulated one by one, and can be realized.

In many cases, it may be necessary to specify the GET/POST method

So how should it be specified? Let's take a look at the source code of the  @RequestMapping annotation:

analyze:

Specifically, this annotation defines the following properties:

  • name : name, defaults to an empty string.
  • value: The requested path, which can be a string or an array of strings. This is an alias attribute for @AliasFor("path").
  • path: The requested path, which can be a string or an array of strings. This is an alias attribute for @AliasFor("value").
  • method: HTTP method of the request, which can be an enumeration value or an array of enumeration values ​​of RequestMethod type.
  • params: The parameters that must be included in the request can be a string or an array of strings.
  • headers: The header information that must be included in the request, which can be a string or an array of strings.
  • consumes: Accept the content type of the request, which can be a string or an array of strings.
  • produces: The content type of the response, which can be a string or an array of strings.

It should be noted that the attributes in the annotation have default values, which can be set according to the needs when using. Among them, value and path are equivalent. If these two properties are set at the same time, their values ​​must be the same. If no attributes are set, the default will be mapped to the path of the handler method.

Enter RequestMetho[] and you can see that there are the following methods:

But many people may have doubts, but isn't the source code just now defaulted to empty? Then why can we access it through post, get, etc. when there is no setting method before?

First of all, we need to be clear that in Java, the keyword default is used to represent the default value. In this source code, RequestMethod[]() default{} does mean that when the value of the path attribute is not set, the default value of the attribute is an empty array.

In other words, if the value of the path attribute is not specified when using the @RequestMapping annotation, the default value of the attribute is an empty array.

However, the @RequestMapping annotation will be regarded as a fuzzy matching method to process the request by default, that is, as long as the requested URL can match the path specified by the value or path attribute of the annotation, the annotation will be triggered , regardless of the HTTP request method used to send the request.

 After the analysis, we can know that the method of access needs to be specified through the method method:

After specifying, the url address cannot be accessed through other methods, and a request can be sent through PostMan for further verification: 

2.1.2 @GetMapping and PostMapping

These two methods are used to specifically specify access to url through get/post, which simplifies the above method specified by parameters:

Here, since the usage of GetMapping and PostMapping is similar, only one usage is demonstrated:

 Since only post requests are supported, accessing through other methods will throw 405:

2.2 Get parameter function

2.2.1 Passing common parameters

In Spring MVC, you can directly use the parameters in the method to pass parameters, such as the following code:

 ​​​​​​​The display effect:

If multiple parameters are passed: the order of the parameters does not need to be fixed, only key-value pairs need to be matched :

 Let's look at a small set of exercises: observe what the following three methods return?

When we access these three methods separately, without passing in any value:

It can be found that the two classes String and Integer have a default value of null, and a basic type such as int will directly report an error when no value is passed to it.

Therefore, in the usual development process, it is recommended to use classes instead of basic types when passing parameters. The purpose of this is to let front-end developers understand where mistakes are made quickly. The code can be modified as follows:

We know that SpringMVC is built based on the Servlet API, so HttpServletRequest/HttpServletResponse can also be used to complete the task of accepting parameters/responses.

However, this method is relatively rare. In SpringMVC, the getRemoteAddr() method of HttpServletRequest is usually used to obtain the client's IP address (for example, to blacklist some users to deny their access):

@RequestMapping("/getIpAddress")
public String getIpAddress(HttpServletRequest request) {
    String ipAddress = request.getRemoteAddr();
    return ipAddress;
}

It should be noted that using this method to obtain the IP address may have certain errors. For example, when the client uses a proxy server, the obtained IP address may be the IP address of the proxy server instead of the real client IP address. If you need a more accurate IP address, you can consider obtaining it through HTTP header information such as X-Forwarded-For.

Of course, you can also use the sendRedirect method of HttpServletResponse to perform redirection operations:

    @RequestMapping("/Hi4")//可以是一级路由也可以是n级路由
    public String sayHi4(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.sendRedirect("https://www.baidu.com/");//当然这里跳转了,就不会触发后续的return了。
        return "say Hi "+request.getParameter("name");
    }

 Let’s talk about redirection, so let’s talk about the difference between request forwarding and request redirection

1. Different concepts;

Redirection means: when the server receives the request sent by the client, the server returns a redirection response, telling the client that the resource requested has been moved to another location, and the client needs to resend the request to the new address. The redirection is done on the browser side, and the server only needs to return the new URL address in the response (the URL has changed).

Request forwarding means: After receiving the request sent by the client, the server forwards the request to another resource for processing, and then returns the processing result to the client. Re-forwarding is done on the server side, and the client does not know that the requested resource has been forwarded. Therefore, the URL for request forwarding during the whole process will not change.

2. Different implementation methods:

Redirection allows the client to resend the request to a new URL address by modifying the Location field in the HTTP response header. Because there are two requests, there will be two request records in the browser, so redirection will be slower than re-forwarding.

Request forwarding is done on the server side, without modifying the content in the HTTP response header, just forwarding the request to the target resource for processing. Because it's done on the server side, reforwarding is more efficient than redirecting.

3. Data sharing is different:

Redirection is two requests, so the context information of the request cannot be shared. Each request is independent, so the parameters and attributes in the request cannot be directly shared.

Re-forwarding is done on the server side, so parameters and attributes in the request can be shared as they are all handled internally by the server.

To sum up, although redirection and reforwarding are both methods of page jump, their implementation methods and characteristics are very different, and you should choose which method to use according to the actual situation.

2.2.2 Passing Objects

The code of the object to be passed:

 Get the code implementation of the object:

The demonstration is as follows:

We found that the SpringMVC framework is very intelligent, and can be flexibly converted according to the actual returned type: for example, as shown in the above code, it was originally returned to the Object type, but the actual return is in JSON format.

There is also the following: the returned object is originally an Object class, but according to the actual situation, an HTML interface is returned:

2.2.3 Form parameter passing

Form parameters can be obtained by encapsulating multiple data into one object, or by using the same method as obtaining multiple parameters. Since it has been demonstrated above, it will not be demonstrated in detail here.

2.2.4 Backend parameter renaming (backend parameter mapping)——@RequestParam

Why do you need to rename the backend parameters? In fact, students may already know a thing or two, because when capturing data at the back end, under normal circumstances, if you want to obtain success, you need to ensure the consistency of parameters, as shown below: 

However, in the actual development process: the parameters agreed by the front and back ends may not be exactly the same. At this time, in order to ensure the normal interaction between the front and back ends, the back-end parameters need to be renamed:

It is inevitable to use @RequestParam to rename parameters. Let's take a look at its source code first:

@RequestParam has three main attributes:

  1. value: The name of the request parameter.
  2. required: Specifies whether the parameter must exist. The default value is true.
  3. defaultValue: Specifies the default value of the request parameter.

Next, use @RequestParam to demonstrate how to rename parameters:

Someone may have noticed that the attribute required() in @RequestParam is true by default, that is, if the correct parameters are not passed, or no parameters are passed, an exception will be thrown:

Summary: In fact, it is enough to let the username get the parameter. If this parameter is not required to be passed, then you can set require to false, as shown in the following figure:

2.2.5 Use @RequestBody to accept JSON objects

It is not allowed to use objects directly to accept JSON objects:

    @RequestMapping("/reg3")
    public Object reg3(Userinfo userinfo) {
        System.out.println(userinfo);
        return userinfo;
    }

Use PostMan to simulate sending a POST request for verification: 

Using @RequestBody, the code is as follows:

    @RequestMapping("/reg3")
    public Object reg3(@RequestBody Userinfo userinfo) {
        System.out.println(userinfo);
        return userinfo;
    }

It should be noted that the @RequestBody annotation can only be used to process the data in the request body. If you need to process URL parameters, you need to use the @RequestParam annotation. At the same time, since @RequestBody needs to deserialize the request body, the data in the request body The format needs to meet the format requirements of Java objects of the specified type, otherwise deserialization will fail.

What is deserialization?

Serialization is the process of converting an object into a transportable or storable format. Then deserialization is the process of restoring serialized data to original data, which is usually used in scenarios such as network transmission and data storage. In Java, the process of deserialization is achieved by converting the serialized byte stream into Java objects . The purpose of deserialization is to convert data from one form to another to facilitate the transmission, storage and processing of data in different systems or scenarios. Common deserialization libraries include Java's native serialization mechanism, Jackson, Gson, etc.

2.2.6 Use @PathVariable to get the parameters in the base URL (not from the parameters part of the URL)

@PathVariable gets the parameter in the base URL:

    /**
     * 获取URL参数(?之前的参数)
     * @param name
     * @param password
     * @return
     */
    @RequestMapping("/reg4/{name}/{password}")
    public Object reg4(@PathVariable String name,@PathVariable String password) {
        return "say Hi "+name+" 密码是: "+password;
    }

actual effect:

 In addition, you need to pay attention to the following points:

@PathVariable source code:

Observing the source code of @PathVariable found that its default value is true, that is to say, like @RequestParam, if the parameter acquisition fails, an error will be reported:

Although we can set required to false so that it does not report an error, the parameter is still not obtained and it is displayed as null.

After setting the value attribute in @PathVariable: you can get the parameters normally.

2.2.7 Difference between @PathVariable and @RequestParam

Review: We know that both @PathVariable and @RequestParam can be used to obtain the parameters of the request, but their implementation methods and usage scenarios are different.

@RequestParam is mainly used to obtain request parameters (parameters after?), which map request parameters to corresponding controller method parameters, and can obtain request parameters in GET and POST requests. When using @RequestParam to obtain parameters, the request parameters must be passed, and an error will be reported if they are not passed.

And @PathVariable is used to get the parameters in the URL (the parameters before?), it can pass part of the URL as a parameter to the controller method. Compared with @RequestParam, its advantage is that it can achieve a more friendly URL, and can enhance the SEO of the website, making it easier for search engines to identify and parse the URL of the website.

Therefore, if you need to achieve a more friendly URL and enhance the SEO of the website, it is recommended to use @PathVariable to obtain parameters.

What is SEO?

SEO (Search Engine Optimization) refers to search engine optimization . It is a kind of internal and external optimization of the website by understanding the operating rules of the search engine, so as to improve the ranking of the website in the natural search results, thereby improving the website's ranking in the search engine. The process of exposure, traffic and conversion.

2.2.8 Upload file @RequestPart

Before introducing @RequestPart, let's take a look at some preliminary knowledge:

What is MultipartFile

MultipartFile is an interface provided by the Spring framework to represent received uploaded files. It is the result of Spring's encapsulation of the Part interface in Servlet. It provides some methods for obtaining information such as file name, file type, and file byte array, and also supports streaming reading of file content.

In Spring Web applications, the MultiFile parameter is usually used in the parameter list of the controller method to receive uploaded files. The advantage of this is that uploaded files can be easily processed, such as saving to the local file system or uploading to cloud storage services.

What is the function of the transferto method of MultipartFile?

The transferto method of MultipartFile is a method for writing the content of MultipartFile to a disk file. Its syntax is as follows:

    void transferTo(File dest) throws IOException, IllegalStateException;

This method writes the contents of MultipartFile to the specified file dest. If the target file already exists, the original file will be overwritten. When the contents of a MultipartFile have been written to the file, it is no longer available.

It should be noted that the transferTo method needs to specify a File object as a parameter, and the File object represents the path and file name of the target file. At the same time, the premise of calling this method is that the directory where the target file is located must exist and have write permission. If the directory does not exist, an IOException will be thrown.

The implementation code is as follows:

    @RequestMapping("/upload")
    public Object upload(@RequestPart("img") MultipartFile file) {
        File saveFile = new File("C:\\Users\\86136\\Desktop\\img.png");
        try {
            file.transferTo(saveFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

Use PostMan to send the request:

 After the upload is successful, it can be found in the target path:

 

In the process of uploading files, you may encounter a situation where the file is too large and the upload fails. At this time, you can modify the configuration in the configuration file:

Take properties as an example:

Limit the maximum size of a single file in bytes, the default is 1MB

spring.servlet.multipart.max-file-size=2MB 

 Limit the maximum size of the entire request, including the size of all files and form items, in bytes, the default is 10MB

 spring.servlet.multipart.max-request-size=2MB

 Use UUIDs for improvements

But this method is flawed, because  the contents of MultipartFile are written to the specified file dest using the transferto  method. If the target file already exists, the original file will be overwritten. When the contents of a MultipartFile have been written to the file, it is no longer available.

    @RequestMapping("/upload")
    public Object upload(@RequestPart("img") MultipartFile file) {
        String fileName = UUID.randomUUID() + //获取文件名
                file.getOriginalFilename().substring(  //获取文件后缀
                        file.getOriginalFilename().lastIndexOf("."));

        File saveFile = new File("C:\\Users\\86136\\Desktop\\"+fileName);
        try {
            file.transferTo(saveFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

2.2.9 Get Cookie/Session/header

get cookie

The first way to get Cookie is to use getCookie of HttpServletRequest:

    @RequestMapping("/getCookies")
    public String getCookies(HttpServletResponse response,HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        return cookies.toString();//无实际意义,只是为了不报错
    }

 The second is to use @CookieValue to get a single cookie:

    @RequestMapping("getCookie")
    public Object getCookie(@CookieValue String a) {
        return a;
    }

Analyze the meaning of the code: Get a Cookie named a and inject it into a of String type. However, since the source code shows that required is true by default, an error will be reported when the acquisition fails:

 Of course, we can also set the value of required to false, so that no error will be reported, but the page is still not available:

 Of course, if you manually add a cookie named a, then you can get success:

 get header

 Use the getHeader method of HttpServletRequest to get the header:

    @RequestMapping("/getHeader")
    public Object getHeader(HttpServletResponse response,HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        return userAgent;
    }

The realization effect is as shown in the figure:

 Use @RequestHeader to get the header:

 The required of its source code is still true, so it will not be demonstrated here.

 The implementation code is as follows:

    @RequestMapping("/getHeader2")
    public String getHeader2(@RequestHeader("User-Agent") String userAgent) {
        return "userAgent : "+userAgent;
    }

 Realize the effect:

 Of course, further verification is also possible: an exact match is found.

 Get Session

 Before getting the Session, we need to manually store a Session in it. 

Note that we don't need to pass parameters here, because the default is true. (Do not pass false, otherwise the task of storing the session will not be completed):

 Get Session:

    /**
     * 获取Session
     * @param name
     * @return
     */
    @RequestMapping("/getSession")
    public Object getSession(@SessionAttribute(SESSION_KEY) String name) {
        return name;
    }

 Get success:

2.3 Return function

Through the above study, we know that under the default request, whether it is Spring MVC or Spring Boot, the view
(xxx.html) is returned, but now the front and back ends are separated, and the back end only needs to return the data to the front end. , this time we need to use @ResponseBody (or use @RestController instead of @ResponseBody and @Controller).

Now create the front-end page index.html in the static directory:

It is found that the page cannot be accessed (this method defaults to request forwarding, if the current path cannot be found, then an error will be reported): 

And we added a '/' in front of the index.html file, and found that it can be accessed normally, why is this?

First of all, we need to understand the meaning of the root path: domain name (IP) + port number.

Because according to the normal logic, the query address of this route means: query this static web page in the localhost:8080/test/ directory:

That is, the actual URL is: localhost:8080/test/index.

You can view it through fiddler capture:

If you add /, it means: search in the root directory. This is because the return is redirected by default. If you include the root path, you will directly check whether there is such an html interface under the absolute path.

 

2.3.1 Request Forwarding VS Request Redirection

return can not only return a view, but also realize jump. There are two ways to jump:

  • forward: is request forwarding;
  • redirect: request redirection.

Comparison between request forwarding and redirection:

Request to forward: 

 Request redirection (of course, you can also use sendRedirect to redirect as in 2.2.1 above):

We will find:

Request forwarding means that the server side makes the request on behalf of the client, and then returns the result to the client, so the URL address remains unchanged during the entire request process; while request redirection means that the server side tells the client side, "Go to another place to visit", Therefore, the browser will resend the request again, so the URL finally displayed by the client is also the address of the final jump, not the address of the initial request, so the URL address has changed.

Guess you like

Origin blog.csdn.net/qq_63218110/article/details/130659168