栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot加Lambda进行参数校验的一个通用方案

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot加Lambda进行参数校验的一个通用方案

一、背景

有这样一个业务场景,用户要申请一个功能,但是这个功能需要有校验多种资格。如果有些资格不满足需要给用户提示。

下面给出一个简单的通用方案。

这个方案的优势是,加新的校验非常容易,只需要写一个新的校验函数,添加校验条件即可,不至于把所有校验写在一大串代码里,导致可读性,可维护性都不好。

其实还可以更强大一些,可以在应用启动后获取某个注解或者继承自某个类或接口的所有校验类,然后校验时自动调用。

二、方法2.1 项目结构

2.2 pom文件


    4.0.0

    com.chujianyun
    lambdacheck
    1.0-SNAPSHOT

    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.6.RELEASE
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.projectlombok
            lombok
            1.18.8
        

        
        
            org.apache.commons
            commons-lang3
            3.9
        

    

    
        1.8
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

2.3 实体


import lombok.Data;@Datapublic class UserParam {    
    private Long userId;
}


结果

package com.chujianyun.entity.dto;import lombok.Data;import java.util.List;@Datapublic class UserCheckResultDTO {    
    private Boolean isValidUser;    
    private Boolean isInWhiteList;    
    private Boolean isHighLevel;    
    private List failedMessages;
}

上下文

import com.chujianyun.entity.dto.UserCheckResultDTO;import lombok.Data;@Datapublic class UserCheckContext {    private UserCheckResultDTO userCheckResultDTO = new UserCheckResultDTO();    // 可以携带其他结果}

2.4 核心封装
import com.chujianyun.entity.context.UserCheckContext;import com.chujianyun.entity.dto.UserCheckResultDTO;import com.chujianyun.entity.param.UserParam;import org.apache.commons.lang3.RandomUtils;import org.springframework.stereotype.Component;import java.util.ArrayList;import java.util.List;import java.util.function.Consumer;import java.util.function.Function;@Componentpublic class UserCheckFuntions {    // 注入校验所需的各种Bean

    public Function checkIsValid(UserParam userParam) {        return buildCheck(userCheckContext -> {
            UserCheckResultDTO userCheckResultDTO = userCheckContext.getUserCheckResultDTO();            // 模拟调用服务A,检查有效性
            boolean result = (userParam.getUserId() > 50);            if (result) {
                userCheckResultDTO.setIsValidUser(true);
            } else {
                userCheckResultDTO.setIsValidUser(false);
                addFailedMessage(userCheckResultDTO, "无效");
            }
        });
    }    public Function checkIsInWhiteList(UserParam userParam) {        return buildCheck(userCheckContext -> {
            UserCheckResultDTO userCheckResultDTO = userCheckContext.getUserCheckResultDTO();            // 模拟调用服务B,检查是否在白名单
            boolean result = (userParam.getUserId() > 500);            if (result) {
                userCheckResultDTO.setIsInWhiteList(true);
            } else {
                userCheckResultDTO.setIsInWhiteList(false);
                addFailedMessage(userCheckResultDTO, "不在白名单");
            }
        });
    }    public Function checkIsHighLevel(UserParam userParam) {        return buildCheck(userCheckContext -> {
            UserCheckResultDTO userCheckResultDTO = userCheckContext.getUserCheckResultDTO();            // 模拟调用服务C,检查是否高级用户
            boolean result = (userParam.getUserId() > 30);            if (result) {
                userCheckResultDTO.setIsHighLevel(true);
            } else {
                userCheckResultDTO.setIsHighLevel(false);
                addFailedMessage(userCheckResultDTO, "等级不够");
            }
        });
    }    public Function buildCheck(Consumer userCheckContextConsumer) {        return (userCheckContext) -> {
            userCheckContextConsumer.accept(userCheckContext);            return userCheckContext;
        };
    }    
    public void addFailedMessage(UserCheckResultDTO userCheckResultDTO, String message) {

        List failMessages = userCheckResultDTO.getFailedMessages();        if (failMessages == null) {
            failMessages = new ArrayList<>();
            userCheckResultDTO.setFailedMessages(failMessages);
        }
        failMessages.add(message);

    }
}



2.5 服务类
import com.chujianyun.entity.dto.UserCheckResultDTO;import com.chujianyun.entity.param.UserParam;public interface UserService {    UserCheckResultDTO checkUser(UserParam userParam);
}

实现

import com.chujianyun.component.UserCheckFuntions;import com.chujianyun.entity.context.UserCheckContext;import com.chujianyun.entity.dto.UserCheckResultDTO;import com.chujianyun.entity.param.UserParam;import com.chujianyun.service.UserService;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Servicepublic class UserServiceImpl implements UserService {    @Resource
    private UserCheckFuntions userCheckFuntions;    @Override
    public UserCheckResultDTO checkUser(UserParam userParam) {
        UserCheckContext userCheckContext = new UserCheckContext();        return userCheckFuntions.checkIsValid(userParam)
                .andThen(userCheckFuntions.checkIsInWhiteList(userParam))
                .andThen(userCheckFuntions.checkIsHighLevel(userParam))
                .apply(userCheckContext)
                .getUserCheckResultDTO();
    }
}

如果需要新增一个校验,则结果对象里加一个boolean属性,在Function里加一个校验函数,然后再实现类里加一个andThen的校验即可。

2.6 控制器


import com.chujianyun.entity.dto.UserCheckResultDTO;import com.chujianyun.entity.param.UserParam;import com.chujianyun.service.UserService;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import javax.annotation.Resource;@Controller@RequestMapping("/user")public class HelloController {    @Resource
    private UserService userService;    @PostMapping("/check")    public ResponseEntity checkUser(UserParam userParam) {        return new ResponseEntity<>(userService.checkUser(userParam), HttpStatus.OK);
    }
}


2.7 测试



三、总结

本文主要演示Lambda表达式在参数校验的特殊场景下的一个很有趣的应用,可读性,可拓展性更强。

给我们的启发是要灵活运用Java8提供的新的函数式类。


本文源码:https://github.com/chujianyun/lambdacheck

创作不易,如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。




转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/239486.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号