preface
Spring MVC is also called Spring web mvc. It is a built-in MVC framework in spring and will be released after spring 3.0. Spring MVC framework solves common problems in WEB Development (parameter receiving, file uploading, form verification, etc.), and is simple to use and seamlessly integrated with spring. Support RESTful style URL requests. The loose coupling pluggable component structure is adopted, which is more scalable and flexible than other MVC frameworks.1, First glimpse of the doorway
Before using spring MVC, we used servlets for web development. However, using servlet development is relatively complex in receiving request parameters, data sharing, page Jump and other operations. Servlet is the standard for web development in java. Since spring MVC encapsulates servlets, it is obvious that * * the bottom layer of spring MVC is servlet, and spring MVC encapsulates servlets at a deep level**2, Small trial ox knife
1. Introduce dependency
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>springmvckkb</groupId> <artifactId>com.dmlll.mvc</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <target>1.8</target> <source>1.8</source> </configuration> </plugin> <!--tomcat plug-in unit--> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/</path> </configuration> </plugin> </plugins> </build> </project>
Spring MVC relies on spring. If there is no version requirement, you don't have to import spring
2. Create Spring and Spring MVC configuration files
2.1 Spring configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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 "> <context:component-scan base-package="com.dmlll.dao,com.dmlll.service"/> </beans>
2.2 spring MVC configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mc="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 "> <context:component-scan base-package="com.dmlll.controller"/> <!--open mvc In annotation driven--> <mvc:annotation-driven/> </beans>
3.web.xml configuration
<?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"> <!--spring Configuration of--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:application.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--SpringMVC Configuration of--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
4. Write Controller
@Controller public class TestController { @RequestMapping("hello.do") public ModelAndView hello(){ String str = "If you want to practice this skill, you must go to the Palace first"; System.out.println(str); ModelAndView mv = new ModelAndView(); mv.addObject("word",str); mv.setViewName("hello"); return mv; } }
5. Write a page
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${word} </body> </html>
6. Start tomcat
Because the plug-in is configured, it can be started directly in maven
3, Rough fur
1. Workflow of spring MVC
- The browser sends a request, and the DispatchServlet receives the request sent by the browser
<!--It depends on you here web.xml Configured in <url-pattern>*.do</url-pattern> All with suffix(.do)Your request goes through the front-end controller <url-pattern>/</url-pattern> All requests go through the front-end controller --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
- After receiving the request, DispatchServlet forwards it to HandlerMapping
- HandlerMapping finds the corresponding processor according to the request, encapsulates it into a processor execution chain (including processor Handler, processor interceptor and HandlerInterceptor) and returns it to DispatchServlet
- DispatchServlet finds the corresponding HandlerAdaptor according to the Handler, and the HandlerAdaptor undergoes a series of operations such as parameter encapsulation / data format conversion.
- The HandlerAdaptor executes the methods in the Controller
- The Controller returns ModelAndView
- HandlerAdaptor returns ModelAndView to DispatchServlet
- DispatchServlet gives ModelAndView to ViewResolve for parsing
- ViewResolve returns the parsed View to the DispatchServlet
- DispatcherServlet calls the view object for rendering to get the response object
- Returns the response object to the browser
The code is as follows (example):
2. Spring MVC components
- Dispatcher servlet: front end controller
The dispatcher servlet is the entry controller for user requests. The dispatcher servlet is the center of the whole process control. It calls other components to process user requests. The dispatcher servlet reduces the coupling between components. - HandlerMapping: processor mapper
HandlerMapping is the controller of dispatch request. It is responsible for finding the Handler according to the user's request. - Handler: processor
The Handler is the Controller, which is written by the programmer according to the requirements - HandlerAdaptor: processor adapter
Be responsible for calling the processor and passing parameters. - Vievresolver: View parser
The ViewResolver is responsible for generating the processing results into the View view. The ViewResolver first resolves the logical View name (relative) into the physical View name (absolute), generates the View object, and finally renders the View to display the processing results to the user.
3. URL pattern parsing in web.xml
<servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
This node can be written in two ways:
- *.xx
Without special requirements, spring MVC front-end controllers often use suffix matching - /
In this way, all requests go through the front-end controller to find the corresponding processor. However, the static file will not write the processor, so it is necessary to configure the release of static resources
<!--Method 1: in SpringMVC.xml Medium configuration--> <mvc:default-servlet-handler/> <!-- After declaring the label, SpringMVC The frame is created in the container DefaultServletHttpRequestHandler Processor object. This object will be applied to all that enter the front-end controller URL Check. If a request is found to be a static resource, the request is forwarded to Web Application server processing (e.g.: Tomcat) General servers have default Servlet. Tomcat In the server, there is one dedicated to handling static resource access Servlet---->DefaultServlet. Bit and tomcat Installation directory/conf/web.xml in -->
<!--Method 2: in SpringMVC.xml Medium configuration--> <!--mapping: Map all files in this folder, location: File location--> <mvc:resources mapping="/image/**" location="/image/"/> <!-- stay Spring3.0 After that, the processor dedicated to processing static resource requests is defined ResourceHttpRequestHandler. And add<mvc:resources/>Tag to solve the problem that static resources cannot be accessed -->
4. Common notes
- @RequestMapping
It defines the mapping rules of the processor for requests, that is, the request path. It can act on classes and methods - @ResponseBody
Convert the returned data structure to JSON format - @PathVariable
Used to get the parameters in the path
http://localhost:8080/user/{id} - @RequestParam
Parameters used to get the request
http://localhost:8080/user?id=1 - @RequestBody
Used on POST requests to accept JSON entity parameters - @ControllerAdvice
Controller enhancer, which adds unified operations or processing to the controller
5. Chinese garbled code
Spring provides a special CharacterEncodingFilter class for Chinese garbled code in request parameters, which is configured in web.xml
<filter> <filter-name>characterEncodingFilter</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> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
You can enter this class to view the corresponding parameters:
If you are using the tomcat plug-in in maven, you should also configure the character set of tomcat
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/</path> <uriEncoding>utf-8</uriEncoding> </configuration> </plugin>
4, Enter the house
1. Processor receives parameters
Write a page params.jsp that passes parameters
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Processing parameters</title> </head> <body> <form action="/params/get1.do"> ID: <input type="text" name="id"><br/> full name:<input type="text" name="name"><br/> Address:<input type="text" name="address"><br/> <button type="submit">Submit</button> </form> </body> </html>
Write the page ok.jsp that requests the end jump
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${id},${name},${address} </body> </html>
Write the entity class Person.java
public class Person { private Integer id; private String name; private String address; //setter/getter/toString }
Write page Jump controller ParamsController.java
@Controller @RequestMapping("params") public class ParamsController { @RequestMapping("view.do") public ModelAndView view(){ System.out.println("get into params page"); return new ModelAndView("params"); } }
1.1 parameters of direct use method are received one by one
Note: the parameter name must be consistent with the name passed from the front end
Add method to ParamsController.java
@RequestMapping("get1.do") public ModelAndView get1(Integer id,String name,String address){ System.out.println(id + "---" + name + "---" + address); ModelAndView mv = new ModelAndView("ok"); mv.addObject("id",id); mv.addObject("name",name); mv.addObject("address",address); return mv; }
function:
1.2 use object to receive multiple parameters
Note: the attribute of the object must be consistent with the parameter name passed from the front end
Add method to ParamsController.java
@RequestMapping("get2.do") public ModelAndView get2(Person person){ System.out.println(person.getId() + "---" + person.getName() + "---" + person.getAddress()); ModelAndView mv = new ModelAndView("ok"); mv.addObject("person",person); return mv; }
Modify the form in params.jsp
<form action="/params/get2.do"> ID: <input type="text" name="id"><br/> full name:<input type="text" name="name"><br/> Address:<input type="text" name="address"><br/> <button type="submit">Submit</button> </form>
Modify the variables of ok.jsp receiving parameters
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${person.id},${person.name},${person.address} </body> </html>
function:
1.3 using native HttpServletRequest to obtain
Add method to ParamsController.java
@RequestMapping("get3.do") public ModelAndView get3(HttpServletRequest request){ String id = request.getParameter("id"); String name = request.getParameter("name"); String address = request.getParameter("address"); System.out.println(id + "---" + name + "---" + address); ModelAndView mv = new ModelAndView("ok"); //Encapsulated as Person Person person = new Person(); person.setId(Integer.valueOf(id)); person.setName(name); person.setAddress(address); mv.addObject("person",person); return mv; }
Modify the form path of params.jsp
<form action="/params/get3.do">
function:
1.4 get date type parameters
Direct reception will report an error
Modify Person.java and add time attribute
private Date date;
Modify params.jsp and add a time selection box
Date:<input type="date" name="date"><br/>
function:
The annotation @ DateTimeFormat(pattern = "yyyy MM DD") needs to be added on the date attribute
Restart:
1.5 get parameters of array type
Modify ParamsController.java
@RequestMapping("get4.do") public ModelAndView get4(String[] names){ ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("names",names); modelAndView.setViewName("ok"); return modelAndView; }
Modify the params.jsp form
<form action="/params/get4.do"> Name 1:<input type="text" name="name"><br/> Name 2:<input type="text" name="name"><br/> Name 3:<input type="text" name="name"><br/> <button type="submit">Submit</button> </form>
Modify ok.jsp
${name[0]},${name[1]},${name[2]}
function:
1.6 get parameters of List type
Collection type cannot receive directly
Modify ParamsController.java
@RequestMapping("get5.do") public ModelAndView get5(List<String> name){ ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("names",names); modelAndView.setViewName("ok"); return modelAndView; }
Modify params.jsp
<form action="/params/get5.do">
Run at this time:
The @ RequestParam() annotation needs to be added to the collection parameters
@RequestMapping("get5.do") public ModelAndView get5(@RequestParam(value = "names") List<String> names){ ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("names",names); modelAndView.setViewName("ok"); return modelAndView; }
Start again and everything is normal.
If you replace list < string > with list < person >
Restart
(at this time, the name attribute corresponds to the name attribute in Person. If it is normal, only Person.name has a value.)
Prompt: the name in the List does not exist, so you cannot directly use the List to accept the object collection and encapsulate the collection into an object ListVO
public class ListVO<T> { private List<T> list; public List<T> getList() { return list; } public void setList(List<T> list) { this.list = list; } }
Modify ParamsController.java
@RequestMapping("get6.do") public ModelAndView get6(ListVO vo){ ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("names",vo.getNameList()); modelAndView.setViewName("ok"); return modelAndView; }
Modify params.jsp
<form action="/params/get6.do"> Name 1:<input type="text" name="nameList[0].name"><br/> Name 2:<input type="text" name="nameList[1].name"><br/> Name 3:<input type="text" name="nameList[2].name"><br/> <button type="submit">Submit</button> </form>
Start program:
Note: the parameter name of the front-end parameter list must be consistent with the properties of the ListVO object
1.7 use URL address to transfer parameters
Modify ParamController.java
@RequestMapping("get7/{id}.do") public ModelAndView get7(@PathVariable("id") Integer id){ ModelAndView modelAndView = new ModelAndView("ok"); modelAndView.addObject("id",id); return modelAndView; }
Modify ok.jsp
${id}
Enter directly in the address field
http://localhost:8080/params/get7/1.do
Because *. do configured in the configuration file can only be intercepted if. do is the suffix, this method @ RequestMapping("get7/{id}.do") is adopted
2. Processor method return value
There are four types of processor return values:
- ModelAndView
- String
- Returns a custom type object
- No return value void
ModelAndView has been used in the previous section.
2.2 return String
@RequestMapping("get8.do") public String get8(){ return "ok"; }
If parameters are carried, HttpServletRequest can be carried, and parameters are passed through native methods
2.3 return object type
2.3.1 return basic type
@RequestMapping("get9.do") @ResponseBody public String get9(){ return "xiaoming"; }
Introducing JSON dependencies
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.12.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.4</version> </dependency>
@RequestMapping("get9.do") @ResponseBody public Person get9(){ Person p = new Person(); p.setAddress("Dongguan"); p.setName("Super Marie"); p.setId(1); return p; }
2.4 return void
Use native HttpServletRequest and HttpServletResponse
3. Forwarding and redirection
3.1 forwarding
@RequestMapping("get11.do") public String get11(){ return "forward:/ok.jsp"; } @RequestMapping("get12.do") public ModelAndView get12(){ return new ModelAndView("forward:/ok.jsp"); }
3.2 redirection
@RequestMapping("get13.do") public String get13(){ return "redirect:/ok.jsp"; } @RequestMapping("get14.do") public ModelAndView get14(){ return new ModelAndView("redirect:/ok.jsp"); }
General redirection does not pass parameters. Redirection in spring MVC can pass parameters to? Splicing in the form of key=value
4. Exception handling
Use the @ ExceptionHandler annotation to specify the method for exception handling.
The return values can be ModelAndView, String and void
The parameters can be Exception and its subclasses, HttpServletRequest, HttpServletResponse, etc. the system will assign values to them automatically
4.1 custom exception class
public class MyException extends Exception{ public MyException() { } public MyException(String message) { super(message); } }
ParamsController.java
@RequestMapping("get16.do") public ModelAndView get16() throws MyException { throw new MyException("He deliberately reported an error");//Throw exception } @ExceptionHandler(value= MyException.class) public ModelAndView get15(Exception ex){ ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("ok"); modelAndView.addObject("msg",ex.getMessage()); return modelAndView; }
Modify ok.jsp
${msg}
function
You can also manage exception handling methods uniformly through the @ ControllerAdvice annotation
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = ArithmeticException.class) public ModelAndView exception01(ArithmeticException ex){ ModelAndView ok = new ModelAndView("ok"); ok.addObject("msg",ex.getMessage()); return ok; } @ExceptionHandler(value = Exception.class) public ModelAndView exception02(Exception ex){ ModelAndView ok = new ModelAndView("ok"); ok.addObject("msg",ex.getMessage()); return ok; } }
5. Interceptor
Main function: intercept the user's request and carry out corresponding preprocessing and post-processing
How to implement: implement the HandlerInterceptor interface and rewrite its methods
public class MyInterceptor implements HandlerInterceptor { //Execute before the processor method is executed, and the return value is true to release the intercepted method, //Put the afterCompletion method into a special method stack and wait //If the return value is false, the intercepted method will not be executed @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return false; } //After the execution of the processor method and before returning the result, the method can change the processing result and jump page of the processor method @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } //When the preHandle method returns true, the method is executed after the processor method returns the result @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
Configuring Interceptors
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean id="myInterceptor" class="com.dmlll.controller.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>
Writing interceptor code
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Pretreatment-----------"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Processing-----------"); System.out.println("Replace processor storage msg"); request.setAttribute("msg","You were replaced"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("Post processing-----------"); } }
Write processor
@RequestMapping("get17.do") public String get17(HttpServletRequest request) { System.out.println("Processor method execution storage"); request.setAttribute("msg","I am 1"); return "ok"; }
6. File upload and download
6.1. File upload
Spring MVC provides direct support for file upload through MultipartResolver
There is an implementation class CommonsMultipartResolver in Spring
MultipartResolver is not installed by default in the spring MVC context. It needs to be configured in the configuration file first
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
Introduce dependency
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency>
Edit page for file upload
<form action="/params/get18.do/id" method="post" enctype="multipart/form-data"> File:<input type="file" name="file"><br/> <button type="submit">Submit</button> </form>
Write processor
@RequestMapping("get18.do") public String get18(@RequestParam("file") MultipartFile file,HttpServletRequest request) throws IOException { String originalFilename = file.getOriginalFilename();//original filename //Get suffix String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")); //Composition random name String filename = UUID.randomUUID().toString().replace("-","")+suffix; request.setAttribute("filename",filename); //Storage path String path = request.getServletContext().getRealPath("/upload") + "/"; file.transferTo(new File(path,filename)); System.out.println("Upload succeeded"); return "ok"; }
New upload folder
Modify ok.jsp
<img src="upload/${requestScope.filename}">
function:
6.2 download
@RequestMapping("get19.do") public ResponseEntity get19(HttpServletRequest request) throws IOException { //Specify path String path = request.getServletContext().getRealPath("/upload")+"/566e00bb19a8430e85beeafd4c27697a.jpg"; //Create header information for response HttpHeaders headers = new HttpHeaders(); //Open as stream headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); //Respond to users in the form of attachments headers.setContentDispositionFormData("attachment", URLEncoder.encode("566e00bb19a8430e85beeafd4c27697a.jpg","utf-8")); File file = new File(path); ResponseEntity responseEntity = new ResponseEntity(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED); return responseEntity; }
<img src="/upload/566e00bb19a8430e85beeafd4c27697a.jpg"> <a href="/params/get19.do">download</a>