yml configuration file syntax-interceptor-request parameter verification

1.ymlConfiguration file syntax

1. Configure custom data

1.1 Configure common data

Syntax: key: value

name: kaifamiao
1.2 Configuration object data

Grammar 1:

key:

? key1: value1;

? key2: value2;

person:
  name: zhangsan
  age: 19

Grammar 2:

key: {key1: value1,key: value2}

person1: {<!-- -->name: lisi,age: 21}
1.3 Configure Mapdata

Same configuration object data

1.4 Configuration array (list, set) data

Grammar 1:

key:

- value1

- value2

student:
  - maqi
  - sunliu

Grammar 2:

key: [value1,value2]

student1: [phr,lzh,zk]

Elements in a collection can be objects

student2:
  - name: zhangkui
    age: 22
    gender: male
  - name: penghaorun
    age: 21
    gender: male

2. Mapping relationship between configuration issues and configuration classes

1. Use the annotation @Value

For example, the yml question is as follows:

name: kaifamiao
person:
  name: zhangsan
  age: 19

The code to obtain the data is as follows:

package com.lzh.mybatis_springboot.testyml;

import com.lzh.mybatis_springboot.model.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class Yml {<!-- -->
  
    //Get a single attribute
    @Value("${name}")
    private String name;
    //Get object properties
    @Value("${person.name}")
    private String getName;
    @Value("${person.age}")
    private Integer age;
    @Test
    public void test() {<!-- -->

        System.out.println(name);
        System.out.println(getName);
        System.out.println(age);

    }
}

2. Use the Environment class

The yml file is as follows:

person:
  name: zhangsan
  age: 19

retrieve data:

package com.lzh.mybatis_springboot.controller;

import com.lzh.mybatis_springboot.model.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class TestYmlController {<!-- -->
    //Directly inject the Environment object environment and use the environment.getProperty() method to get the value
    @Autowired
    Environment environment;
    @Autowired
    Person person;
    @RequestMapping("/test")
    public String test(){<!-- -->
        System.out.println(environment.getProperty("name"));
        System.out.println(environment.getProperty("person.name"));
        System.out.println(environment.getProperty("student[0]"));
        System.out.println(person);
        return "/emp/list";
    }
}

3. Use the @ConfigurationProperties(prefix = "prefix of the key in the configuration file") annotation

yml file

person:
  name: zhangsan
  age: 19

Entity class

package com.lzh.mybatis_springboot.model;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data//Why write this annotation? It’s because the set method is required when using the annotation @ConfigurationProperties to obtain data.
//person refers to the prefix of the key in the configuration file
@ConfigurationProperties(prefix = "person")
@Component
public class Person {<!-- -->
    private String name;
    private int age;
}

retrieve data

package com.lzh.mybatis_springboot.testyml;

import com.lzh.mybatis_springboot.model.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.awt.print.Pageable;

@SpringBootTest
public class ConfigYml {<!-- -->
    @Autowired
    Person person;

    @Test
    public void test() {<!-- -->
        System.out.println(person.getAge());
    }
}

Note: Use the @ConfigurationProperties method to automatically map configuration files and entity fields, but fields are required

The set method must be provided. Fields modified with the @Value annotation do not need to provide the set method.

3. Interceptor

The interceptor will not intercept static resources. The default static directory of Spring Boot is resources/static. Static pages in this directory,

JS, CSS, images, etc. will not be intercepted. Of course, this also depends on the implementation process. In some cases, they may be intercepted.

1. Interceptor usage steps:

1.1 Define interceptors

Create a class that implements the HandlerInterceptor interface and overrides three methods

preHandle(……) method

The execution time of this method is when a URL has matched a method in the corresponding Controller and before this method is executed

forward. Therefore, the preHandle(......) method can decide whether to release the request. This is determined by the return value. If it returns true, the request will be released.

line, returning false will not execute backwards.

postHandle(……) method

The execution time of this method is when a URL has matched a method in the corresponding Controller and the method has been executed.

But before the DispatcherServlet view is rendered. So there is a ModelAndView parameter in this method, you can do something here

some modification actions.

afterCompletion(……) method

As the name suggests, this method is executed after the entire request processing is completed (including view rendering). At this time, some resource cleanup work is done. This

The method will only be executed after preHandle(…) is successfully executed and returns true.

package com.lzh.mybatis_springboot.interceptor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Implement HandlerInterceptor interface override method
 * Realize that non-logged-in users cannot access other pages other than the login page
 */
@Component
public class MyInterceptor implements HandlerInterceptor {<!-- -->

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {<!-- -->
        HttpSession session = request.getSession(); //Get the Session because the user's login information exists in the session
        Object user = session.getAttribute("loginUser");//Use this method to get the value stored in the session domain
        if(user==null){<!-- -->//If it is empty, it proves that there is no such user in the session and redirects to the login page
            response.sendRedirect(request.getContextPath() + "/user/login");
            return false;
        }
        System.out.println("The user is logged in, let go");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse
         response, Object handler, ModelAndView modelAndView) throws Exception {<!-- -->
        log.info("After executing the method, it will be executed (after the Controller method is called), but the view rendering has not yet been performed.
       dye");
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) throws Exception{<!-- -->
log.info("The entire request has been processed, and DispatcherServlet has also rendered the corresponding view. At this time, I can
Let's do some cleanup work");
}
}

1.2 Configuring interceptors

Implement the WebMvcConfigurer interface and override the addInterceptors() method

package com.lzh.mybatis_springboot.config;

import com.lzh.mybatis_springboot.interceptor.AccessIPInterceptor;
import com.lzh.mybatis_springboot.interceptor.LoginCountInterceptor;
import com.lzh.mybatis_springboot.interceptor.MyInterceptor;
import com.lzh.mybatis_springboot.interceptor.RequestManyInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Configure interceptor
 */
@Component
public class MyConfig implements WebMvcConfigurer {<!-- -->
    @Autowired
    MyInterceptor myInterceptor;
    @Autowired
    AccessIPInterceptor accessIPInterceptor;
    @Autowired
    LoginCountInterceptor loginCountInterceptor;
    @Autowired
    RequestManyInterceptor requestManyInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {<!-- -->
// InterceptorRegistration interceptor = registry.addInterceptor(myInterceptor); //Configure the interceptor object
// InterceptorRegistration pathPatterns = interceptor.addPathPatterns("/*");
// //Which resources can enter the interceptor
// InterceptorRegistration excluded = interceptor.excludePathPatterns("/css");
// //Which resources do not enter the interceptor
// registry.addInterceptor(myInterceptor).addPathPatterns("/**").
// excludePathPatterns("/login", "/captcha", "/js/**", "/css/**", "/font/**");
        registry.addInterceptor(loginCountInterceptor).addPathPatterns("/login")
                .excludePathPatterns("/logins", "/captcha", "/js/**", "/css/**", "/font/**", "/ block/blocked");
        registry.addInterceptor(requestManyInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/login", "/captcha", "/js/**", "/css/**", "/font/**", "/ block/blocked");
        registry.addInterceptor(accessIPInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/login", "/captcha", "/js/**", "/css/**", "/font/**", "/ block/blocked");
    }
}

4. Request parameter verification and exception handling

Import dependencies

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

1. Three verification methods

  • Business layer verification
  • Validator + BindResult verification
  • Validator + automatically throws exceptions

2.Validator + automatically throw exceptions (use)

2.1 Add corresponding annotations to entity class fields
@Data
public class User implements Serializable {<!-- -->
@NotNull(message = "User ID cannot be empty")
private Long id;
@NotNull(message = "User account cannot be empty")
@Size(min = 6, max = 11, message = "The account length must be 6-11 characters")
private String account;
@NotNull(message = "User password cannot be empty")
@Size(min = 6, max = 11, message = "Password length must be 6-16 characters")
private String password;
@NotNull(message = "User mailbox cannot be empty")
@Email(message = "The email format is incorrect")
private String email;
}
2.2 Exception handling

When passing in the controller layer, add the annotation @Validated and pass in BindingResult bindingResult, and use bindingResult.getAllErrors(); to obtain the error information collection

@RestController
public class UserController {<!-- -->

    @RequestMapping("/insert")
    public String insert(@RequestBody @Validated User user BindingResult bindingResult ) {<!-- -->
        List<ObjectError> allErrors = bindingResult.getAllErrors();
         if (allErrors != null) {<!-- -->
             StringBuilder message = new StringBuilder();
             for (ObjectError oe : allErrors) {<!-- -->
                String msg = oe.getDefaultMessage();
                 message.append(msg).append(",");
             }
           return message.substring(0, message.length() - 1);
         }
        return "success";
    }

}

(After removing BindingResult, an exception will be automatically thrown. If an exception occurs, the business logic will not be executed.

3. Global exception handling

If you don’t want to manually get exceptions at the controller layer, use global exception handling

step:

  • Write a class and add annotation @RestControllerAdvice to the class
  • Write a method in the class, and add the annotation @ExceptionHandler here to write the bytecode object of the exception)
/**
* Global exception handling
* Use the form-data method to call the interface, and throw BindException when verifying exceptions.
* Use the json request body to call the interface, and the verification exception throws MethodArgumentNotValidException
* Single parameter verification exception throws ConstraintViolationException
*/
@RestControllerAdvice
public class GlobalExceptionHandler {<!-- -->
/**
* Handle exceptions thrown when JSON request body calls interface verification failure
*
* @param ex Exception occurred during program execution
* @return response entity object
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultVO<String>
handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {<!-- -->
List<FieldError> fieldErrors =
ex.getBindingResult().getFieldErrors();
List<String> collect = fieldErrors.stream().map(o ->
o.getDefaultMessage()).collect(Collectors.toList());
return ResultVO.failure(ResponseCode.VALIDATE_ERROR_CODE, "Parameter verification error
Error", collect.toString());
}
/**
* Process using form-data method to call the interface, and throw BindException when verifying exceptions
*
* @param ex Exception occurred during program execution
* @return response entity object
*/
@ExceptionHandler(BindException.class)
public ResultVO<String> handleBindException(BindException ex) {<!-- -->
List<FieldError> fieldErrors =
ex.getBindingResult().getFieldErrors();
List<String> collect = fieldErrors.stream().map(o ->
o.getDefaultMessage()).collect(Collectors.toList());
return ResultVO.failure(ResponseCode.VALIDATE_ERROR_CODE, "Parameter verification error
Error", collect.toString());
}
}