Spring MVC [one article done]

Spring MVC

1. What is Spring MVC

Description from the official documentation:

​ Spring Web MVC is the original web framework built on the Servlet API and has been 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 referred to as "Spring MVC".

Summary from the official description:

1. Spring MVC is a web framework

2. Spring MVC is built on the basis of Servlet API

One of the frameworks that must be mastered in the web in Spring.

2. Introduction to MVC

MVC is the abbreviation of Model View Controller. It is a software architecture pattern in software engineering. It is divided into three basic parts: Model (model), View (view), and Controller (controller).

  • Model: is the part of the application that is used to process application data logic; usually the model object is responsible for accessing data in the database.
  • View: The part of the application that handles the display of data; usually views are created from model data
  • Controller: The part of the application that handles user interaction; (similar to security personnel)

The following figure is a flow chart:

insert image description here

2.1, the relationship between Spring MVC and MVC

​ The relationship between the two is similar to the relationship between IoC and DI; MVC is an idea, and Spring MVC is a concrete realization of the MVC idea and is a framework product.

IoC describes the goal, and DI describes the specific and achievable ideas.

In general: Spring MVC is a Web framework that implements the MVC pattern and inherits the Servlet API.

Although it is a web framework, when the user enters the url, the Spring MVC project can perceive the user's request.

3. Create Spring MVC

​ Creating Spring MVC is based on Spring Boot, so the previous creation steps are the same as Spring Boot, until the following figure, now the dependent link is different

insert image description here

Here you need to select Spring Web in Web and then you can see Spring MVC in the description inside.

After clicking next, you need to wait for a while, and then delete the redundant files in the directory after the idea is loaded; and some directory file descriptions, you can refer to the article created by Spring Boot for the project.

insert image description here

Fourth, master the core of Spring MVC☆☆☆☆

Learning Spring MVC only needs to master 3 functions:

1. The function of connection: connect the user (browser) with the java program, simply speaking, accessing a url address can call our Spring program.

2. The function of obtaining parameters: the user will bring some parameters when accessing, and find a way to obtain the parameters in the program.

3. The function of outputting data: After executing the business logic, the execution result needs to be returned to the user.

These three functions are the core of Spring MVC, that is to say, mastering these three functions will also master Spirng MVC. The following is the detailed analysis and use of these three functions.

4.1. Spring Hot Deployment

​ Now here is also the setting of Spring’s hot deployment. Hot deployment means that the idea will automatically update and deploy the latest code. It will not let you restart the Spring MVC program every time you code, otherwise it will be too troublesome. Use hot deployment to automatically update Deploy the code, and you can access the url without restarting the program again.

However, it may be unsuccessful when loading a new class. Wait for about 5 seconds. If it is unsuccessful, you can restart it. The effect of hot deployment may not be very good for file changes, but there is no problem for modifying code

1. First, add dependencies, dev-tool framework support

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
</dependency>

2. Turn on the automatic compilation of the current project in idea

insert image description here

3. Enable runtime hot deployment

insert image description here

My idea version is relatively old. If your current idea version is relatively high, or if you do not find the option ...app.runinng, you can perform the following operations:

insert image description here

Finally, use debug to start the project instead of the run method (otherwise it will be invalid)

4.2. Realize the connection between users and programs☆

The following codes have been used in Spring Boot and are relatively easy to understand.

@Controller
@ResponseBody // 返回一个非静态页面的数据
@RequestMapping("/user") // 路由地址
public class UserController {
    
    
    
    @RequestMapping("/hi") //localhost:8080/user/hi
    public String hi() {
    
    
        return "Hello ,Spring MVC!!!";
    }
}

Start the Spring MVC program and enter the url address to access the browser page.

4.2.1、@RequestMapping

The main thing to pay attention to in this code is @RequestMappingthe annotation, which can modify both the class and the method. By default, it supports both GET requests and post requests.

image-20230809114111963

But @RequestMappingannotations can also set the request type;

@RequestMapping(value = "/user" , method = RequestMethod.POST) // 路由地址

The parameter value is the default value, which can be omitted only when routing. The method parameter is used to set the request type. You can open it in the idea to view the source code to support those request parameters.

At this time, the Post request is set. When the Get request is used, an error prompt 401 Method Not Allowed will be reported.

4.2.2、@GetMapping/@PostMapping

​ These two annotations are actually the same as the parameter setting method in the @RequestMapping annotation, depending on which method you are used to.

@Controller
@ResponseBody // 返回一个非静态页面的数据
@RequestMapping("/user") // 路由地址
public class UserController {
    
    
    
    @PostMapping("/hi2") // http://localhost:8080/user/hi2
    public String hi2() {
    
    
        return "Hello ,Spring MVC2!!!";
    }
}

That is to say, this code only supports Post requests, and if you use Get requests forcibly, it will prompt 405. The usage of @GetMapping is also the same reason, so I won’t repeat it here.

4.3. Obtain parameters☆

4.3.1, pass a single parameter

​ The formal parameters in the code should be consistent with the formal parameters passed by the front end

@Controller
@ResponseBody // 返回一个非静态页面的数据
@RequestMapping(value = "/user" ) // 路由地址  method = RequestMethod.POST
public class UserController {
    
    

    @RequestMapping("/hi4") //localhost:8080/user/hi4
    public String hi4(String name) {
    
    
        return "Hello "+name;
    }
}

url:

http://localhost:8080/user/hi4?name=python

The code should be consistent with the parameter name passed by the front end, and the final print result is python; if nothing is entered, a null is returned.

4.3.2, transfer object

​ First, there must be an object:

import lombok.Data;
@Data // 复合注解,基于lombok依赖,里面包含了 @Getter + @Setter + @ToString
public class User {
    
    
    private int id;
    private String name;
    private String password;
    private int age;
}

get the object:

@Controller
@ResponseBody // 返回一个非静态页面的数据
@RequestMapping(value = "/user" ) // 路由地址  method = RequestMethod.POST
public class UserController {
    
    
    @RequestMapping("/add") // localhost:8080/user/add
    public String add(User user) {
    
     // 这里就是拿到了这个对象
        return user.toString();
    }
}

url:

http://localhost:8080/user/add?id=1&name=java&password=123&age=18

result:

User(id=1, name=java, password=123, age=18)

If the parameter name in the url does not correspond to the parameter name in the backend code, then the uncorresponding attribute in the object is null

4.3.3. Form passing parameters

This can mainly be delivered by Postman, just enter it directly

image-20230809150331689

4.3.4, back-end mapping front-end parameters

​ After all, the front and back ends are separated, so the code is not written by the same person. Sometimes when the work is handed over, the newcomer changes the parameter name of the old man. If the front end is inconsistent, the front end parameters cannot be received. There are two ways to solve this problem.

1. Change the password of the backend to pwd. This method is not acceptable. When the project is large, changing the name will implicate other backend codes. The more you change, the more mistakes you make, so this method is not advisable❌ ❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌

2. Use @RequestParamannotations to map front-end and back-end parameter values

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/login") //localhost:8080/user/login
    public String login(String name ,@RequestParam("pwd") String password) {
    
    
        return "name= " + name+ "| password=" +password;
    }
}

Map the pwd parameter of the front end to the password variable of the back end

url:

http://localhost:8080/user/login?name=java&pwd=987

Result: name=java|password=987

With @RequestParamthe annotation, even if the front-end passes the pwd, the parameters of the back-end can also be well mapped to the front-end.

4.3.5, @RequestParam (the parameter is not nul)

As can be seen from the above, the first function can be renamed to realize the front-end and back-end mapping; the second function is that the parameter cannot be null; example: when performing a login operation, the account and password must be entered. In order to prevent it from being null, you can set it in that parameter Annotate in front @RequestParam;

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    
    @RequestMapping("/login2") //localhost:8080/user/login2
    public String login2(@RequestParam String name ,@RequestParam String password) {
    
    
        return "name= " + name+ "| password=" +password;
    }
}

url:

localhost:8080/user/login2?name=java

Error:

{

“timestamp”: “2023-08-09T07:28:59.552+00:00”,

“status”: 400,

“error”: “Bad Request”,

}

The prompt is that the request failed, so after adding the @RequestParam annotation, their parameters cannot be null

4.3.6, optional parameters

@RequestParamThe third function is that after setting the mapping of front-end and back-end parameters, it is an optional parameter. There is a piece of code in the source code of the annotation @RequestParamisboolean required() default true;The meaning of this code is that it must be passed. If you change its parameter to false, it does not have to be passed.

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/login3") //localhost:8080/user/login2
    public String login3(@RequestParam String name ,@RequestParam(value = "pwd",required = false) String password) {
    
    
        return "name= " + name+ "| password=" +password;
    }
}

url:

localhost:8080/user/login3?name=java

result:

name= java| password=null

Programmers set required = false to set it as a non-required parameter.


@RequestParamFunction summary:

1. Front-end and back-end parameter mapping;

2. Set the required parameters;

3. Front-end and back-end parameter mapping + optional parameter required = false


4.3.7. Get a Json object

​ Obtaining the front-end Json object requires an annotation. @RequestBodyThis annotation lets the back-end know that the data passed by the front-end is a Json format.

If it is not annotated, the backend will respond with a null if it cannot receive

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/loginByJson") // localhost:8080/user/loginByJson
    public String loginByJson(@RequestBody User user){
    
     // Json 是对象要用对象来接受形参
        return "name= " + user.getName()+ "| password=" +user.getPassword();
    }
}

Json:

{
    
    "name":"java","password":"123"}

result:

name= java| password=123

Annotations must be added to obtain the data in the Json format of the front end @RequestBody. She said that the backend should be prompted to obtain a data in Json format from the front end.

4.3.8. Get the parameters in the URL

The url address under normal circumstances: http://localhost:8080/login ?name…

But some url addresses: http://localhost:8080/ {name}/{password}…

​ Some companies use keywords in order to have a higher search ranking on search engines. The general url address is followed by parameters, but some urls: http://localhost:8080/java/ How to learn java well ? URLs like /123/… will have keywords, and they will rank higher on search engines.

​ Then get the parameters from the path of the url need to use @PathVariableannotations, code implementation:

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    
    @RequestMapping("/loginByPath/{name}/{passwrod}") 
    public String loginByPath( @PathVariable String name,
                               @PathVariable("passwrod") String pwd) {
    
    
        return "name= " + name+ "| password=" +pwd;
    }
}

url:

http://localhost:8080/user/loginByPath/java/234

result:

name= java| password=234


Summary @PathVariablehas two functions:

1. Get the parameters in the url

2. @RequestParamIt has the function of front-end and back-end mapping with annotations, corresponding to {password} in the front-end url


4.3.9. Get uploaded files

​ When the front end passes a picture or a file, one of the annotations in Spring @RequestPartis to receive the file, and then put the file into the specified directory.

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/upFile") // localhost:8080/user/upFile
    public String upFile(Integer id, @RequestPart("photo")MultipartFile file) throws IOException {
    
    
        //业务处理....
        file.transferTo(new File("E:\\a.png"));
        return "id:"+id+" 图片上传成功!";
    }
}

The "photo" in the annotation @RequestPartcorresponds to the front-end parameters. Here, postman is used to simulate the front-end

image-20230810095128576

But there is a problem with this code. When you need to transfer pictures in batches, transferring them to the E drive will directly overwrite a.png, and no new files will be generated. Therefore, the code needs to be improved to allow each file to generate a unique id. , so that it will not be swallowed by coverage.

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/upFile") // localhost:8080/user/upFile
    public String upFile(Integer id, @RequestPart("photo")MultipartFile file) throws IOException {
    
    
        //业务处理....
        // 1、生成唯一的id
        String fileName = UUID.randomUUID().toString(); // UUID是唯一id:时间轴+网卡号+随机数....
        // 2、获取上传文件名的后缀
        String fileType = file.getOriginalFilename().substring(
                file.getOriginalFilename().lastIndexOf(".") 
        ); // 获取后缀名
        fileName += fileType; // 组成完整的文件名
        file.transferTo(new File("E:\\"+fileName));
        return "id:"+id+" 图片上传成功!";
    }

image-20230810100350375

Use UUID in the java program to generate a unique id, and then intercept the suffix of the file, and add the unique id and suffix to form a complete new picture and pass it into the specified directory; but the specified directory is best configured in the configuration The file summary is convenient for the final maintenance. If you don't understand the code, just change the configuration file.

4.3.10. Get Cookie/Session/ header

​ Why are there Cookie and Session? Because in the http protocol or the https protocol, their characteristics are connectionless (no long connection, only one response), stateless (the request sent last time has nothing to do with the previous one), for example, logging in to a website requires input account password, then due to the characteristics of the http protocol, you will enter the account number and password every time you visit the information in this website, which is very troublesome and has a very poor user experience. In order to solve this problem, cookies and sessions appear ;

Cookie: When a user first logs in to a website with an account number and password, the browser will store the successful login information in the cookie so that when visiting other pages of the website, your information has been verified and there is no need to log in again; but cookies One disadvantage is that the cookie information is stored on the customer service side. If there is a client side, security issues will be considered. Users can simulate cookies and write some of their own things in the cookies. In order to solve security problems, sessions appear.

Session: In order to solve the problem caused by Cookie, then Session puts the user's information in the server, and the Session also stores key-value pairs in the server, and the id value of the Session changes dynamically. Stored in the Cookie, the browser will find the corresponding value in the server after getting the Session id, thus solving the problem, but the Session is not absolutely safe, because some people will hijack the Session id and use the id to find it in the server. value, but a feature of Session is that the id is dynamically changed. When you get the id, the id may have changed. Relatively speaking, the security is relatively high, but it is not absolutely safe.

4.3.11. Obtaining Cookies

The method of Spring MVC annotation is used here, @CookieValuebut the method of Sevelet can also be used.

@Controller
@ResponseBody 
@RequestMapping(value = "/user") 
public class UserController {
    
    

    @RequestMapping("/getCookie") // localhost:8080/user/getCookie
    public String getCookie(@CookieValue String name) {
    
    
        return "Cookie-name=" + name;
    }
}

@CookieValue(“xxx”), the name parameter of the Cookie is in the brackets, which is consistent with the parameter of name, so no need to add brackets

Because it is a simulation, so set up the simulation in the browser

image-20230810121629577

4.3.12. Get the header

​ User-Agent is a common header in requests.

@Controller
@ResponseBody 
@RequestMapping(value = "/user") 
public class UserController {
    
    

    @RequestMapping("/getAgent") // localhost:8080/user/getAgent
    public String getAgent(@RequestHeader("User-Agent") String userAgent) {
    
    
        return userAgent;
    }
}

​ Obtain the annotation used by the User-Agent in the http protocol @Requestheader.

4.3.13. Get Session

​ Because it is a simulation, first set and store a Session by yourself.

@Controller
@ResponseBody 
@RequestMapping(value = "/user") 
public class UserController {
    
    
    @RequestMapping("/setSession") // localhost:8080/user/setSession
    public String setSession(String name, HttpServletRequest req) {
    
    
        HttpSession session = req.getSession(true); // 有Session就获取,没有就创建
        if (session != null) {
    
    
            session.setAttribute("name", name);
        }
        return "Session 设置成功!";
    }
}

url:

localhost:8080/user/setSession?name=java

Get Session:

@Controller
@ResponseBody 
@RequestMapping(value = "/user")
public class UserController {
    
    
    @RequestMapping("/getSession") 
    public String getSession(@SessionAttribute(name = "name", required = false) String name) {
    
    
        return name;
    }
}

url:

// localhost:8080/user/getSession

4.4. Input data

​ Return data By default, a static page is returned. For the output of the static page, write the code of the static page under the directory, and then wake up the url access at the back end.

@Controller
public class TestController {
    
    

    @RequestMapping("/index") // localhost:8080/index
    public String getIndex() {
    
    
        return "index.html";
    }
}

​ The code above does not add @ResponseBody, so the output is always a static page, and now a calculator function is completed so that it returns a data.

@Controller
public class TestController {
    
    

    @RequestMapping("/calc") //localhost:8080/calc
    @ResponseBody
    public String calc(Integer num1, Integer num2) {
    
    
        return "计算结果:" + (num1 + num2);
    }
}

url:

http://localhost:8080/calc?num1=5&num2=10

result:

Calculated result: 15

This is the page returned by using @ResponseBody is data, and it has been mentioned many times that @ResponseBody will not be additionally traced.

4.4.1. Return Json object

​ Returning a Json object requires a HashMap to return the Json object format:

@Controller
public class TestController {
    
    

    @RequestMapping("/json") // localhost:8080/json
    @ResponseBody
    public HashMap<String,String> json() {
    
    
        HashMap<String ,String > hashMap = new HashMap<>();
        hashMap.put("name","java");
        hashMap.put("password","123");
        return hashMap;
    }
}

​ If you don’t use the HashMap method, you use the string printing method, which makes no difference to the user in the browser page, but for the front-end transmission is the type of html format, when the front-end uses data, it will not recognize it. To, more errors may occur, so when using Json data, the backend needs to use HashMap.

4.5. Forwarding and redirection

forward VS redirect

  • redirect (redirect): the URL becomes a redirected URL, the page display is normal, and external links can be accessed;
  • Forward (forwarding): The URL has not changed, there may be problems with the accessed pages, and external resources may not be loaded (re-forwarding is done by the server side, and there may be problems with routing address positioning)
@Controller
//@ResponseBody
@RequestMapping("/test")
public class TestController {
    
    

    @RequestMapping("/myForward") // localhost:8080/test/myForward
    public String myForward() {
    
    
        return "forward:/test.html";
    }

    @RequestMapping("/myRedirect") // localhost:8080/test/myRedirect
    public String myRedirect() {
    
    
        return "redirect:/test.html";
    }
}

​ In one case, it is more convenient to use redirection, but it is troublesome and error-prone to forward, but remember the difference between the two, which is often tested in interviews.

Guess you like

Origin blog.csdn.net/qq_54219272/article/details/132240238
Recommended