yml配置文件语法-拦截器-请求参数校验

本文详细介绍了如何在SpringBoot项目中使用YML配置文件,配置对象、Map数据,以及环境变量映射。同时涵盖了拦截器的使用和请求参数的校验及异常处理策略。
摘要由CSDN通过智能技术生成

一.yml配置文件语法

1.配置自定义数据

1.1 配置普通数据

语法:key: value

name: kaifamiao
1.2配置对象数据

语法1:

key:

key1: value1;

key2: value2;

person:
  name: zhangsan
  age: 19

语法2:

key: {key1: value1,key: value2}

person1: {name: lisi,age: 21}
1.3配置Map数据

同配置对象数据

1.4配置数组(list,set)数据

语法1:

key:

— value1

— value2

student:
  - maqi
  - sunliu

语法2:

key: [value1,value2]

student1: [phr,lzh,zk]

集合中的元素可以是对象

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

二.配置问件与配置类的映射关系

1.使用注解@Value

例如yml问件如下:

name: kaifamiao
person:
  name: zhangsan
  age: 19	

获取数据的代码则如下:

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 {
  
    //获取单个属性
    @Value("${name}")
    private String name;
    //获取对象属性
    @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.使用Environment

yml文件如下:

person:
  name: zhangsan
  age: 19	

获取数据:

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 {
    //直接注入 Environment对象environment 使用environment.getProperty()方法取值
    @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.使用@ConfigurationProperties(prefix = "配置文件中的key的前缀")注解

yml文件

person:
  name: zhangsan
  age: 19	

实体类

package com.lzh.mybatis_springboot.model;

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

@Data//为什么要写这个注解,是因为使用注解@ConfigurationProperties在获取数据的时候需要set方法
//person是指配置文件中的key的前缀
@ConfigurationProperties(prefix = "person")
@Component
public class Person {
    private String name;
    private int age;
}

获取数据

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());
    }
}

注意:使用@ConfigurationProperties方式可以进行配置文件与实体字段的自动映射,但需要字段

必须提供set方法才可以,而使用@Value注解修饰的字段不需要提供set方法

三.拦截器

拦截器不会拦截静态资源,Spring Boot 的默认静态目录为 resources/static,该目录下的静态页面、

JSCSS、图片等不会被拦截,当然这也要看实现过程,有些情况下可能会被拦截.

1.拦截器使用步骤:

1.1定义拦截器

创建一个类实现HandlerInterceptor接口,重写三个方法

preHandle(……) 方法

该方法的执行时机是,当某个 URL 已经匹配到对应的 Controller 中的某个方法,且在这个方法执行之

前。所以 preHandle(……) 方法可以决定是否将请求放行,这是通过返回值来决定的,返回 true 则放

行,返回 false 则不会向后执行。

postHandle(……) 方法

该方法的执行时机是,当某个 URL 已经匹配到对应的 Controller 中的某个方法,且在执行完了该方法,

但是在 DispatcherServlet 视图渲染之前。所以在这个方法中有个 ModelAndView 参数,可以在此做一

些修改动作。

afterCompletion(……) 方法

顾名思义,该方法是在整个请求处理完成后(包括视图渲染)执行,这时做一些资源的清理工作,这个

方法只有在 preHandle(……) 被成功执行后并且返回 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;

/**
 * 实现HandlerInterceptor接口 重写方法
 * 实现未登录用户不可以访问登录页面之外的其他页面
 */
@Component
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();//获取Session,因为用户的登录信息时存在session里面的
        Object user = session.getAttribute("loginUser");//使用该方法获取存在session域中的值
        if(user==null){//如果为空,证明session中没有该用户,重定向到登录页面
            response.sendRedirect(request.getContextPath()+"/user/login");
            return false;
        }
        System.out.println("用户登录了,放行");
        return  true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse
         response, Object handler, ModelAndView modelAndView) throws Exception {
        	 log.info("执行完方法之后进执行(Controller方法调用之后),但是此时还没进行视图渲
       		染");
}
	@Override
	public void afterCompletion(HttpServletRequest request,
		HttpServletResponse response, Object handler, Exception ex) throws Exception{
		log.info("整个请求都处理完咯,DispatcherServlet也渲染了对应的视图咯,此时我可
			以做一些清理的工作了");
	}
}

1.2配置拦截器

实现 WebMvcConfigurer 接口,重写addInterceptors()方法

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;

/**
 * 配置拦截器
 */
@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);//配置拦截器对象
//        InterceptorRegistration pathPatterns = interceptor.addPathPatterns("/*");
//        //哪些资源可以进入拦截器
//        InterceptorRegistration excluded = interceptor.excludePathPatterns("/css");
//        //哪些资源不进入拦截器
//        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");
    }
}

四.请求参数校验及其异常处理

导入依赖

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

1.三种校验方式

  • 业务层校验
  • Validator + BindResult 校验
  • Validator + 自动抛出异常

2.Validator + 自动抛出异常(使用)

2.1在实体类字段上加上对应的注解
@Data
public class User implements Serializable {
@NotNull(message = "用户id不能为空")
private Long id;
@NotNull(message = "用户账号不能为空")
@Size(min = 6, max = 11, message = "账号长度必须是6-11个字符")
private String account;
@NotNull(message = "用户密码不能为空")
@Size(min = 6, max = 11, message = "密码长度必须是6-16个字符")
private String password;
@NotNull(message = "用户邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
}
2.2异常处理

在controller层传入的时候,加上注解@Validated ,并传入BindingResult bindingResult,用bindingResult.getAllErrors();获取错误信息集合

@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";
    }

}

(去掉BindingResult后会自动引发异常,异常发生了自然而然就不会执行业务逻辑

3.全局异常处理

如果不想在controller层手动获取异常,使用全局异常处理

步骤:

  • 写一个类,类上加上注解@RestControllerAdvice
  • 类中写一个方法,方法上加上注解@ExceptionHandler这里写异常的的字节码对象)
/**
* 全局异常处理
* 使用form-data方式调用接口,校验异常抛出 BindException
* 使用 json 请求体调用接口,校验异常抛出 MethodArgumentNotValidException
* 单个参数校验异常抛出ConstraintViolationException
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理 json 请求体调用接口校验失败抛出的异常
*
* @param ex 程序执行发生的异常
* @return 响应实体对象
*/
@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, "参数校验错
误", collect.toString());
}
/**
* 处理使用 form-data 方式调用接口,校验异常抛出 BindException
*
* @param ex 程序执行发生的异常
* @return 响应实体对象
*/
@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, "参数校验错
误", collect.toString());
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值