SpringMVC learning record

Note: The following content is the notes, source code and personal understanding recorded after learning the SpringMVC video of Beijing Power Node, recorded for learning only

Chapter 4 SpringMVC core technology

4.2 Exception Handling

A common way the SpringMVC framework handles exceptions is by using the @ExceptionHandler annotation.

Exception handling procedure:

  1. Create a New Maven Web project
  2. Join the rely on
  3. Create a custom exception class MyUserException and define its subclasses NameException and AgeException
  4. Throw NameException, AgeException in controller
  5. Create a normal class for global exception handling (1). Add @ControllerAdvice (2) to the top of the class. Define a method in the class with @ExceptionHandler above it
  6. Create a view page to handle exceptions
  7. Create springMVC configuration file (1). Component scanner, scan @Controller annotation (2). Component scanner that scans the package name in which @controllerAdvice is located (3). Declaration annotation driver

Project Structure:

2 @ ExceptionHandler annotation

The @ExceptionHandler annotation is used to specify a method as an exception handling method. The annotation has only one optional attribute, value, which is a Class<? > array that specifies the exception class to be handled by the annotated method, that is, the exception to be matched. The return value of an annotated method can be ModelAndView, String, or void, and the method name can be arbitrary. The method parameters can be Exception and its subclasses, HttpServletRequest, HttpServletResponse, and so on. The system automatically assigns values to these method parameters. For the use of exception handling annotations, it is also possible to annotate exception handling methods directly into the Controller.

(1) Custom exception class

Define three exception classes: NameException, AgeException, and MyUserException. MyUserException is the parent of the other two exceptions. MyUserException.java

package com.bjpowernode.exception;
public class MyUserException extends Exception {
    public MyUserException(a) {
        super(a); }public MyUserException(String message) {
        super(message); }}Copy the code

AgeException.java

package com.bjpowernode.exception;

// The exception thrown when there is an age problem
public class AgeException extends MyUserException {
    public AgeException(a) {
        super(a); }public AgeException(String message) {
        super(message); }}Copy the code

NameException.java

package com.bjpowernode.exception;
// Throws a NameException when the user's name is abnormal
public class NameException extends MyUserException {
    public NameException(a) {
        super(a); }public NameException(String message) {
        super(message); }}Copy the code

(2) Modify Controller to throw an exception

MyController.java

package com.bjpowernode.controller;

import com.bjpowernode.exception.AgeException;
import com.bjpowernode.exception.MyUserException;
import com.bjpowernode.exception.NameException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.ws.RequestWrapper;

/ * * *@RequestMapping: * value: The common part of all requested addresses, called the module name * location: placed above the class */
@Controller
public class MyController {
    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(String name,Integer age) throws MyUserException {
        // The some.do request was processed. The service call processing is complete.
        ModelAndView mv  = new ModelAndView();

        //try {
            // Throw an exception based on the request parameters
            if (!"zs".equals(name)) {
                throw new NameException("Wrong name!!");
            }

            if (age == null || age > 80) {
                throw new AgeException("Older!!");
            }

        //}catch(Exception e){
        // e.printStackTrace();
        / /}
        mv.addObject("myname",name);
        mv.addObject("myage",age);
        mv.setViewName("show");
        returnmv; }}Copy the code

(3) Define the abnormal request and response page

Request page: index.jsp

<%@ page contentType="text/html; charset=UTF-8" language="java" %> <% String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/"; % ><html>
<head>
    <title>Title</title>
    <base href="<%=basePath%>" />
</head>
<body>
     <p>Handle exceptions, global exception handling</p>
    <form action="some.do" method="post">Name:<input type="text" name="name"> <br/>Age:<input type="text" name="age"> <br/>
        <input type="submit" value="Submit request">
    </form>
</body>
</html>
Copy the code

Response page ageerror.jsp

<%@ page contentType="text/html; charset=UTF-8" language="java" %><html>
<head>
    <title>Title</title>
</head>
<body>
   ageError.jsp <br/>${MSG}<br/>System exception message: ${ex.message}</body>
</html>

Copy the code

defaultError.jsp

<%@ page contentType="text/html; charset=UTF-8" language="java" %><html>
<head>
    <title>Title</title>
</head>
<body>
   defaultError.jsp <br/>${MSG}<br/>System exception message: ${ex.message}</body>
</html>

Copy the code

nameError.jsp

<%@ page contentType="text/html; charset=UTF-8" language="java" %><html>
<head>
    <title>Title</title>
</head>
<body>
   nameError.jsp <br/>${MSG}<br/>System exception message: ${ex.message}</body>
</html>

Copy the code

(4) Define global exception handling classes

However, this is not generally used. Instead, the exception handling methods are specifically defined in a class as a global exception handling class. You need to use the @controllerAdvice annotation, which literally means’ controller enhancement ‘, to enhance controller objects. A class decorated with @ControllerAdvice can use @ExceptionHandler. When an exception is thrown by a method decorated with the @RequestMapping annotation, the exception handling method in the @ControllerAdvice modified class is executed. ==@ControllerAdvice == with the @Component annotation, you can create an object by scanning the classpath (package name) of @ControllerAdvice in context: Component-scan.

GlobalExceptionHandler.java

package com.bjpowernode.handler;

import com.bjpowernode.exception.AgeException;
import com.bjpowernode.exception.NameException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

/ * * *@ControllerAdvice: Controller enhancements (that is, add functionality to the controller class -- exception handling) * Location: above the class. * Features: The framework must be aware of the package name in which the annotation is located, and the component scanner needs to be declared in the SpringMVC configuration file. * specified@ControllerAdviceThe package name is */
@ControllerAdvice
public class GlobalExceptionHandler {
    // Define methods to handle exceptions that occur
    /* The Exception handling method can take multiple arguments, as defined by the Controller method. It can have ModelAndView, String, void, and return value parameters of the object type: Exception, which represents the Exception object thrown by the Controller. Parameters are used to obtain information about the exception that occurred. @ExceptionHandler(Exception class) : Indicates the type of exception. When this type of exception occurs, the current method handles it */

    @ExceptionHandler(value = NameException.class)
    public ModelAndView doNameException(Exception exception){
        // Handle NameException.
        /* Exception occurrence processing logic: 1. Need to record the exception, record the database, log file. Record the time when the log occurred, which method occurred, and the exception error content. 2. Send notifications and send abnormal information to relevant personnel through email, SMS or wechat. 3. Give user friendly tips. * /
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg"."Name must be ZS and cannot be accessed by other users");
        mv.addObject("ex",exception);
        mv.setViewName("nameError");
        return mv;
    }


    / / AgeException processing
    @ExceptionHandler(value = AgeException.class)
    public ModelAndView doAgeException(Exception exception){
        // Handle exceptions for AgeException.
        /* Exception occurrence processing logic: 1. Need to record the exception, record the database, log file. Record the time when the log occurred, which method occurred, and the exception error content. 2. Send notifications and send abnormal information to relevant personnel through email, SMS or wechat. 3. Give user friendly tips. * /
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg"."You can't be older than 80.");
        mv.addObject("ex",exception);
        mv.setViewName("ageError");
        return mv;
    }

    // Handle exceptions other than NameException and AgeException
    @ExceptionHandler
    public ModelAndView doOtherException(Exception exception){
        // Handle other exceptions
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg"."You can't be older than 80.");
        mv.addObject("ex",exception);
        mv.setViewName("defaultError");
        returnmv; }}Copy the code

ControllerAdvice class is annotated with @Component. @Component is used for ControllerAdvice: Instantiate regular POJO classes into the Spring container, equivalent to the
@Component, @service,@Controller, @repository annotation classes in the configuration file. And manage these classes in the Spring container.

(5) Define the Spring configuration file

springmvc.xml


      
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <! Declare component scanner -->
    <context:component-scan base-package="com.bjpowernode.controller" />

    <! Declare the view parser in the SpringMVC framework to help developers set the path of view files.
    <bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <! Prefix: view file path -->
        <property name="prefix" value="/WEB-INF/view/" />
        <! -- suffix: extension of view file -->
        <property name="suffix" value=".jsp" />
    </bean>
    
    
    <! -- Two steps to handle the need
    <context:component-scan base-package="com.bjpowernode.handler" />
    <mvc:annotation-driven />
</beans>
Copy the code

web.xml


      
<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">

    <! To register springMVC's core object DispatcherServlet, you need to create an instance of the DispatcherServlet object after the Tomcat server is started. Why create an instance of the DispatcherServlet object? Because DispatcherServlet creates springMVC container objects in its creation process, reads the SpringMVC configuration file, creates the objects in this configuration file, and can use the objects directly when the user makes a request. The initialization of the servlet executes the init () method. DispatcherServlet creates container in init () { Reading configuration files WebApplicationContext CTX = new ClassPathXmlApplicationContext (" for springmvc. XML "); // Put the container object into ServletContext getServletContext().setAttribute(key, CTX); / web-INF /springmvc-servlet.xml (/ web-INF/myWeb-servlet.xml) The default configuration file read is/web-INF /<servlet-name>-servlet.xml. -->
    <servlet>
        <servlet-name>myweb</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <! -- Customize the location of configuration files read by SpringMVC -->
        <init-param>
            <! -- SpringMVC configuration file location property -->
            <param-name>contextConfigLocation</param-name>
            <! -- Specify location of custom file -->
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>

        <! Load-on-startup: specifies the sequence of objects created after Tomcat is started. Its value is an integer, and the smaller the value, the earlier Tomcat creates the object. An integer greater than or equal to 0. -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>myweb</servlet-name>
        <! When using frames, url-pattern can use two values: 1. XXXX is a user-defined extension name. Commonly used way *. Do *. Action, *. MVC, and so on Can't use the *. JSP http://localhost:8080/myweb/some.do http://localhost:8080/myweb/other.do 2. Use the slash "/" -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>
Copy the code