Introduction to spring MVC framework
- Spring mvc is a web framework based on mvc.
- Spring MVC has a controller, which is similar to Struts. It is used to receive external requests, parse parameters and pass them to the service layer.
- MVC is short for Model, View and Controller.
- The main function of MVC is to reduce the two-way coupling between view and business logic.
Analysis of spring MVC Architecture Principle
- Initiate a request to the central scheduler DispatcherServlet.
- After the central scheduler receives the request, it calls the HandlerMapping mapper to find Handler.
- The HandlerMapping mapper searches the specific processor Handler according to the xml configuration and annotation, generates the processor object and connector, and returns the Handler to the central scheduler.
- The central scheduler calls the HandlerAdapter configurator to execute the Handler.
- After adaptation, the HandlerAdapter adapter calls a specific processor (Controller, also known as Controller) for business logic operation.
- The Handler returns ModelAndView to the adapter after execution.
- The HandlerAdapter returns the Handler execution result ModelAndView to the central scheduler (ModelAndView is an underlying object of the spring MVC framework, including Model and view).
- The central scheduler passes the ModelAndView to the ViewResolver view parser for view parsing, and parses it into a real view (jsp) according to the logical view name.
- ViewResolver the View parser returns the View to the central scheduler.
- The central scheduler performs view rendering, which fills the request field with model data (in the ModelAndView object).
- The front-end controller responds to the result to the user.
- Front end controller DispatcherServlet (no programmer development required)
Function: receive request and response result, equivalent to repeater and CPU. The dispatcher servlet reduces the coupling between other components. - Processor mapper HandlerMapping (no programmer development required)
Function: find the Handler according to the requested url. - Processor adapter HandlerAdapter
Function: execute Handler according to specific rules (rules required by HandlerAdapter). - Processor Handler (programmer development required)
Note: when writing a Handler, follow the requirements of the HandlerAdapter so that the adapter can execute the Handler correctly. - View resolver (no programmer development required)
Function: analyze the view and convert it into a real view according to the logical view name - View (requires programmers to develop jsp) view is an interface, and the implementation class supports different view types (jsp, freemaker, pdf...)
Spring MVC configures the dispatcher servlet central scheduler
-
In POM Add servlet API and spring MVC dependency to XML.
<!-- servlet rely on --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- springmvc rely on --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency>
-
On the web Register the DispatcherServlet, the core object of the spring MVC framework, in the spring configuration file, and set the spring configuration file with < init param >. (note that the web app version here is 4.0)
<?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> <!-- custom springmvc Read configuration file location --> <init-param> <!-- springmvc Profile location properties for --> <param-name>contextConfigLocation</param-name> <!-- Specifies the path to the customization file --> <param-value>classpath:applicationContext.xml</param-value> </init-param> <!-- Configuration in Tomcat After startup, create Servlet object --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
-
Create the spring configuration file ApplicationContext. In the resources file xml. Set up the view parser to handle unpublished jsp files.
<context:component-scan base-package="com.springmvc.controller" /> <!-- View parser, set the path of view file --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- File path prefix --> <property name="prefix" value="/WEB-INF/view/"/> <!-- file extension --> <property name="suffix" value=".jsp"/> </bean>
@Controller annotation
1) Create a MyController class and use the @ Controller annotation to identify this class as a Controller object.
@Controller public class MyController { @RequestMapping("/doSome.do") public ModelAndView doSome() { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("msg","smg data"); modelAndView.setViewName("show"); return modelAndView; } }
@RequestMapping annotation
-
Defining annotations on a class is called a parent interface.
@RequestMapping("/test") public class MyController { }
-
An annotation defined on a method is called a child interface.
@RequestMapping(value = "/doSome.do") public ModelAndView doSome() { }
Interface access mode: http://xxxx.xxxx/test/doSome.do
-
The request method is defined in the annotation. The method attribute represents the request method, and its value is the enumeration value of the RequestMethod class.
@RequestMapping(value = "/doSome.do",method = RequestMethod.GET) public class MyController { }
Controller method request parameter acquisition
-
The method represented by the @ RequestMapping annotation has three parameters: request, response and session. These parameters are automatically assigned by the system when the system is called.
@RequestMapping(value = "/doSome.do",method = RequestMethod.GET) public ModelAndView doSome(HttpServletRequest res, HttpServletResponse resp,HttpSession seion) { }
Parameter by parameter reception
The parameters submitted by the receiving user remain the same as the formal parameter name of the controller method.
@RequestMapping(value = "/login.do",method = RequestMethod.POST) public ModelAndView otherSome(String username,String password) { }
Characterencoding filter to solve Chinese garbled code
-
On the web Register a filter in the XML configuration file to filter all interfaces and solve Chinese garbled code.
<filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!-- Set character encoding --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <!-- Force request object(HttpServletRequest)use encoding The default value is false --> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <!-- Force response object(HttpServletResponse)use encoding The default value is false --> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Controller method return value
String return value (jump page)
Directly return to jump to the name of the page, and the frame will be spliced with the view parser.
For data return, you can add an HttpServletRequest object to the formal parameter and set the object field to receive it on the page.
@RequestMapping(value = "/returnString-view.do",method = RequestMethod.POST) public String doReturnStringView(HttpServletRequest req,String username, String password) { req.setAttribute("username",username); req.setAttribute("password",password); return "show"; }
ModelAndView return value (domain object)
-
@RequestMapping annotation: it can be set on a method or in a class.
-
@RequestMapping annotation: request mapping is used to bind the request address to the method, and specify a method for processing a request.
-
@RequestMapping annotation: the modified method is called processor method or controller method, which can process requests, similar to doGet and doPost in servlet.
-
ModelAndView object:
- addObject(String attributeName, @Nullable Object attributeValue): add data. The framework puts the data into the request scope at the end of the request.
- setViewName(@Nullable String viewName): Specifies the view, and the framework executes a request for the view getRequestDispatcher("/show.jsp"). Forward (req, resp) operation.
- Parameter: the framework will use the view parser to splice the path: prefix + file name + suffix.
@RequestMapping(value = "/returnObject-view.do",method = RequestMethod.POST) public ModelAndView doReturnObjectView(String username, String password) { ModelAndView modelAndView = new ModelAndView(); Student student = new Student(); student.setUsername(username); student.setPassword(password); modelAndView.addObject(student); modelAndView.setViewName("show"); return modelAndView; }
void return value (Ajax response)
When dealing with Ajax, you can use void to return the value.
Ajax requests the server to put back data that is independent of the view.
Use HttpServletResponse to output data in response to the Ajax request. The data format accepted by the Ajax request is JSON. You need to use Jackson dependency to convert the object into JOSN string, and Ajax will parse the JOSN string into JSON.
@RequestMapping(value = "/returnVoid-ajax.do") public void doReturnAjax(HttpServletResponse resp, String username, String password) throws IOException { Student student = new Student(); student.setUsername(username); student.setPassword(password); //Object to json result String json = null; if (student != null) { ObjectMapper objectMapper = new ObjectMapper(); json = objectMapper.writeValueAsString(student); System.out.println(json); } //Responding to ajax requests resp.setContentType("application/json; charset=utf-8"); resp.getWriter().write(json); }
$(function(){ $("#btn").click(function() { $.post("user/returnVoid-ajax.do",{username:"tuoyingtao",password:"123456"}, function fun(response) { alert(JSON.stringify(response)) },"json") }) })
Object return value (annotation Ajax response)
The springmvc controller method returns Object, converts JSON and outputs it to the browser. The response principle is as follows:
1) < MVC: annotation driven > annotation driven: complete the conversion of Java objects to JOSN, xml, text, binary and other data formats.
2) < MVC: annotation driven > after being added to the spring MVC configuration, the implementation class of HttpMessageConverter interface will be automatically created, including MappingJackson2HttpMessageConverter. (use ObjectMapper in Jackson tool library internally to convert Java objects into JSON strings)
3) The HttpMessageConverter interface has two methods:
- canWrite(Class<?> clazz, @Nullable MediaType mediaType);: Check whether the return value of the controller method can match the data format converted to mediatype.
- Write (T, @ nullable mediatype, contenttype, httpoutputmessage, outputmessage): put the controller method back to the object, use the ObjectMapper in Jackson and convert it to JSON format.
4) Call @ ResponseBody, output the data results to the browser, and ajax processes the response.
- After converting the returned object of the processor into JSON, it is output to the browser through HttpServletResponse.
Step 1: introduce Jackson dependency:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency>
Step 2: register the annotation driver in the spring configuration file: (Note: the package path is under mvc)
<mvc:annotation-driven/>
Step 3: use the @ ResponseBody annotation to respond the data to the Ajax request:
//Return object @ResponseBody @RequestMapping(value = "/returnStudentJson.do",method = RequestMethod.POST) public Student doReturnStudentJson(String username, String password) { Student student = new Student(); student.setUsername("Thomas·Crist"); student.setPassword("123456"); return student; } //Return List array @ResponseBody @RequestMapping(value = "/returnStudentList.do",method = RequestMethod.POST) public List<Student> doReturnStudentList(String username, String password) { List<Student> list = new ArrayList<Student>(); Student student = new Student(); student.setUsername("Thomas·Crist"); student.setPassword("123456"); Student student1 = new Student(); student1.setUsername("Mary·Molia"); student1.setPassword("123456"); list.add(student); list.add(student1); return list; }
Annotation Ajax response text
1) The controller method returns String data, not a view.
2) If the @ ResponseBody annotation is added, it means that the returned data is text data, otherwise it is view.
3) text/plain is used by default when text data is returned; charset=ISO-8859-1 is used as ContentType, resulting in Chinese garbled code.
Solution: add the produces attribute in @ RequestMapping to specify the ContentType type.
@ResponseBody @RequestMapping(value = "/returnStringData.do",produces = "text/plain;charset=utf-8") public String doStringData(String username,String password) { return "jack·Roberta"; }
Central scheduler < URL pattern / >
-
In the absence of special requirements, the < URL pattern / > of the DispatcherServlet, the central scheduler of spring mvc, often uses suffix matching, such as * do or * action , *. mvc et al.
-
You can also use / instead. When we initiate a static resource request, dispatcherservert will use the request as the most common Controller. The central scheduler calls the Controller mapper to find the corresponding Controller for it. In this case, all static resource requests will report an Error 404.
-
Generally, the static resources returned by the server are processed by Tomcat itself.
-
Tomcat's web There is a servlet named default in the XML configuration file. When Tomcat runs, a DefaultServlet object will be created to process the request for mapping static resources to.
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
How to access static resources
1) The first: add the < MVC: default servlet handler > tag in the spring MVC configuration file: the framework creates a controller object and forwards the received request to Tomcat.
<mvc:default-servlet-handler/>
2) The second is to add the < MVC: Resources > tag to the spring MVC configuration file: the framework creates a ResourceHttpRequestHandler controller object to handle the access of static resources without relying on the Tomcat server.
- Location attribute: the directory location of the static resource in your project.
- mapping attribute: the URL address to access the static resource, using the wildcard * *.
<mvc:resources location="/static/" mapping="/static/**"/>
exception handling
Spring MVC framework adopts unified and global exception handling. All exception handling in the controller is concentrated in one place, and the business logic and exception handling code are separated by aop idea. Also known as decoupling.
Use two annotations:
ControllerAdvice: controller enhancement. The framework must know the package name of this annotation. It is required to declare the package name of the global exception handling class where @ ControllerAdvice is located in the component scanner in the spring MVC configuration file.
ExceptionHandler: indicates the type of Exception. When this type of Exception occurs, it will be handled by the current method. The method of handling exceptions is the same as the definition of the Controller method, which can have multiple parameters. There can be return values of ModelAndView, String and void object types. The formal parameter: Exception represents the Exception object thrown in the Controller. The sent Exception information can be obtained through the formal parameter.
1) Custom Exception class myuserexception Java, inheriting the Exception class.
public class MyUserException extends Exception{ public MyUserException() { super(); } public MyUserException(String message) { super(message); } }
2) Create a subclass nameexception. Of MyUserException java,PasswordException.java.
public class UsernameException extends MyUserException{ public UsernameException() { super(); } public UsernameException(String message) { super(message); } } public class PasswordException extends MyUserException { public PasswordException() { super(); } public PasswordException(String message) { super(message); } }
3) In the controller method, catch NameException and PasswordException exceptions, and throw the parent class exception MyUserException.
@Controller public class MyController { @ResponseBody @RequestMapping(value = "/errorData",method = RequestMethod.POST) public ModelAndView doErrorData(String username,String password) throws MyUserException { System.out.println(username + password); ModelAndView mv = new ModelAndView(); //Throw an exception with more request parameters if (!"Thomas·Crist".equals(username)) { throw new UsernameException("Wrong name!!!"); } if (!"123456".equals(password)) { throw new PasswordException("Wrong password!!!"); } mv.addObject("username",username); mv.addObject("password",password); mv.setViewName("show"); return mv; } }
4) Create the GlobalExceptionHandler class as the global exception handling class.
@ControllerAdvice public class GlobalExceptionHandler { //Define exception handling methods @ExceptionHandler(value = UsernameException.class) public ModelAndView doUsernameException(Exception e) { //Handling account exceptions ModelAndView mv = new ModelAndView(); mv.addObject("message","Name must be Thomas·Crist!!!"); mv.addObject("error",e); mv.setViewName("uesrnameError"); return mv; } @ExceptionHandler(value = PasswordException.class) public ModelAndView doPasswordException(Exception e) { //Handling account exceptions ModelAndView mv = new ModelAndView(); mv.addObject("message","Password must be 123456!!!"); mv.addObject("error",e); mv.setViewName("passwordError"); return mv; } //Handle unknown exception @ExceptionHandler public ModelAndView doOtherException(Exception e) { ModelAndView mv= new ModelAndView(); mv.addObject("message","Wrong user or password!"); mv.addObject("error",e); mv.setViewName("defaultError"); return mv; } }
5) The spring MVC configuration file scans for exception handlers and registers drivers.
<context:component-scan base-package="com.springmvc.handler"/> <!-- Add annotation driven --> <mvc:annotation-driven/>
Interceptor
What is an interceptor
1) Interceptor is a kind of spring MVC, which needs to implement the HandlerInterceptor interface.
2) Interceptors are similar to filters and deal with different application scenarios. The filter is used to filter request parameters, set character set codes, etc., while the interceptor is used to intercept and judge user requests.
3) The interceptor is global and can intercept multiple controllers. A project can have multiple interceptors. Commonly used in: user login processing, permission checking, logging, etc.
Interceptor execution
Define an interceptor class to implement the HandlerInterceptor interface, and override the following three methods: preHandle(), postHandle(), and afterCompletion().
1) preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler): it is intercepted before the request is processed, that is, before the method in the Controller class. If the return value is true, proceed to the next step. If it is false, terminate. In this method, you can obtain the user request information and verify whether the request meets the requirements.
2) preHandle() returns true to execute the methods in the Controller class.
3) postHandle(HttpServletRequest req, HttpServletResponse resp, Object handler, ModelAndView mv): after the controller method is executed, the interceptor can obtain the return value of the controller method ModelAndView, modify the data and view in ModelAndView, and affect the final execution result. It mainly makes secondary modifications to the original execution result.
4) After completion (HttpServletRequest req, httpservletresponse resp, object handler, exception Ex): the interceptor is executed after the request is processed. It is specified in the framework that when you forward the view after the view processing is completed, the request processing is considered completed. Generally, resource recovery is done. Some objects are created during the request process, You can delete it here and recycle the occupied memory..
Use of interceptors
-
The definition class implements the HandlerInterceptor interface.
public class MyInterceptor implements HandlerInterceptor { /** * @param request * @param response * @param handler Intercepted controller object * @return Boolean * @throws Exception */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Interceptor MyInterceptor of preHandle method"); return true; } /** * @param request * @param response * @param handler Intercepted controller object * @param modelAndView Return value of processor method * @throws Exception */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Interceptor MyInterceptor of postHandle method"); } /** * @param request * @param response * @param handler Intercepted controller object * @param ex An exception occurred in the program * @throws Exception */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("Interceptor MyInterceptor of afterCompletion method"); } }
-
Declare interceptors in the spring MVC configuration file. In the framework, multiple interceptors are stored in the ArrayList in order.
<mvc:interceptors> <!-- Declare first interceptor --> <mvc:interceptor> <!-- Specify the request for the interceptor url Address interception/**All interfaces --> <mvc:mapping path="/**"/> <!-- Declare interceptor object --> <bean class="com.springmvc.handler.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>
Execution sequence
Execution of multiple interceptors
1) MyInterceptor interceptor class I
public class MyInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Interceptor MyInterceptor of preHandle method"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Interceptor MyInterceptor of postHandle method"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("Interceptor MyInterceptor of afterCompletion method"); } }
2) MyInterceptor2 interceptor class II
public class MyInterceptor2 implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Interceptor MyInterceptor of preHandle Method 22222222"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Interceptor MyInterceptor of postHandle Method 2222"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("Interceptor MyInterceptor of afterCompletion Method 2222222"); } }
3) Spring MVC configuration file
<mvc:interceptors> <!-- Declare first interceptor --> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.springmvc.handler.MyInterceptor"/> </mvc:interceptor> <!-- Declare the second interceptor --> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.springmvc.handler.MyInterceptor2"/> </mvc:interceptor> </mvc:interceptors>
Case 1: when the return of preHandle() in MyInterceptor and MyInterceptor 2 interceptors is true, the execution result is returned.
Case 2: when the preHandle() in the MyInterceptor2 interceptor returns false, the execution result is returned.
Case 3: when the preHandle() in the MyInterceptor interceptor returns false, the result is executed.
The difference between interceptor and filter
- Filters are objects in servlet s.
Interceptors are objects in the framework. - A filter is an object that implements the filter interface.
Interceptors implement the Handlerinterceptor interface. - Filter is used to set the parameters of request and response. It is used to filter data.
Interceptors are used to verify requests and can truncate requests. - The filter is executed before the interceptor.
Interceptors are objects in the spring MVC container. - A filter is a point in execution time.
The interceptor has three execution time points. - Filters can handle jsp, js, html, and so on.
The interceptor intercepts the Controller object. If your request cannot be accepted by the dispatcher servlet, the interceptor will not be executed. - The filter filters the servlet request response.
Interceptors intercept the execution of common methods.