Spring MVC User Guide
1, How spring MVC works
1.1 principle and process of spring MVC
Picture address: 22. Web MVC framework
- The user initiates a request and the request is intercepted into the dispatcher servlet (FrontController), which is the core of Spring,
- Handle the URL of the request with HandlerMapping and find the processor Handler that handles the corresponding request
- HandlerMapping encapsulates the found controller information and processed request information into handlerexception and returns it to dispatcher servlet
- The dispatcher servlet passes the processed Handler information to the HandlerAdapter
- HandlerAdapter finds the corresponding Controller
- After processing the request, the Controller encapsulates the data and the view information to be returned into ModelAndView and returns it to the HandlerAdapter
- HandlerAdapter returns ModelAndView to DispatcherServlet
- The dispatcher servlet passes ModelAndView to the view parser ViewResolver
- The view parser parses the view name transmitted from the view information and returns the specific view address to the dispatcher servlet
- The dispatcher servlet finds the view according to the view address and passes the model data to the view display
- After rendering, the view is returned to the dispatcher servlet
- The dispatcher servlet returns the rendered view to the user as a response
1.2 spring MVC interface
The process contains several interfaces or classes:
- DispatcherServlet class: all requests go through it. Before DispatcherServlet sends the request to the Controller, you need to locate the specific Controller with the help of HandlerMapping
- HandlerMapping interface: it is responsible for mapping the request to the Controller
- Controller interface: handles user requests, which are consistent with Java EE servlets. After handling the requests, the controller will return ModelAndView objects to the DispatcherServlet front-end controller
- ViewResolver interface: a View parser, which finds the View object in the Web application and returns the Model rendering to the user
- ModelAndView class: stores the data Model and View returned by the Controller after processing
2, Simple use of spring MVC (without annotations)
2.1 create a maven project
pom.xml file
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>top.lan-mao.computer-world.study-2022</groupId> <artifactId>SpringMVC-Demo02</artifactId> <version>1.0-SNAPSHOT</version> <name>SpringMVC-Demo02</name> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <junit.version>5.8.2</junit.version> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.14</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <compilerArguments> <extdirs>src/main/webapp/WEB-INF/lib</extdirs><!-- If there is no such specification, you need to manually maven of jar Packages, mapping to lib below --> </compilerArguments> <!-- Skip test case ,No compilation--> <skip>true</skip> </configuration> </plugin> </plugins> </build> </project>
2.2 configuring web xml
<?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"> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!--Startup level 1: refers to starting the service when it is started servlet--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
It should be noted that the path matched by the dispatcher Servlet is /, not / *, because / * is a path match and will intercept * jsp request; And / is the default match in the Servlet, with the lowest priority, * jsp will be intercepted by jsp parser in Tomcat instead of spring MVC.
The default Spring configuration file location for Spring MVC is web - inf / springmvc - Servlet XML, Spring MVC is web The name of the Servlet configured in XML. If not here, configuration is required. It can be configured in two places: 1 The init param tag is used in the dispatcher Servlet; 2. web. Configure the contextConfigLocation item in the context param tag in XML
1 of the load on startup item configured in the dispatcher Servlet means that the Servlet is started when the web project starts
2.3 configuring spring MVC servlet xml
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <!--Processor mapper--> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!--Processor adapter--> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!--view resolver --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!--prefix--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--suffix--> <property name="suffix" value="*.jsp"/> </bean> <bean name="/hello" class="top.lan_mao.computer_world.study_2022.springmvc_demo02.HelloServlet"/> </beans>
- BeanNameUrlHandlerMapping: it is a processor mapper that matches the Controller with the request path according to the name and id attributes of the Bean
- SimpleControllerHandlerAdapter: adapter, which will be executed by the matched processor
- InternalResourceViewResolver: View resolver, which parses the path of the view, adds the prefix, etc
- The processor, mapper and view parser are implemented in spring 4 After 0, it is not necessary to configure.
2.4 create a Controller class
public class HelloController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("msg", "HELLO"); modelAndView.setViewName("hello"); //WEB-INF/jsp/hello.jsp return modelAndView; } }
3, Using annotations
Spring MVC provides annotation based configuration after version 2.5, so the actual use is basically configured with annotations.
If you do not use annotations and use the interface to create the Controller class, there can only be one request processing method in a class.
3.1 enable annotations in projects
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <!--Annotation scanning of packages--> <context:component-scan base-package="top.lan_mao.computer_world.study_2022.springmvc_demo03.controller"/> <!--Filter requests for static files without DispatcherServlet,You can also use<mvc:resource location="/html"/>Filter Tags--> <mvc:default-servlet-handler/> <!--Enable SpringMVC The default mapper and adapter when using annotations--> <mvc:annotation-driven/> <!--Configure view parser--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value="*.jsp"/> </bean> </beans>
3.2 create Controller based on annotation
@Controller @RequestMapping("/hello") public class HelloController { @RequestMapping("/h1") public String hello(Model model) { model.addAttribute("msg", "Hello"); return "hello"; } }
- @The Controller annotation indicates that the class is contained by the Spring container
- @RequestMapping: can be used for classes and methods to represent the path of the request.
- You can determine the type of request through the method attribute. Or use @ GetMapping, @ PostMapping, @ PutMapping, @ PutMapping, @ PutMapping, @ PatchMapping and other replacement and explicit request methods. But only one can take effect.
- @RequestMapping(value = "/h1",method = {RequestMethod.GET,RequestMethod.POST})
- The path acting on the class is the parent path of the method
- You can determine the type of request through the method attribute. Or use @ GetMapping, @ PostMapping, @ PutMapping, @ PutMapping, @ PutMapping, @ PatchMapping and other replacement and explicit request methods. But only one can take effect.
4, Processing method of @ Controller
4.1 parameter types allowed by @ controller
- ServletRequest /ServletResponse /HttpServletRequest /HttpServletResponse
- HttpSession
- InputStream / Reader / OutputStream / Writer
- Local/ TimeZone/ ZoneId
- java.security.Principal
- @PathVariable (RestFul style), @ MatrixVariable, @ RequestParam (receive request parameter), @ RequestHeader, @ RequestBody, @ RequestPart, @ SessionAttribute, @ RequestAttribute annotation
- HttpMethod
- Map/ Model/ ModelMap
- RedirectAttributes (for redirection, pass parameters in Session and remove them after receiving)
- Errors/ BindingResult
- SessionStatus/ UriComponentsBuilder
- HttpEntity<?>
4.2 allowed return value types
- ModelAndView
- Model
- View
- String (if the @ ResponseBody annotation is added to the method, the string value will be returned directly as a response)
- void
- HttpEntity<?> Or responseentity <? >
- Callable<?>/ DeferredResult<?>
4.3 method of receiving request parameters
4.3.1 the request parameter name is the same as the processing method parameter name
It is directly received through the formal parameters of the processing method. It is recommended to add @ RequestParam annotation to determine the parameter name even if the name is the same, so as to clarify some error causes.
4.3.2 the request parameter name is different from the processing method parameter name
Add @ RequestParam("name") annotation to bind request parameter name and formal parameter
4.3.3 receiving parameters through Bean entity class
The passed parameter name is consistent with the property name in the Bean. If there is any inconsistency, the property value is null
4.3.4 receive via @ PathVariable
For the URL of RestFul style request, the @ PathVariable annotation needs to be added before the formal parameter
4.3.5 receive parameters through @ ModelAttribute
It is the same as receiving through Bean, but the difference is that the received parameters are added to the Model. See the following for specific usage: Introduction to integrated development of Java EE framework to actual combat: Spring+Spring MVC+MyBatis (wechat version) - Chen Heng - wechat reading
5, RestFul request style
Spring MVC supports RESTFul style request paths.
@RequestMapping(value="/h2/{a}/{b}", method=RequestMethod.GET) public String hello2(@PathVariable Integer a, @PathVariable Integer b, Model model) { model.addAttribute("msg", a + b); return "hello"; }
- You can include parameters in the path through {}. The corresponding parameters with the same name need to be annotated with @ PathVariable.
- The RestFul style request path and the traditional style request path are not the same request. Two methods are needed to receive the request.
- It is best to add GET request mode qualification
6, Request forwarding and redirection
In the spring MVC framework, data can be transferred to the view by return ing a path. By default, data is transferred to the view by request forwarding. You can also determine the method through the displayed ID, that is, add "forward:" or "redirect:" before the path.
Note:
- The added path no longer passes through the view parser, that is, the pre suffix of the configuration does not work
- Both the forwarding and redirection paths jump under this web application directory
- Project path: / demo3; Request address: / hello/h1,/hello/h2
- "forward:hello": /demo3/hello/hello
- "forward:/hello": /demo3/hello
- "redirect:hello": /demo3/hello/hello
- "redirect:/hello": /demo3/hello
- Can I add on the requested path? Spring MVC will automatically splice the parameters to be passed
- There are two ways to redirect parameters,
- Use the URL address of GET to pass parameters,
- Use the class RedirectAttributes to pass parameters through the Session. RedirectAttributes adds parameters to the Session and deletes the parameters after receiving.
- The method used is redirectattributes addFlashAttributie(“prama”,value)
- If it is passed to a Controller, you need to receive parameters in @ RequestPrama(value = "prama") String prama mode
- Method redirectattributes Addattributee ("prama", value) is still passed in the GET mode
7, Garbled code problem
7.1 JSP and Servlet
Spring MVC comes with a garbled filter. On the web XML.
Note that the filter path should preferably be set to / *, otherwise it may not work. And the value of forceEncoding needs to be initialized to true, otherwise it will not work.
<filter> <filter-name>encoding</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-name> <url-pattern>/*</url-pattern> </filter-mapping>
! [[why does characterencoding filter not work on responses]]
However, it will not work for the response that directly returns the string after adding the @ ResponseBody annotation, because Spring MVC is output through StringHttpMessageConverter, and it will add the header information: content type: text / plain; Charset = iso-8859-1, which overrides the character set setting made by the filter. You can set the following in the Spring configuration file:
<mvc:annotation-driven> <!-- Message converter --> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="defaultCharset" value="UTF-8"/> </bean> </mvc:message-converters> </mvc:annotation-driven>
Or set the character set @ requestmapping (value = "/ U3", products = "text / plain; charset = UTF-8") on the processing method. Note that if the Accept field in the request header sent by the request does not have the corresponding protocol in produces, a 406 error will appear.
8, Spring MVC support for JSON
8.1 Jackson
Spring MVC supports the Jackson framework to parse JSON strings by default. Just add Jackson's package to use. You can return an object directly, and spring MVC will automatically convert it into a JSON string.
The coding format must be set before use, otherwise the Chinese code is garbled.
<mvc:annotation-driven> <!-- Message converter --> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="defaultCharset" value="UTF-8"/> </bean> </mvc:message-converters> </mvc:annotation-driven>
The @ ResponseBody annotation must be added to the corresponding processing method or class to directly return the string. Or change the @ Controller annotation of the class to the @ RestController annotation (this is the combined annotation of @ Controller and @ ResponseBody).
@Controller public class UserController { @RequestMapping("/u1") @ResponseBody public String getUser1() { User user = new User("computer", 12, "male"); return user.toString(); } @RequestMapping("/u2") @ResponseBody public String getUser2() throws JsonProcessingException { User user = new User("computer", 12, "male"); return new ObjectMapper().writeValueAsString(user); } /** * To solve the problem of garbled code, the products attribute of RequestMapping is added, but the Accept field of the request must contain the corresponding protocol type */ @RequestMapping(value="/u3", produces = "application/json;charset=UTF-8") @ResponseBody public String getUser3() throws JsonProcessingException { User user = new User("computer", 12, "male"); return new ObjectMapper().writeValueAsString(user); } @RequestMapping("/u4") @ResponseBody public User getUser4(HttpServletRequest request, HttpServletResponse response) { return new User("computer", 12, "male"); } }