SpringMVC framework----->(5) SpringMVC core technology (forwarding and redirection, exception handling, interceptor)

SpringMVC core technology

1. Request forwarding and redirection

  • When the processor completes processing the request and jumps to other resources, there are two jump methods: request forwarding and redirection. According to the type of resource to be jumped, it can be divided into two categories: jump to the page and jump to other processors.

Note that the page requested to be forwarded can be a page in WEB-INF; while a redirected page cannot be a page in WEB-INF. Because redirection is equivalent to the user making a request again, and the user cannot directly access the resources in WEB-INF.

Insert picture description here

The SpringMVC framework encapsulates the request forwarding and redirection operations in the original Servlet. Now you can use a simple way to achieve forwarding and redirection.

(1) Request forwarding

  • forward:

Represents forwarding, realizes request.getRequestDispatcher("xx.jsp").forward()

  • Features:

Do not work with the view resolver, you can access the page in WEB-INF

  • grammar:
setViewName("forward:视图文件完整路径")
@RequestMapping(value = "/doForward.do")
public ModelAndView doSome(){
    
    
    //处理some.do请求了。 相当于service调用处理完成了。
    ModelAndView mv  = new ModelAndView();
    mv.addObject("msg","欢迎使用springmvc做web开发");
    mv.addObject("fun","执行的是doSome方法");
    //使用forward显示转发
    //mv.setViewName("forward:/WEB-INF/view/show.jsp");
    mv.setViewName("forward:/hello.jsp");
    return mv;
}

(2) Request redirection

  • redirect:

Represents redirection, realizes response.sendRedirect("xxx.jsp")

  • Features:

Does not work with the view resolver and cannot access pages in WEB-INF

  • grammar:
setViewName("redirect:视图完整路径")
/**
 * 框架对重定向的操作:
 * 1.框架会把Model中的简单类型的数据,转为string使用,作为hello.jsp的get请求参数使用。
 *   目的是在 doRedirect.do 和 hello.jsp 两次请求之间传递数据
 *
 * 2.在目标hello.jsp页面可以使用参数集合对象 ${param}获取请求参数值
 *    ${param.myname}
 *
 * 3.重定向不能访问/WEB-INF资源
 */
@RequestMapping(value = "/doRedirect.do")
public ModelAndView doWithRedirect(String name,Integer age){
    
    
    //处理some.do请求了。 相当于service调用处理完成了。
    ModelAndView mv  = new ModelAndView();
    //数据放入到 request作用域
    mv.addObject("myname",name);
    mv.addObject("myage",age);
    //重定向
    mv.setViewName("redirect:/hello.jsp");
    //http://localhost:8080/springmvc/hello.jsp?myname=lisi&myage=22

    //重定向不能访问/WEB-INF资源
    //mv.setViewName("redirect:/WEB-INF/view/show.jsp");
    return mv;
}

2. Exception handling

  • All the exception handling in the controller is concentrated in one place, and the idea of ​​aop is adopted to separate business logic and exception handling code to achieve decoupling.
Use two annotations

1) @ControllerAdvice: Defined on the class to enhance the exception handling function for the controller class. The component scanner needs to be declared in the springmvc configuration file to specify the package name where the annotation is located.

2) @ExceptionHandler: Defined on the method, the value attribute indicates the type of exception, and when such an exception occurs, the current method handles the exception.

(1) Custom exception class

  • Define three exception classes: NameException, AgeException, MyUserException. Among them, MyUserException is the parent class of the other two exceptions.
public class MyUserException extends Exception{
    
    

    public MyUserException() {
    
    
        super();
    }

    public MyUserException(String message) {
    
    
        super(message);
    }
}
/**
 * 表示用户姓名有异常,抛出异常
 */
public class NameException extends MyUserException {
    
    
    public NameException() {
    
    
        super();
    }

    public NameException(String message) {
    
    
        super(message);
    }
}
/**
 * 表示年龄有异常抛出异常
 */
public class AgeException extends MyUserException{
    
    
    public AgeException() {
    
    
        super();
    }

    public AgeException(String message) {
    
    
        super(message);
    }
}

(2) Define the global exception handling class

@ControllerAdvice
public class GlobalExceptionHandler {
    
    
    //定义方法,处理异常
    @ExceptionHandler(value = NameException.class)
    public ModelAndView doNameException(Exception exception){
    
    
        //处理NameException的异常
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","姓名必须是张三,其它用户不能访问");
        mv.addObject("ex",exception);
        mv.setViewName("nameError");
        return mv;
    }

    @ExceptionHandler(value = AgeException.class)
    public ModelAndView doAgeException(Exception exception){
    
    
        //处理AgeException的异常
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","年龄必须不能大于80");
        mv.addObject("ex",exception);
        mv.setViewName("ageError");
        return mv;
    }

    //处理其它异常
    @ExceptionHandler
    public ModelAndView doOtherException(Exception exception){
    
    
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","发生其它异常");
        mv.addObject("ex",exception);
        mv.setViewName("defaultError");
        return mv;
    }
}

(3) Declare the component scanner in the springmvc configuration file

<!--声明组件扫描器:@Controller所在包名-->
<context:component-scan base-package="com.hcz.controller" />
<!--声明组件扫描器:@ControllerAdvice所在包名-->
<context:component-scan base-package="com.hcz.handler"/>
<!--注解驱动-->
<mvc:annotation-driven/>

(4) Create a page for handling exception results

<body>
ageError.jsp<br/>
提示信息:${msg}<br>
系统异常信息:${ex.message}
</body>
<body>
    nameError.jsp<br/>
    提示信息:${msg}<br>
    系统异常信息:${ex.message}
</body>
<body>
    defaultError.jsp<br/>
    提示信息:${msg}<br>
    系统异常信息:${ex.message}
</body>

3. Interceptor

(1) Overview of interceptors:

  • 1) Interceptor is a kind of springmvc and needs to implement the HandlerInterceptor interface.
  • 2) The interceptor is similar to the filter, but the focus of the function direction is different. Filters are used to filter request parameters, set coded character sets, and other tasks. The interceptor intercepts the user's request and makes the request for judgment processing.
  • 3) The interceptor is global and can intercept multiple Controllers. There can be 0 or more interceptors in a project, and they intercept user requests together.
  • 4) Interceptors are commonly used in: user login processing, permission checking, and logging.

(2) Steps to use the interceptor:

1. Define the class to implement the HandlerInterceptor interface.
2. In the springmvc configuration file, declare the interceptor to let the framework know the existence of the interceptor.

(3) Execution time of the interceptor:

1) Before the request is processed, that is, before the method in the controller class is executed, it is intercepted.
2) The interceptor will also be executed after the controller method is executed.
3) The interceptor will also be executed after the request processing is completed.

(4) Custom interceptor

  • Need to implement the HandlerInterceptor interface, and the interface contains three methods:
  • preHandle(request,response, Object handler):

preHandle returns true: the request is verified by the interceptor, and the handler method can be executed


Interceptor's preHandle() of MyInterceptor
=Execute the doSome method in MyController=
Interceptor's MyInterceptor's postHandle()
interceptor's MyInterceptor's afterCompletion()

preHandle returns false: the request does not pass the verification of the interceptor, the request is terminated when it reaches the interceptor, and the request is not processed

Features :
1. The method is executed before the controller method (doSome of MyController). The user's request first reaches this method
2. In this method, the requested information can be obtained to verify whether the request meets the requirements. You can verify whether the user is logged in, and verify whether the user has permission to access a certain connection address (url).
If the verification fails, the request can be truncated and the request cannot be processed.
If the verification is successful, the request can be released, and then the controller method can be executed.

  • postHandle(request,response, Object handler,modelAndView):

Features :
1. The method is executed after the processor method is executed. If the processor method is not executed in the end, the method will not be executed.
2. The method parameter contains ModelAndView, so the method can modify the processing result data of the processor method, and can modify the jump direction

  • afterCompletion(request,response, Object handler, Exception ex):

When the preHandle() method returns true, the method will be placed in a special method stack, and the method will be executed after all the work in response to the request is completed. Generally, it is the last method to be executed for resource recovery.

(5) springmvc registration interceptor

<!--声明拦截器: 拦截器可以有0或多个-->
<mvc:interceptors>
    <!--声明第一个拦截器-->
    <mvc:interceptor>
        <!--指定拦截的请求uri地址
            path:就是uri地址,可以使用通配符 **
                  ** : 表示任意的字符,文件或者多级目录和目录中的文件
            http://localhost:8080/myweb/user/listUser.do
            http://localhost:8080/myweb/student/addStudent.do
        -->
        <mvc:mapping path="/**"/>
        <!--声明拦截器对象-->
        <bean class="com.hcz.handler.MyInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

(6) A working flow chart of an interceptor:

Insert picture description here

(7) Work flow chart of multiple interceptors:

Insert picture description here

As can be seen from the figure, as long as a preHandle() method returns false, the upper execution chain will be disconnected, and
its subsequent processor methods and postHandle() methods will not be executed. But regardless of the execution of the execution chain, as long as there are methods in the method stack, that is, as long as the preHandle() method in the execution chain returns true, the afterCompletion() method in the method stack will be executed, and a response will eventually be given.

(8) The difference between interceptor and filter

1. The filter is the object in the servlet, the interceptor is the object in the framework; the filter implements the object of the Filter interface, and the interceptor implements the HandlerInterceptor
2. The filter is used to set the request and response parameters and attributes, focusing on the right Data filtering; interceptors are used to verify requests and can intercept requests.
3. The filter is executed before the interceptor.
4. The filter is the object created by the tomcat server; the interceptor is the object created in the springmvc container
5. The filter is an execution time point; the interceptor has three execution time points
6. The filter can process jsp, js, html, etc. ; Interceptor is focused on intercepting the object of the Controller. If your request cannot be received by the central dispatcher DispatcherServlet, the request will not execute the interceptor content.
7. The interceptor intercepts the execution of ordinary methods, and the filter filters the servlet request response

(9) The interceptor verifies the login item

  • Case: Only the logged-in user can access the processor, otherwise, it will return to "No access" prompt

Implementation steps:
1. Create a new maven
2. Modify web.xml to register the central scheduler
3. Create a new index.jsp to initiate a request
4. Create a MyController to process the request
5. Create the result show.jsp
6. Create a login.jsp to simulate login (put The user information is saved in the session)
7. Create a logout.jsp to simulate exiting the system (delete data from the session)
8. Create an interceptor to obtain the user's login data from the session to verify whether the system is accessed or not.
9. Create an authentication jsp, if you verify the view, give a prompt
10. Create a springmvc configuration file
1) Declare the component scanner
2) Declare the interceptor

A. Create a new index.jsp page
<body>
    <p>一个拦截器</p>
    <form action="some.do" method="post">
        姓名:<input type="text" name="name"> <br/>
        年龄:<input type="text" name="age"> <br/>
        <input type="submit" value="提交请求">
    </form>
</body>
B. Create a Controller to process the request
@Controller
public class MyController {
    
    

    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(String name,Integer age)  {
    
    
        System.out.println("=====执行MyController中的doSome方法=====");
        //处理some.do请求了。 相当于service调用处理完成了。
        ModelAndView mv  = new ModelAndView();
        mv.addObject("myname",name);
        mv.addObject("myage",age);
        mv.setViewName("show");
        return mv;
    }
}
C. Create the result page show.jsp
<body>
    <h3>/WEB-INF/view/show.jsp从request作用域获取数据</h3><br/>
    <h3>myname数据:${myname}</h3><br/>
    <h3>myage数据:${myage}</h3>
</body>
D. Create a login page login.jsp
<body>
    模拟登录,zs登录系统
    <%
        session.setAttribute("name","zs");
    %>
</body>
E. Create logout.jsp to exit the system
<body>
    退出系统
    <%
        session.removeAttribute("name");
    %>
</body>
F. Create an interceptor class
/**
 * 拦截器类:拦截用户的请求
 */
public class MyInterceptor implements HandlerInterceptor {
    
    

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("111111-拦截器的MyInterceptor的preHandle()");
        String loginName = "";
        //从session中获取name数据
        Object attr = request.getSession().getAttribute("name");
        if (attr != null){
    
    
            loginName = (String)attr;
        }
        //判断登录的账号是否符合要求
        if (!"zs".equals(loginName)){
    
    
            //不能访问
            request.getRequestDispatcher("/tips.jsp").forward(request,response);
            return false;
        }
        return true;
    }
}
G. Create a prompt page that has not been logged in
<body>
  tips.jsp  非张三不能访问
</body>
H, modify the springmvc configuration file
<!--声明组件扫描器-->
<context:component-scan base-package="com.hcz.controller" />

<!--声明 springmvc框架中的视图解析器, 帮助开发人员设置视图文件的路径-->
<bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--前缀:视图文件的路径-->
    <property name="prefix" value="/WEB-INF/view/" />
    <!--后缀:视图文件的扩展名-->
    <property name="suffix" value=".jsp" />
</bean>

<!--声明拦截器: 拦截器可以有0或多个
    在框架中保存多个拦截器是ArrayList,
    按照声明的先后顺序放入到ArrayList
-->
<mvc:interceptors>
    <!--声明第一个拦截器-->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <!--声明拦截器对象-->
        <bean class="com.hcz.handler.MyInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>
I. Project testing

1) http://localhost:8080/springmvc/index.jsp
Because the zs user is not logged in, it cannot respond to the index.jsp page request
2) http://localhost:8080/springmvc/login.jsp
3) http:// localhost:8080/springmvc/index.jsp
Because the zs user has logged in, it can respond to the index.jsp page request and forward it to the show.jsp page
4) http://localhost:8080/springmvc/login.jsp
5) http:/ /localhost:8080/springmvc/logout.jsp
6) http://localhost:8080/springmvc/index.jsp
When zs users log out of the system, they can no longer respond to the index.jsp page

Guess you like

Origin blog.csdn.net/hcz666/article/details/113988586