Spring MVC core technology
1, Request redirection and forwarding
When the processor finishes processing the request and jumps to other resources, there are two ways: request forwarding and redirection. According to the type of resources to jump, it can be divided into two categories: jump to page and jump to other processors.
Note that for the page to be forwarded, it can be the page in WEB-INF; for the page to be redirected, it cannot be the page in web-inf. Because redirection is equivalent to the user issuing a request again, and the user cannot directly access the resources in web-inf.
The spring MVC framework encapsulates the request forwarding and redirection operations in the original Servlet. Forwarding and redirection can now be done in a simple way.
- Forward: forward, implementation request.getRequestDispatcher(“x.jsp”).forward()
- redirect: indicates redirection and implements response.sendRediret(“ xx.jsp ”)
1. Request forwarding
When the processor method returns ModelAndView, it needs to add "forward:" before the view specified by setViewName(), and the view no longer works with the view parser at this time, so that the view in different locations can be specified when the parser is configured. The view page must write out the path relative to the project root. The forward operation does not require a view parser.
The processor method returns String, and adds the "forward:" view full path before the view path.
The processor method returns ModelAndView to implement forward
- Syntax: setViewName("forward: view file full path")
- forward feature: not used with the view parser, just when there is no view parser in the project
mv.setViewName("forward:/other.jsp"); mv.setViewName("forward:/WEB-INF/view/some.jsp");
2. Redirection
The processor method returns ModelAndView to redirect
- Syntax: setViewName("redirect: view full path")
- redirect feature: it is not used with the view parser, just when there is no view parser in the project
package cn.edu.huat.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class MyController { @RequestMapping("/doRedirect.do") public ModelAndView doWithRedirect(String username, String password){ ModelAndView mv = new ModelAndView(); mv.addObject("username",username); mv.addObject("password",password); mv.setViewName("redirect:/other.jsp"); return mv; } }
Framework action on redirection
- The framework will convert the simple type of data in the Model to String as other.jsp The get request parameter of. The purpose is to doRedirect.do Passing data between two requests with other. jsp
- In the target hello. jsp page, you can use the parameter collection object ${param} to get the request parameter value
- Redirection cannot access / WEB-INF resource
<h4>username = ${param.username}</h4> <h4>password = ${param.password}</h4> <!--amount to String username = request.getParameter("username");-->
2, Exception handling
A common way for spring MVC framework to handle exceptions: use @ ExceptionHandler annotation to handle exceptions
1. @ ExceptionHandler annotation
Use the annotation @ ExceptionHandler to specify a method as an exception handler. The annotation has only one optional attribute value, which is an array of class <? > to specify the exception class to be handled by the annotation's method, that is, the exception to be matched.
The return value of the annotated method can be ModelAndView, String, or void. The method name is optional. The method parameter can be Exception and its subclass object, HttpServletRequest, HttpServletResponse, etc. The system automatically assigns values to these method parameters.
For the usage of exception handling annotation, you can also directly annotate the exception handling method in the Controller.
2. Exception handling steps
(1) Custom exception class
Three exception classes are defined: NameException, PasswordException, and MyUserException. Where MyUserException is the parent of the other two exceptions.
NameException
package cn.edu.huat.exception; public class NameException extends MyUserException { public NameException() { super(); } public NameException(String message) { super(message); } }
MyUserException
package cn.edu.huat.exception; public class MyUserException extends Exception { public MyUserException() { super(); } public MyUserException(String message) { super(message); } }
(2) Throw exception
Throw NameException, PasswordException in the controller
package cn.edu.huat.controller; import cn.edu.huat.exception.MyUserException; import cn.edu.huat.exception.NameException; import cn.edu.huat.exception.PasswordException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class MyController { @RequestMapping("/some.do") public ModelAndView doSome(String username, String password) throws MyUserException { ModelAndView mv = new ModelAndView(); //Throw an exception based on the request parameter if (!"zs".equals(username)){ throw new NameException("Incorrect name!"); } if (!"123".equals(password) || password == null){ throw new PasswordException("Password error!"); } mv.addObject("username",username); mv.addObject("password",password); mv.setViewName("show"); return mv; } }
(3) Define global exception handling class
Create a normal class to act as a global exception handler
package cn.edu.huat.handler; import cn.edu.huat.exception.NameException; import cn.edu.huat.exception.PasswordException; import com.sun.org.apache.xpath.internal.operations.Mod; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = NameException.class) public ModelAndView doNameException(Exception exception){ //Handling exceptions for NameException ModelAndView mv = new ModelAndView(); mv.addObject("msg","The only value of a name is zs"); mv.addObject("ex",exception); mv.setViewName("nameError"); return mv; } @ExceptionHandler(value = PasswordException.class) public ModelAndView doPasswordException(Exception exception){ //Handling exceptions for NPasswordException ModelAndView mv = new ModelAndView(); mv.addObject("msg","The only value of the password is 123"); mv.addObject("ex",exception); mv.setViewName("passwordError"); return mv; } @ExceptionHandler public ModelAndView doOtherException(Exception exception){ //Handling other types of exceptions ModelAndView mv = new ModelAndView(); mv.addObject("msg","The only value of the password is 123"); mv.addObject("ex",exception); mv.setViewName("defaultError"); return mv; } }
@ControllerAdvice: controller enhancement (that is to say, adding functions to the controller class ----- exception handling function)
- Location: above the class
- Feature: the framework must know the package name of this annotation. You need to declare the component scanner in the spring MVC configuration file and specify the package name of @ controlleradvise
Define methods to handle exceptions:
- The definition of exception handling method is the same as that of controller method. It can have multiple parameters, including return value of ModelAndView, String, void and object type
- Parameter: Exception, indicating the Exception object thrown in the Controller. You can get the Exception information by parameter
- @ExceptionHandler (exception class): indicates the type of exception. When an exception of this type occurs, it is handled by the current method
Exception handling logic:
- It is necessary to record exceptions to database and log files. Record the time when the log occurred, which method occurred, abnormal error content
- Send notice and send abnormal information to relevant personnel via email, SMS and wechat
- User friendly tips
(4) Create a view page to handle exceptions
nameError.jsp
nameError.jsp <br/> Tips: ${MSG} < br / > System exception message:${ ex.message }
passwordError.jsp
passwordError.jsp <br/> Tips: ${MSG} < br / > System exception message:${ ex.message }
(5) Create a configuration file for spring MVC
-
Component scanner, scan @ Controller annotation
<context:component-scan base-package="cn.edu.huat.controller" />
-
Component scanner, scan the package name where @ ControllerAdvice is located
<context:component-scan base-package="cn.edu.huat.handler" />
-
Declaration annotation driven
<mvc:annotation-driven />
(6) Testing
3, Interceptor
Interceptor interceptor in spring MVC is very important and quite useful. Its main function is to intercept the specified user requests and carry out corresponding preprocessing and postprocessing. The intercepting time point is "the processor mapper maps out the processor class to be executed according to the request submitted by the user, and also finds the processor adapter to execute the processor class, before the processor adapter executes the processor". Of course, when the processor mapper maps out the processor class to be executed, it has combined the interceptor and the processor into a processor execution chain and returned it to the central scheduler.
Interceptor:
-
Interceptor is a kind of spring MVC, which needs to implement the HandlerInterceptor interface
-
The interceptor is similar to the filter, and its function direction is different.
- Filters are used to filter request parameters, set coded character sets, etc
- The interceptor intercepts the user's request and makes the request for judgment processing
-
Interceptors are global and can intercept multiple controllers. There can be 0 or more interceptors in a project, and they can intercept users' requests together.
Interceptors are commonly used in: user login processing, permission checking, and logging
Use steps of Interceptor:
- Define class to implement HandlerInterceptor interface
- In the spring MVC configuration file, declare the interceptor to let the framework know the existence of the interceptor
Execution time of Interceptor:
- Before the request is processed, i.e. the method in the Controller class is intercepted before execution
- Interceptors are also executed after the controller method is executed
- Interceptors are also executed after request processing is complete
1. Three methods of interceptor
(1)preHandle
preHandle: preprocessing method
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Interceptor's MyInterceptor Of preHandle()"); return true; }
-
Important: it is the entrance and portal of the whole project. When preHandle returns true, the request can be processed; preHandle returns false, and the request ends in this method
-
parameter
- object handler: intercepted controller object
-
Return value boolean
- true: the request passes the verification of the interceptor, can execute the processor method, and will put the afterCompletion() method into a special method stack to wait for execution
- false: the request does not pass the verification of the interceptor, and the request ends when it reaches the interceptor. Request not processed
- true: the request passes the verification of the interceptor, can execute the processor method, and will put the afterCompletion() method into a special method stack to wait for execution
-
characteristic
- Method is executed before the controller method (doSome of MyController). The user's request first reaches this method
- In this method, the requested information can be obtained to verify whether the request meets the requirements
- You can verify that the user is logged in and that the user has access to a connection address (url). If the validation fails, the request can be truncated and cannot be processed. If the validation succeeds, the request can be released and the controller method can be executed
(2)postHandle
postHandle: post processing method
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Interceptor 's MyInterceptor Of postHandle()"); //Adjust the execution result of the original doOther if (modelAndView != null){ //Modify data modelAndView.addObject("myDate",new Date()); //Modify view modelAndView.setViewName("other"); } }
-
Processing results
-
Parameters:
- object handler: intercepted processor object (MyController)
- Mode lAndView mv: return value of processor method
-
characteristic
- Executed after the processor method( MyController.doSome() )
- If the processor method is not finally executed, it will not execute
- It can obtain the return value of the processor method ModelAndView, modify the data and view in ModelAndView, and affect the final execution result
- It is mainly to revise the original implementation results twice
(3)afterCompletion
afterCompletion: the last method to execute
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("Interceptor's MyInterceptor Of afterCompletion()"); }
-
parameter
- object handler: the intercepted processor object
- Exception ex: exception in program
-
characteristic
-
When the preHandle() method returns true, the method is placed in a special method stack and is not executed until all work to respond to the request is completed. That is to say, this method is executed after the response page is rendered (filled with data) by the central scheduler. At this time, no further operation on ModelAndView will help the response
-
Executed after request processing is complete. It is stipulated in the framework that when the view processing is completed, forward is executed for the view. Consider the request processing completed
-
Generally do resource recovery work. Some objects are created in the process of program request, which can be deleted and used memory can be recycled
-
2. Execution of an interceptor
The execution sequence of methods and processor methods in the interceptor is as follows:
In another form, it can also be understood as follows:
(1) Register interceptor
<! -- declare interceptors: interceptors can have more than one or 0 -- > <mvc:interceptors> <! -- declare first interceptor -- > <mvc:interceptor> <! -- specifies the request URI address to be intercepted path: is the uri address. Wildcards can be used **: represents any character, file or file in multi-level directory and directory -- > <mvc:mapping path="/**"/> <! -- declare interceptor object -- > <bean class="cn.edu.huat.handler.MyInterceptor" /> </mvc:interceptor> </mvc:interceptors>
(2) Define interceptor
package cn.edu.huat.handler; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("111 - Interceptor's MyInterceptor Of preHandle()"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("111 - Interceptor's MyInterceptor Of postHandle()"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("111 - Interceptor's MyInterceptor Of afterCompletion()"); } }
(3) Console execution results
3. Execution of multiple interceptors
(1) Register multiple interceptors
<! -- declare interceptors: interceptors can have more than one or 0 Save multiple interceptors in the framework as ArrayList, and put them into ArrayList in the order of Declaration -- > <mvc:interceptors> <! -- declare first interceptor -- > <mvc:interceptor> <mvc:mapping path="/**"/> <! -- declare interceptor object -- > <bean class="cn.edu.huat.handler.MyInterceptor" /> </mvc:interceptor> <! -- declare the second interceptor -- > <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="cn.edu.huat.handler.MyInterceptor2" /> </mvc:interceptor> </mvc:interceptors>
(2) Redefining interceptors
package cn.edu.huat.handler; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor2 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("222 - Interceptor's MyInterceptor Of preHandle()"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("222 - Interceptor's MyInterceptor Of postHandle()"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("222 - Interceptor's MyInterceptor Of afterCompletion()"); } }
(3) Console execution results
When there are multiple interceptors, an interceptor chain is formed. The execution order of the blocker chain is the same as its registration order. It needs to be emphasized again that when the preHandle() method of an interceptor returns true and is executed, the interceptor's afterCompletion() method will be put into a special method stack.
The execution sequence of methods and processor methods in multiple interceptors is as follows:
4. Difference between interceptor and filter
(1) Filters are objects in servlet s and interceptors are objects in frameworks
(2) The Filter implements the object of the Filter interface, and the interceptor implements the HandlerInterceptor interface
(3) Filter is used to set the parameters and properties of request and response, focusing on data filtering. Interceptors are used to verify requests and can truncate them.
(4) The filter is executed before the interceptor
(5) Filters are objects created by the tomcat server. Interceptors are objects created in the spring MVC container
(6) The filter is a point in time. The interceptor has three execution points
(7) Filters can handle jsp, js, html, and so on. Interceptor focuses on intercepting the object of Controller. If the request cannot be received by dispatcher servlet, the request will not execute interceptor content
(8) Interceptor intercepts the execution of ordinary class methods, filter servlet request response
5. Example of permission interceptor
Only the logged in user can access the processor, otherwise, the "no access" prompt will be returned.
The login of this example is completed by a JSP page. Put the user information into the session in this page. That is, as long as you have visited the page, you are logged in. If it has not been accessed, it is an unregistered user.
(1) Define index page
<form action="other.do" method="post"> //Name: < input type = "text" name = "username" / > < br > //Password: < input type = "text" name = "password" / > < br > <input type="submit" value="Submit request"> </form>
(2) Create MyController to process requests
package cn.edu.huat.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class MyController { @RequestMapping("/other.do") public ModelAndView doOther(String username, String password){ ModelAndView mv = new ModelAndView(); mv.addObject("username",username); mv.addObject("password",password); mv.setViewName("show"); return mv; } }
(3) Create show. jsp
<h3>Hello SpringMVC!</h3><br> <h4>username = ${username}</h4> <h4>password = ${password}</h4>
(4) Create login.jsp
Simulate login (put user's information into session)
Simulated Login, zs login system <% session.setAttribute("name","zs"); %>
(5) Create logout.jsp
Simulation exit system (delete data from session)
Exit the system and delete the data from the session <% session.removeAttribute("name"); %>
(6) Create interceptor
Obtain the login data of the user from the session, and verify whether the system can be accessed
package cn.edu.huat.handler; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor implements HandlerInterceptor { //Verify the logged in user information. The correct return is true. The other return is false @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String loginName = ""; //Get the value of name from session Object attr = request.getSession().getAttribute("name"); if (attr != null){ loginName = (String) attr; } //Judge whether the login account meets the requirements if (!"zs".equals(loginName)){ //Unable to access system //Prompt the user request.getRequestDispatcher("/tips.jsp").forward(request,response); return false; } //zs login return true; } }
(7) Create tips.jsp
A verified tips.jsp , if the view is validated, give a prompt
tips.jsp Non zs cannot access
(8) Create spring MVC configuration file
<context:component-scan base-package="cn.edu.huat.controller" /> <mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/" /> <property name="suffix" value=".jsp" /> </bean>
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="cn.edu.huat.handler.MyInterceptor" /> </mvc:interceptor> </mvc:interceptors>
(9) Testing
Log in first
After the request is submitted, it is blocked by the interceptor because no user name is stored in the session
visit login.jsp , save the user name to the session
Now go back to the home page and log in again
Since zs has been stored in the session, the interceptor will automatically release according to the code in it
At this time, we log out and there is nothing in the session. If we visit again, we can only jump to the error prompt page
4, Spring MVC execution process (understanding)
1. Flow chart
The processing flow of spring MVC internal request: that is, the process from spring MVC receiving request to processing completion
(1) Browser
User initiated request some.do
(2) Processor mapper
Dispatcher servlet receives requests some.do , forward request to processor mapper
- Processor mapper: an object in the spring MVC framework. The framework calls the classes that implement the HandlerMapping interface mapper (multiple)
- Processor mapper function: according to the request, get the processor object (mycontroller) from the springnmvc container object= ctx.getBean (“ some.do ”) )
The framework stores the found processor object in a class called handler execution chain - HandlerExecutionChain: class holds the following
- Processor object (MyController)
- List of all interceptors in the project < handlerinterceptor > interceptorlist
(3) Processor adapter
DispatcherServlet gives the processor object in the HandlerExecutionChain in 2 to the processor adapter object (s)
-
Processor adapter: an object in the spring MVC framework, which needs to implement the HandlerAdapter interface
-
Processor adapter function: execute processor method (call MyController.doSome() get return value ModelAndView)
-
Call adapter in central scheduler
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
-
Execution processor method
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
(4) View parser
The dispatcher servlet gives the ModelAndView obtained in 3 to the view parser object.
- View resolver: the object in spring MVC needs to implement the viewresolver interface (there can be multiple)
- The function of view resolver: make up the complete path of view, use prefix and suffix. And create a view object
- View: it is an interface that represents views. In the framework, jsp and html are not represented by String, but by view and its implementation class
- InternalResourceView: view class, representing JSP file. The view parser will create InternalResourceView class object. In this object, there is a property url = /WEB-INF/view/show.jsp
(5) View
The dispatcher servlet gets the View object created in step 4, calls the View class's own method, and puts the Model data into the request scope. Execute forward for the object View. End of request.
2. Simple analysis of execution process
(1) Browser submits request to central scheduler
(2) The central scheduler transfers the request directly to the processor mapper
(3) According to the request, the processor mapper finds the processor processing the request, encapsulates it as a processor execution chain and returns it to the central scheduler
(4) The central scheduler finds the processor adapter that can execute the processor according to the processor in the processor execution chain
(5) Processor adapter calls execution processor
(6) The processor encapsulates the processing result and the view to jump into an object ModelAndView and returns it to the processor adapter
(7) The processor adapter returns the result directly to the central scheduler
(8) The central scheduler calls the view resolver to encapsulate the view name in ModelAndView as a view object
(9) The view parser returns the encapsulated view object to the central scheduler
(10) The central scheduler calls the view object to render itself, that is, to fill in the data to form the response object
(11) Central scheduler response browser