Review the native Servlet to get the request parameters
Get through Servlet API
-
Take HttpServletRequest as the formal parameter of the controller method. At this time, the parameter of HttpServletRequest type represents the object encapsulating the request message of the current request.
An HTTP request message consists of four parts: request line, request header, blank line and request data
case
-
Create test_ param. The HTML page is used to test the effect of obtaining request parameters
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test request parameters</title> </head> <body> <h1>Test request parameters</h1> <a th:href="@{/testServletAPI(name='tom', age=18)}">Test use ServletAPI Get request parameters</a><br/> </body> </html>
-
Create the Controller and write the corresponding Controller method
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; /** * @ClassName ParamController * @Description: Test the function of obtaining request parameters * @Author Laoyang * @Date 2022/1/7 11:13 */ @Controller public class ParamController { /** * Jump to test_param page */ @RequestMapping("/param") public String doTestParam() { return "test_param"; } /** * Get request parameters through servlet API * The request of the formal parameter position represents the current request (through which the data in the current request can be obtained) * > In the actual development, the request is rarely used, and it is usually obtained by annotation */ @RequestMapping("/testServletAPI") public String testServletAPI(HttpServletRequest request){ String name = request.getParameter("name"); String age = request.getParameter("age"); System.out.println(name + "--->" + age); // tom--->18 return "success"; } }
-
Start Tomcat to test the effect
-
Browser effect
-
Console effect
-
Obtain the request parameters through the formal parameters of the controller method
- Set the formal parameter with the same name as the request parameter at the formal parameter position of the controller method. When the browser sends the request and matches the request mapping, the request parameter will be assigned to the corresponding formal parameter in the dispatcher servlet
Set character encoding format
-
Why?
If we don't set the character code, the Chinese data submitted by the form will cause garbled code. Therefore, set the corresponding character code first, so we don't have to worry about the problem of garbled code in the later test.
On the web Set character encoding in XML file
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- Set character encoding format --> <filter> <filter-name>encoding-filter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding-filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Ps: Although I only write the code for setting the character code here, the previous configurations need to be added (such as those for registering the front-end controller). I won't show them all here for simplicity.
Characterencoding filter part of the source code
public class CharacterEncodingFilter extends OncePerRequestFilter { // Character encoding format @Nullable private String encoding; // Force manually set encoding format private boolean forceRequestEncoding = false; private boolean forceResponseEncoding = false; public void setForceEncoding(boolean forceEncoding) { this.forceRequestEncoding = forceEncoding; this.forceResponseEncoding = forceEncoding; } @Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String encoding = getEncoding(); if (encoding != null) { // If forceRequestEncoding is not false or the character encoding of the request has not been set, set the character encoding of the request if (isForceRequestEncoding() || request.getCharacterEncoding() == null) { request.setCharacterEncoding(encoding); } // If forceResponseEncoding is not false, set the character encoding of the response if (isForceResponseEncoding()) { response.setCharacterEncoding(encoding); } } // If encoding is not configured, the default encoding format is used filterChain.doFilter(request, response); } }
case
No request parameter with the same name
-
In test_param.html page authoring hyperlink
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test request parameters</title> </head> <body> <h1>Test request parameters</h1> <!-- Obtain the request parameters through the formal parameters of the controller method --> <a th:href="@{/parameter(name='tom', age=18)}">Obtain the request parameters through the formal parameters of the controller method</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; @Controller public class ParamController { /** * Obtain the request parameters through the formal parameters of the controller method (no duplicate name attribute writing method) * If no request parameter with the same name is passed, you only need to keep the passed request parameter name consistent with the parameter name in the controller method */ @RequestMapping("/parameter") public String doParameter(String name, Integer age) { System.out.println(name + "--->" + age); // tom--->18 return "success"; } }
-
Start Tomcat to see the effect
Console printing: admin --- > 12345 --- > basketball, football
Request parameters with the same name
-
In test_param.html page authoring form
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test request parameters</title> </head> <body> <h1>Test request parameters</h1> <form method="get" th:action="@{/parameter2}"> user name:<input name="username" type="text"><br/> password:<input name="password" type="text"><br/> Hobbies:<input name="hobby" type="checkbox" value="Basketball">Basketball <input name="hobby" type="checkbox" value="Football">Football <input name="hobby" type="checkbox" value="badminton">badminton <br/> <input type="submit" value="Submit test"> </form> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; @Controller public class ParamController { /** * Obtain the request parameters through the formal parameters of the controller method (no duplicate name attribute writing method) * If multiple request parameters with duplicate names are passed (such as check boxes in the form), you can receive them in the following ways: * 1,The request parameter name can be received in the same way as the control parameter name (String hobby). Multiple values are separated by commas (a,b,c) by default * 2,You can use an array to receive (String[] hobby) * > You can use it according to your own needs */ @RequestMapping("/parameter2") public String doParameter2(String username, String password, String[] hobby) { // System.out.println(username + "--->" + password + "--->" + hobby); System.out.println(username + "--->" + password); System.out.println(Arrays.toString(hobby)); return "success"; } }
-
Start Tomcat to see the effect
The effect is the same as that of parameters without the same name. The corresponding request parameters can be obtained
@Get request parameters with RequestParam annotation
-
@RequestParam is to create a mapping relationship between the request parameters and the formal parameters of the controller method
-
@The RequestParam annotation has three attributes:
-
value: Specifies the parameter name of the request parameter assigned to the formal parameter
-
required: sets whether this request parameter must be transmitted. The default value is true
If it is set to true, the current request must transmit the request parameter specified by value. If the request parameter is not transmitted and the defaultValue property is not set, the page will report an error 400: Required String parameter 'xxx' is not present; If it is set to false, the current request does not have to transmit the request parameter specified by value. If there is no transmission, the value of the formal parameter identified by the annotation is null
-
defaultValue: whether the required property value is true or false, when the request parameter specified by value is not transmitted or the transmitted value is "" (empty string), the default value is used to assign value to the formal parameter
-
case
-
In test_param.html page authoring form
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test request parameters</title> </head> <body> <h1>Test request parameters</h1> <!-- Get request parameters using annotation --> <form method="get" th:action="@{/parameter3}"> <!-- User name set to user_name,So back-end username The formal parameter cannot be received It needs to be used at this time @RequestParam Get annotation --> user name:<input name="user_name" type="text"><br/> password:<input name="password" type="text"><br/> Hobbies:<input name="hobby" type="checkbox" value="Basketball">Basketball <input name="hobby" type="checkbox" value="Football">Football <input name="hobby" type="checkbox" value="badminton">badminton <br/> <input type="submit" value="Submit test"> </form> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; @Controller public class ParamController { @RequestMapping("/parameter3") public String doParameter3(String username,String password,String[] hobby) { // System.out.println(username + "--->" + password + "--->" + hobby); System.out.println(username + "--->" + password); System.out.println(Arrays.toString(hobby)); return "success"; } }
In order to make you see better results, I don't add @ RequestParam annotation here
-
Start Tomcat to see the effect
The effect in the browser is basically no problem, but the effect printed in the console is: null - > 12345 - > basketball and football
Although the browser sends the request with user_name, but there is no parameter in the controller method that can receive this value, so the final value is null
-
Use the @ RequestParam annotation to get the request parameters
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; @Controller public class ParamController { /** * Use the @ RequestParam annotation to get the request parameters * Parameter Description: * name: Request parameter name * value: Request parameter name (this parameter uses more than name, but the effect is the same) * required: The default value is true, indicating whether the request parameters corresponding to value or name must be transmitted * (For example, the corresponding request parameter here is user_name, if we find that there is no user in the request parameters when requesting mapping_ If the value is name, 400 will be reported.) * defaultValue: Default value. If the request parameters corresponding to value or name are not transmitted, the default value we set will be used * If the corresponding request parameter is transmitted, the transmitted value is used * This property sets the required value to false */ @RequestMapping("/parameter3") public String doParameter3(@RequestParam(value = "user_name", defaultValue = "haha") String username, String password, String[] hobby) { // System.out.println(username + "--->" + password + "--->" + hobby); System.out.println(username + "--->" + password); System.out.println(Arrays.toString(hobby)); return "success"; } }
You can set it in combination with the attribute description in the comment, and then test the corresponding effect. I won't show it one by one here
-
Retest
Console printing: admin --- > 123456 --- > basketball and football (these are the specific printed data, but the format is different, so don't be too serious). Because we also set the default value, if you submit the form_ If the name is empty, the final print is haha --- > 123456 --- > basketball and football. If you are interested, you can test it
@RequestHeader annotation
- @The RequestHeader creates a mapping relationship between the request header information and the formal parameters of the controller method
- @The RequestHeader annotation has three attributes: value, required and defaultValue. The usage is the same as @ RequestParam
case
-
In test_param.html page authoring hyperlink
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test request parameters</title> </head> <body> <h1>Test request parameters</h1> <!-- use @RequestHeader Annotation get request header information --> <a th:href="@{/header}">test@RequestHeader Annotation get request header information</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import java.util.*; @Controller public class ParamController { /** * Use the @ RequestHeader annotation to get the request header information * You can use Map to obtain all the request header information, or only one parameter in the request header information * > @RequestHeader The attribute of the annotation is the same as that of the @ RequestParam annotation, so I won't talk about it here */ @RequestMapping("/header") public String doHeader(@RequestHeader("Host") String host, @RequestHeader Map<String, String> headers) { for (Map.Entry<String, String> map : headers.entrySet()) { System.out.println(map.getKey() + ":" + map.getValue()); } System.out.println("host: " + host); return "success"; } }
-
Start Tomcat to see the effect
- The browser is the effect of successful page Jump
- It mainly depends on the console printing. You can also directly set the Map as the return value, then save the obtained request header into the Map and return it. In this way, you can see the obtained request header data in the page (you can also directly use F12 to view it)
@CookieValue
- @Cookie value is to create a mapping relationship between cookie data and formal parameters of the controller method
- @The CookieValue annotation has three attributes: value, required and defaultValue. The usage is the same as @ RequestParam
case
-
In test_param.html page authoring hyperlink
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test request parameters</title> </head> <body> <h1>Test request parameters</h1> <!-- use @CookieValue Annotation acquisition Cookie information --> <a th:href="@{/cookie}">test@CookieValue Annotation get request header information</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.*; @Controller public class ParamController { /** * Get Cookie information using @ Cookie value annotation * > Note: everyone's cookie s may be different, which can be viewed in browser F12 */ @RequestMapping("/cookie") public String doCookie(@CookieValue("JSESSIONID") String jsessionid) { System.out.println("---->" + jsessionid); return "success"; } }
-
Start Tomcat to see the effect
- It mainly depends on the printing effect of the console, so there is no screenshot here. You can check it yourself
Get request parameters through POJO
You can set a formal parameter of entity class type at the formal parameter position of the controller method. At this time, if the parameter name of the request parameter transmitted by the browser is consistent with the attribute name in the entity class, the request parameter will assign a value to this attribute.
case
-
Write the corresponding entity class
package com.laoyang.mvc.pojo; public class User { private String username; private String password; private String sex; private Integer age; private String email; public User() { } public User(String username, String password, String sex, Integer age, String email) { this.username = username; this.password = password; this.sex = sex; this.age = age; this.email = email; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", sex='" + sex + '\'' + ", age=" + age + ", email='" + email + '\'' + '}'; } }
-
In test_param.html page authoring form
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test request parameters</title> </head> <body> <h1>Test request parameters</h1> <!-- adopt POJO Get request parameters --> <form th:action="@{/doUser}" method="post"> user name:<input type="text" name="username"><br/> password:<input type="password" name="password"><br/> Gender:<input type="radio" name="sex" value="male">male <input type="radio" name="sex" value="female">female<br/> Age:<input type="text" name="age"><br/> Email:<input type="text" name="email"><br/> <input type="submit" value="test pojo Get parameters"> </form> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import com.laoyang.mvc.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.*; @Controller public class ParamController { /** * Get request parameters through POJO * This is the best way to transmit multiple request parameters * If all of them are written in the formal parameters of the controller method, it will be very redundant and troublesome */ @RequestMapping("/doUser") public String doPojo(User user) { System.out.println(user); return "success"; } }
-
Start Tomcat to see the effect
At this time, after the browser inputs the form data, the controller method can normally get the corresponding parameter values and print them (remember to configure the coding format!)
Domain objects share data
-
To clean up, create a new project to demonstrate the same thing as before: Web xml,spring-mvc.xml,pom.xml
-
HelloController:
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { /** * Jump to home page */ @RequestMapping("/") public String doIndex() { return "index"; } }
-
index.html:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>home page</title> </head> <body> <h1>home page</h1> </body> </html>
Use the servlet API to share data with the request domain object
-
In index Writing hyperlinks in HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>home page</title> </head> <body> <h1>home page</h1> <!-- use ServletAPI towards request Domain objects share data --> <a th:href="@{/doServletAPI}">use ServletAPI towards request Domain objects share data</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @Controller public class ScopeController { /** * Use the servlet API to share data with the request domain object */ @RequestMapping("/doServletAPI") public String doRequest(HttpServletRequest request) { request.setAttribute("name", "I'm Zhang San!"); return "success"; } }
-
Create success HTML page and get the domain object
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test multiple ways to get domain objects</title> </head> <body> <h1>Test multiple ways to get domain objects</h1> <p th:text="${name}"></p> </body> </html>
-
Start Tomcat to see the effect
Use ModelAndView to share data with the request domain object
-
In index Writing hyperlinks in HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>home page</title> </head> <body> <h1>home page</h1> <!-- use ModelAndView towards request Domain objects share data --> <a th:href="@{/doModelAndView}">use ModelAndView towards request Domain objects share data</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.util.Map; @Controller public class ScopeController { /** * Use ModelAndView to share data with the request domain object */ @RequestMapping("/doModelAndView") public ModelAndView doModelAndView() { ModelAndView modelAndView = new ModelAndView(); // Process model data, that is, share data with the request domain request modelAndView.addObject("modelAndView", "Hello, ModelAndView"); // Set the view name (that is, the page name) modelAndView.setViewName("success"); return modelAndView; } }
-
In success Get domain object from HTML page
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test multiple ways to get domain objects</title> </head> <body> <h1>Test multiple ways to get domain objects</h1> <!-- use ModelAndView Shared data --> <p th:text="${modelAndView}"></p> </body> </html>
-
Start Tomcat to see the effect
Use the Model to share data with the request domain object
-
In index Writing hyperlinks in HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>home page</title> </head> <body> <h1>home page</h1> <!-- use Model towards request Domain objects share data --> <a th:href="@{/doModel}">use Model towards request Domain objects share data</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.util.Map; @Controller public class ScopeController { /** * Use the Model to share data with the request domain object */ @RequestMapping("/doModel") public String doModel(Model model) { model.addAttribute("model", "Code man, code soul!"); return "success"; } }
-
In success Get domain object from HTML page
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test multiple ways to get domain objects</title> </head> <body> <h1>Test multiple ways to get domain objects</h1> <!-- use Model Shared data --> <p th:text="${model}"></p> </body> </html>
-
Start Tomcat to see the effect
Use Map to share data with the request domain object
-
In index Writing hyperlinks in HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>home page</title> </head> <body> <h1>home page</h1> <!-- use Map towards request Domain objects share data --> <a th:href="@{/doMap}">use Map towards request Domain objects share data</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.util.Map; @Controller public class ScopeController { /** * Use Map to share data with request domain objects */ @RequestMapping("/doMap") public String doMap(Map<String, Object> map) { // Every data added in the map is a shared data map.put("map", "Code white!"); return "success"; } }
-
In success Get domain object from HTML page
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test multiple ways to get domain objects</title> </head> <body> <h1>Test multiple ways to get domain objects</h1> <!-- use ModelMap Shared data --> <p th:text="${modelMap}"></p> </body> </html>
-
Start Tomcat to see the effect
Use ModelMap to share data with request domain objects
-
In index Writing hyperlinks in HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>home page</title> </head> <body> <h1>home page</h1> <!-- use ModelMap towards request Domain objects share data --> <a th:href="@{/doModelMap}">use ModelMap towards request Domain objects share data</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.util.Map; @Controller public class ScopeController { /** * Use ModelMap to share data with request domain objects */ @RequestMapping("/doModelMap") public String doModelMap(ModelMap modelMap) { modelMap.addAttribute("modelMap", "2022 No bug!!!"); return "success"; } }
-
In success Get domain object from HTML page
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test multiple ways to get domain objects</title> </head> <body> <h1>Test multiple ways to get domain objects</h1> <!-- use ModelMap Shared data --> <p th:text="${modelMap}"></p> </body> </html>
-
Start Tomcat to see the effect
Relationship between Model, ModelMap and Map
There are five ways to share:
- First: use servlet API (not recommended)
- Second: use ModelAndView
- Third: use Model
- Fourth: use Map
- Fifth: use ModelMap
Relationship between Model, Map and ModelMap:
BindingAwareModelMap And part of the parent source code: public class BindingAwareModelMap extends ExtendedModelMap {} public class ExtendedModelMap extends ModelMap implements Model {} public class ModelMap extends LinkedHashMap<String, Object> {} All three ways are through BindingAwareModelMap Class to instantiate: because BindingAwareModelMap Inherited ExtendedModelMap,and ExtendedModelMap Inherited ModelMap,therefore BindingAwareModelMap Yes ModelMap Instantiate because BindingAwareModelMap Inherited ExtendedModelMap,and ExtendedModelMap Realized Model,therefore BindingAwareModelMap Yes Model Instantiate because BindingAwareModelMap Inherited ExtendedModelMap,and ExtendedModelMap Inherited ModelMap,and ModelMap Inherited again LinkedHashMap,So you can be right Map Instantiate
Use the servlet API to share data to the session domain
-
In index Writing hyperlinks in HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>home page</title> </head> <body> <h1>home page</h1> <!-- use ServletAPI towards session Domain shared data --> <a th:href="@{/doSession}">use ServletAPI towards session Domain shared data</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.Map; @Controller public class ScopeController { /** * Use the servlet API to share data to the Session domain */ @RequestMapping("/doSession") public String doSession(HttpSession session) { session.setAttribute("servletApi", "This is session data~"); return "success"; } }
-
In success Get session domain object from HTML page
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test multiple ways to get domain objects</title> </head> <body> <h1>Test multiple ways to get domain objects</h1> <!-- use ServletAPI towards Session Domain shared data --> <p th:text="${session.servletApi}"></p> </body> </html>
Note: when obtaining session data on the page, you need to use "session. Attribute" to obtain the corresponding value
-
Start Tomcat to see the effect
Use the servlet API to share data with the application domain
-
In index Writing hyperlinks in HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>home page</title> </head> <body> <h1>home page</h1> <!-- use ServletAPI towards application Domain shared data --> <a th:href="@{/doApplication}">use ServletAPI towards application Domain shared data</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.Map; @Controller public class ScopeController { /** * Use the servlet API to share data with the application domain */ @RequestMapping("/doApplication") public String doApplication(HttpSession session) { ServletContext application = session.getServletContext(); application.setAttribute("applicationScope", "This is application My data!"); return "success"; } }
-
In success Get the application domain object from the HTML page
<!DOCTYPE html> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Test multiple ways to get domain objects</title> </head> <body> <h1>Test multiple ways to get domain objects</h1> <!-- use ServletAPI towards application Domain shared data --> <p th:text="${application.applicationScope}"></p> </body> </html>
The calling method is similar to that of session, and the domain object corresponding to "" The corresponding property can get the corresponding value
-
Start Tomcat to see the effect
Description of four scopes
application scope
-
If the variable is placed in application, its scope is application.
-
Effective range: the effective range of application is the entire application; The whole application refers to from the start of the application to the end of the application. We didn't say "from server startup to server shutdown" because a server may deploy multiple applications. Of course, if you shut down the server, all the above applications will be shut down.
The variables in the application scope have the longest survival time. If they are not deleted manually, they can be used all the time.
-
Object getAttribute (String name) / / get information from application;
-
void setAttribute (String name,Object value) / / set information to the application scope.
session scope
- If you put a variable into a session, it means that its scope is session (the session is stored in the memory of the server).
- Valid range: its valid range is the current session; The so-called current session refers to the process from the user opening the browser to the user closing the browser.
- Object HttpSession.getAttribute (String name) / / get information from session.
- void HttpSession.setAttribute (String name,Object value) / / save the information to the session.
- HttpSessionHttpServletRequest. Getsession() / / get the object of the session where the current request is located.
understand
-
The session starts when the browser sends the first HTTP request. However, it is difficult to judge the end, because the server will not be notified when the browser is closed, so it can only be judged by the following methods:
If the client does not respond within a certain period of time, the session is considered to be over.
-
The default value of Tomcat is 120 minutes, but this value can also be set through the setmaxinactivival() method of HttpSession:
void setMaxInactiveInterval(int interval)
-
If you want to actively end the session, for example, when the user clicks the logout button, you can use the invalidate() method of HttpSession to forcibly end the current session
Three ways to delete a session
- Session timeout: timeout refers to that the server has not received the request of the client corresponding to the session for a continuous period of time, and this time exceeds the maximum session timeout set by the server.
- The program calls httpsession invalidate()
- Server shutdown or service stop
be careful
- Access * Because the static resources of html will not be compiled into servlets, the problem of session is not involved.
- When the JSP page does not explicitly prohibit the session, when the browser opens and requests the JSP for the first time, the server will automatically create a session for it, give it a sessionID and send it to the browser of the client.
- Since session consumes memory resources, if you do not intend to use session, you should close it in all JSP S.
- session will not be deleted when the browser is closed, but can only be deleted in the above three ways.
request scope
-
The variables in request can span two pages before and after forward, but as long as the page is refreshed, they are recalculated.
-
Request forwarding: servlet getRequestDispatcher("new.jsp"). forward(req,resp);
be careful:
- Forwarding is server behavior, while redirection is client behavior.
- No matter how it is forwarded on the server, the address of the original Servlet is still displayed in the browser address bar.
page scope
- The scope of the page object is limited to the current page requested by the user
- The life cycle of request and page is short. The difference between them is that a request can contain multiple page pages (include, forward and filter).
For more, see the blog written by this big man: https://m.php.cn/article/418934.html
View of spring MVC
- The View in spring MVC is the View interface. The function of the View is to render data and show the data in the Model to the user. There are many kinds of spring MVC views, including forwarding View and redirection View by default;
- When the project introduces jstl dependency, the forwarding view will be automatically converted to JstlView
- If the view technology used is Thymeleaf, the view parser of Thymeleaf is configured in the configuration file of spring MVC. After the view parser parses, the ThymeleafView is obtained
ThymeleafView
When the view name set in the controller method does not have any prefix, the view name will be parsed by the view parser configured in the spring MVC configuration file. The final path obtained by splicing the view prefix and view suffix will jump through forwarding.
case
-
Create view HTML page and write hyperlinks
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>View test</title> </head> <body> <h1>SpringMVC view</h1> <a th:href="@{/doThymeleafView}">test ThymeleafView</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ViewController { /** * Jump to view test page */ @RequestMapping("/doView") public String doView() { return "view"; } /** * Default (no prefix) * ThymeleafView View object */ @RequestMapping("/doThymeleafView") public String doThymeleafView() { return "success"; } }
-
Start Tomcat to see the effect
- The normal effect is that you can normally access the view page and the success page. There is no screenshot here (localhost: 8080 / spring MVC / doview)
- See the principle analysis below for the implementation principle
Principle analysis
Partial source code:
public class DispatcherServlet extends FrameworkServlet { protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = null; mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // Process model data and view information encapsulated by ModelAndView processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } // Process model data and view information encapsulated by ModelAndView private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception { if (mv != null && !mv.wasCleared()) { // If the view is not empty, the view is rendered render(mv, request, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } } // Render view protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { // Localization (that is, the local environment, which is composed of two parts, one is the language code and the other is the country code. For example, zh_CH means "Chinese _china") Locale locale = (this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale()); response.setLocale(locale); View view; // Get view name String viewName = mv.getViewName(); if (viewName != null) { /* The view object is obtained according to the view name and the model data encapsulated in ModelAndView Because we did not set the prefix when the controller method returned, we created a thymeleafview (view object) > It can be simply understood as: when the view name set in the controller method does not have any prefix, the result is the ThymeleafView view object */ view = resolveViewName(viewName, mv.getModelInternal(), locale, request); if (view == null) { throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" + getServletName() + "'"); } } } }
Note: the above is only part of the source code analysis. If you want to see more detailed, you can explore the source code yourself!
Forwarding view
-
The default forwarding view in spring MVC is internal resource view
-
Create forwarding view in spring MVC:
When the view name set in the controller method is prefixed with "forward:", the InternalResourceView view will be created. At this time, the view name will not be resolved by the view parser configured in the spring MVC configuration file, but the prefix "forward:" will be removed, and the rest will be used as the final path to jump through forwarding.
For example, "forward: /", "forward:/employee"
case
-
In view Writing hyperlinks in HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>View test</title> </head> <body> <h1>SpringMVC view</h1> <a th:href="@{/doForward}">test InternalResourceView</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ViewController { /** * Jump to view test page */ @RequestMapping("/doView") public String doView() { return "view"; } /** * Default (no prefix) * ThymeleafView View object */ @RequestMapping("/doThymeleafView") public String doThymeleafView() { return "success"; } /** * Forwarding view (prefix: "forward:") * InternalResourceView View object */ @RequestMapping("/doForward") public String doInternalResourceView() { /* 1,When forward is used as the prefix, the specific page cannot be accessed directly (404 will be reported), because the page must be accessed through the server >Wrong writing: return "forward:success"; 2,If you want to access a specific page through forward, you can forward it to a controller method that jumps to a page (the request path set by the controller method) For example: forward: / dothymleafview 3,Here, the address shown on the final page is / doForward, not / dothymleafview */ return "forward:/doThymeleafView"; } }
-
Start Tomcat to see the effect
- The normal effect is that you can normally access the view page and success page. There are no screenshots here
Principle analysis
- Some of the key source codes are still those just now, so there is no record here
Redirect view
-
The default redirection view in spring MVC is RedirectView
-
When the view name set in the controller method is prefixed with "redirect:" to create a RedirectView, the view name will not be resolved by the view parser configured in the spring MVC configuration file, but the prefix "redirect:" will be removed, and the rest will be used as the final path to jump through redirection.
For example, "redirect: /", "redirect:/employee"
case
-
In view Writing hyperlinks in HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>View test</title> </head> <body> <h1>SpringMVC view</h1> <a th:href="@{/doRedirect}">test RedirectView</a><br/> </body> </html>
-
Method of writing corresponding controller
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ViewController { /** * Jump to view test page */ @RequestMapping("/doView") public String doView() { return "view"; } /** * Default (no prefix) * ThymeleafView View object */ @RequestMapping("/doThymeleafView") public String doThymeleafView() { return "success"; } /** * Redirect view (prefix: "redirect:") * RedirectView View object */ @RequestMapping("/doRedirect") public String doRedirectView() { /* 1,When redirect is used as the prefix, specific pages cannot be accessed directly (404 will be reported) >Incorrect writing: return "redirect:success"; 2,If you want to access a specific page through redirect, you can forward it to a controller method that jumps to a page (the request path set by the controller method) For example: redirect: / dothymleafview 3,The address shown on the final page here is / dothymleafview, not / doRedirect */ return "redirect:/doThymeleafView"; } }
-
Start Tomcat to see the effect
- The normal effect is that you can normally access the view page and success page. There are no screenshots here
Principle analysis
- Some of the key source codes are those just now, so we won't make records here
Forwarding and redirection (understanding)
The function of forwarding and redirection: realize page Jump in Servlet
forward
-
Concept: the page Jump performed by the server is called "forwarding"
-
characteristic:
- The address bar does not change and displays the address of the previous page
- Request times: only one request (that is, the request sent by the browser to the server)
- Request domain data will not be lost
- Root directory: http://localhost:8080/ Project address /, which contains the access address of the project
-
The native Servlet implements forwarding using request Getrequestdispatcher ("/ address") forward(request, response);
-
Spring MVC uses forwarding and uses redirect: as the prefix before the returned address (the underlying layer will parse and finally get an InternalResourceView view view object)
redirect
- Concept: the page Jump performed by the server is called "redirection"
- characteristic:
- The address bar shows the new address
- Number of requests: twice
- The data in the request domain will be lost because there are two requests
- Root directory: http://localhost:8080/ , there is no access address for the item
Spring MVC view controller
When the controller method is only used to realize page Jump, that is, only the view name needs to be set, the processor method can be represented by the view controller tag.
be careful:
1. If you do not just jump to the page, but perform certain operations, do not use the view controller, because the view controller cannot realize the corresponding operations!
2. Configuring the view controller in the configuration file will invalidate all request mappings in the controller
-
Comment out the request mapping for index
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { /** * Jump to home page */ // @RequestMapping("/") // public String doIndex() { // return "index"; // } }
-
In spring MVC The XML configuration file uses the view controller tag for processing
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- Scan component --> <context:component-scan base-package="com.laoyang.mvc" /> <!-- to configure Thymeleaf view resolver --> <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <!-- priority --> <property name="order" value="1"/> <!-- Character encoding --> <property name="characterEncoding" value="UTF-8"/> <!-- Template --> <property name="templateEngine"> <bean class="org.thymeleaf.spring5.SpringTemplateEngine"> <property name="templateResolver"> <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <!-- View prefix --> <property name="prefix" value="/WEB-INF/templates/"/> <!-- View suffix --> <property name="suffix" value=".html"/> <!-- Template model --> <property name="templateMode" value="HTML5"/> <!-- Page encoding format --> <property name="characterEncoding" value="UTF-8"/> </bean> </property> </bean> </property> </bean> <!-- path: Set the address of the request to be processed. The path is and @RequestMapping The address in the annotation is the same Simple understanding: is to controller The controller method used to jump to the page in is written in the configuration file view-controller: Set the view name corresponding to the request address be careful: 1,If you do not just jump to the page, but perform certain operations, do not write them in the configuration file, because the configuration file cannot realize the corresponding operations! 2,Configure in configuration file view-controller After that, it will lead to controller All request mappings in the controller failed --> <!-- Access method: http://localhost:8080/springmvc/ --> <mvc:view-controller path="/" view-name="index"/> <!-- Access method: http://localhost:8080/springmvc/doView --> <mvc:view-controller path="/doView" view-name="view"/> </beans>
For better understanding, I also configure a jump to view In the view controller of HTML page, remember to comment out the controller method in the corresponding controller! If you don't comment it out, there may be some unnecessary problems.
-
Start Tomcat to test the effect
-
Access method: localhost:8080/springmvc/
-
Access method: localhost:8080/springmvc/doView
-
It can be seen that the path configured in the configuration file can normally access the corresponding page, but there will be a small problem at this time, that is, 404 will be reported after clicking the hyperlink of the page, because the view controller tag will cause the request mapping in all controllers to fail.
-
-
Resolve the annotation driven problem
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- Scan component --> <context:component-scan base-package="com.laoyang.mvc" /> <!-- to configure Thymeleaf view resolver --> <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <!-- priority --> <property name="order" value="1"/> <!-- Character encoding --> <property name="characterEncoding" value="UTF-8"/> <!-- Template --> <property name="templateEngine"> <bean class="org.thymeleaf.spring5.SpringTemplateEngine"> <property name="templateResolver"> <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <!-- View prefix --> <property name="prefix" value="/WEB-INF/templates/"/> <!-- View suffix --> <property name="suffix" value=".html"/> <!-- Template model --> <property name="templateMode" value="HTML5"/> <!-- Page encoding format --> <property name="characterEncoding" value="UTF-8"/> </bean> </property> </bean> </property> </bean> <!-- path: Set the address of the request to be processed. The path is and @RequestMapping The address in the annotation is the same view-controller: Set the view name corresponding to the request address --> <!-- Access method: http://localhost:8080/springmvc/ --> <mvc:view-controller path="/" view-name="index"/> <!-- Access method: http://localhost:8080/springmvc/doView --> <mvc:view-controller path="/doView" view-name="view"/> <!-- Resolve request mapping failure: Enable mvc Annotation driven --> <mvc:annotation-driven /> </beans>
-
Retest
At this point, click the hyperlink to map normally
Spring MVC view resolver (internal resource view resolver)
The view parsers we used above all parse html pages (ThymeleafViewResolver), but if the view uses JSP pages, we need to use the InternalResourceViewResolver view parser
-
Create a new project and put the web XML and pom dependencies are copied into this new project
-
Create and write spring-mvc.net in the resource directory XML configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- Scan component --> <context:component-scan base-package="com.laoyang.mvc" /> <!-- view resolver --> <bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/templates/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
-
Create index. In webapp directory jsp
-
explain:
Tomcat's web The default welcome page (index.html,index.htm,index.jsp) is configured in the XML file; But in tomcat, every subdirectory under webapp directory is considered as a JSP site, so you can only access index JSP welcome page
If index. Is also created in the webapp directory HTML and index JSP, then 404 will be reported when accessing. If there is only index HTML, it will also report 404 after startup, because the default page cannot be accessed
<%-- Created by IntelliJ IDEA. User: Laoyang Date: 2022/1/10 Time: 17:15 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>home page</title> </head> <body> <h1>Hello Tom!</h1> <!-- pageContext.request.contextPath: page The data in the domain object, through which the context path can be obtained > because jsp The context path will not be automatically added to us and then accessed, so we need to add it manually and must add it as a dynamic context path > If a fixed context path is configured, it will be troublesome to maintain once it is modified in the future --> <a href="${pageContext.request.contextPath}/doSuccess">visit success.jsp page</a> </body> </html>
-
-
Create success. In the WEB-INF/templates directory jsp
<%-- Created by IntelliJ IDEA. User: Laoyang Date: 2022/1/10 Time: 17:22 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Main page</title> </head> <body> <h1>Master page effect</h1> </body> </html>
-
Write the corresponding controller method to realize page Jump
package com.laoyang.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * @ClassName JspController * @Description: JSP Jump * @Author Laoyang * @Date 2022/1/10 17:12 */ @Controller public class JspController { @RequestMapping("/doSuccess") public String doSuccess() { // The jsp page returned here will be used by spring MVC The view parser in the XML configuration file is parsed return "success"; } }