• springboot根据参数,调用不同的service接口(策略模式)


    一、前言

    什么是策略模式?它的应用场景是什么?

    https://www.cnblogs.com/mylqm/p/15080706.html

    二、引入依赖

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.6</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-validation</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>

    三、项目结构图

    四、项目具体内容

    1.bean

    /**
     * @author ***
     * @title: AbstractRequestBean
     * @projectName strategy
     * @description TODO
     * @date 2022/2/28 13:22
     */
    @Data
    public abstract class AbstractRequestBean implements Serializable,VerifyModel {
    
        @NotBlank(message = "service不能为空")
        protected String service;
    
        @NotBlank(message = "param1不能为空")
        protected String param1;
    
        @NotBlank(message = "param2不能为空")
        protected String param2;
    
    
    
    }
    /**
     * @author ***
     * @title: RequestBean
     * @projectName strategy
     * @description 请求参数
     * @date 2022/2/28 13:30
     */
    public class RequestDto extends AbstractRequestBean implements Serializable {
    
    
    }
    /**
     * @author ***
     * @title: VerifyModle
     * @projectName strategy
     * @description TODO
     * @date 2022/2/28 13:20
     */
    public interface VerifyModel {
    
        String getParam1();
        String getParam2();
    
    }

    2.common

    /**
     * @author ***
     * @title: ResponseData
     * @projectName strategy
     * @description TODO
     * @date 2022/2/28 13:11
     */
    public class ResponseData<T> {
    
        private String code = "200";
        private String message = "成功";
        private T data;
    
        public static <T> ResponseData<T> ok(T data) {
            return new ResponseData<T>(data);
        }
    
        public static <T> ResponseData<T> ok() {
            return new ResponseData<>();
        }
    
        public static <T> ResponseData<T> fail() {
            return fail("500",null);
        }
    
        public static <T> ResponseData<T> fail(String message) {
            return fail("500",message);
        }
    
        public static <T> ResponseData<T> fail(String code,String message) {
            return new ResponseData<>(code,message);
        }
    
        public static <T> ResponseData<T> fail(String code,String message,T data) {
            return new ResponseData<T>(code,message,data);
        }
    
        public static <T> ResponseData<T> failByParam(String message) {
            return fail("500",message);
        }
    
        public ResponseData(T data) {
            super();
            this.data = data;
        }
    
        public ResponseData(String message) {
            super();
            this.message = message;
        }
    
        public ResponseData(String code,String message) {
            super();
            this.message = message;
            this.code = code;
        }
    
        public ResponseData(String code,String message,T data) {
            super();
            this.message = message;
            this.code = code;
            this.data = data;
        }
    
        public ResponseData() {
            super();
        }
    
        public boolean success(){
            return this.code.equals("200");
        }
    
        public String getCode() {
            return code;
        }
        public void setCode(String code) {
            this.code = code;
        }
        public String getMessage() {
            return message;
        }
        public void setMessage(String message) {
            this.message = message;
        }
        public T getData() {
            return data;
        }
        public void setData(T data) {
            this.data = data;
        }
    }

    3.constant

    /**
     * @author ***
     * @title: ServiceConstant
     * @projectName strategy
     * @description TODO
     * @date 2022/2/28 13:15
     */
    public interface ServiceConstant {
    
        String VERSION = "1.0.0";
    
        String TEST_ONE = "test.one";
    
    }
    /**
     * 校验结果
     */
    public class ValidationResult {
    
        //校验结果是否有错
        private boolean hasErrors;
    
        //校验错误信息
        private Map<String,String> errorMsg;
    
        public boolean isHasErrors() {
            return hasErrors;
        }
    
        public void setHasErrors(boolean hasErrors) {
            this.hasErrors = hasErrors;
        }
    
        public Map<String, String> getErrorMsg() {
            return errorMsg;
        }
    
        public void setErrorMsg(Map<String, String> errorMsg) {
            this.errorMsg = errorMsg;
        }
    
        @Override
        public String toString() {
            return "ValidationResult [hasErrors=" + hasErrors + ", errorMsg="
                    + errorMsg + "]";
        }
    }

    4.controller

    /**
     * @author ***
     * @title: RequestController
     * @projectName strategy
     * @description TODO
     * @date 2022/2/28 13:03
     */
    @RestController
    @RequestMapping("/test")
    public class RequestController {
    
        @Resource
        private Map<String, AbstractService<?, ?>> serviceMap;
    
        @RequestMapping(value = "/service", method = RequestMethod.POST)
        public ResponseData<?> converge(@RequestBody JSONObject jsonObject) throws Exception {
            String service = jsonObject.getString("service");
            AbstractService abstractService = serviceMap.get(service);
            if (abstractService == null) {
                return new ResponseData("500", "Please check your service param");
            }
            AbstractRequestBean request = JSONObject.toJavaObject(jsonObject, (Class<AbstractRequestBean>) abstractService.getType());
            //给上下文对象注入值
            Context context = ContextUtil.getContext();
            context.setService(request.getService());
            //参数校验
            ValidationResult result = ValidationUtil.validateEntity(request);
            if (result.isHasErrors()) {
                StringBuilder sbd = new StringBuilder();
                result.getErrorMsg().forEach((k, v) -> {
                    sbd.append(v).append("&");
                });
                return ResponseData.fail(sbd.deleteCharAt(sbd.length()-1).toString());
            }
            return abstractService.req(request);
        }
    }

    5.service

    /**
     * @param <S> 初始请求参数
     * @param <T> 业务请求参数
     * @author ***
     * @title: AbstractService
     * @projectName strategy
     * @description 抽象服务类
     * @date 2022/2/28 13:08
     */
    public abstract class AbstractService<S, T> {
    
        protected final Type type;
    
        protected AbstractService() {
            Type superClass = getClass().getGenericSuperclass();
            type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
        }
    
        public Type getType() {
            return type;
        }
    
        @Autowired
        private RequestService requestService;
    
    
        /**
         * 业务逻辑处理
         *
         * @param request 业务请求参数
         * @return 业务响应参数
         * @throws Exception
         */
        public abstract ResponseData<?> handle(T request) throws Exception;
    
        /**
         * 交易接口统一入口
         *
         * @param request 初始请求参数
         * @return 签名响应参数
         * @throws Exception
         */
        public ResponseData<?> req(S request) throws Exception {
            try {
                T tarReq = convert(request);
                verify(request);
                return handle(tarReq);
            } finally {
    
                ContextUtil.clear();
            }
        }
    
        /**
         * 入参校验
         *
         * @param request
         */
        private void verify(S request) {
            if (request != null) {
                VerifyModel verify = (VerifyModel) request;
                RequestDto requestDto = new RequestDto();
                requestDto.setParam1(verify.getParam1());
                requestDto.setParam2(verify.getParam2());
    
                ResponseData responseData = requestService.verify(requestDto);
                if (!"200".equals(responseData.getCode())) {
                    throw new RuntimeException(responseData.getMessage());
                }
            }
        }
    
        /**
         * 转化初始请求参数为业务请求参数
         *
         * @param s 初始请求参数
         * @return 业务请求参数
         */
        private T convert(S s) {
            Type superClass = getClass().getGenericSuperclass();
            Type targetType = ((ParameterizedType) superClass).getActualTypeArguments()[1];
            // 传入类型,与转化类型相同
            if (type == targetType) {
                return (T) s;
            }
            return null;
        }
    
    
    }
    /**
     * @author ***
     * @title: RequestService
     * @projectName strategy
     * @description TODO
     * @date 2022/2/28 12:36
     */
    @Service
    public class RequestService {
    
        public ResponseData verify(RequestDto requestDto) {
            String param1 = requestDto.getParam1();
            String param2 = requestDto.getParam2();
    
            if("1".equals(param1) && "2".equals(param2)){
                return ResponseData.fail("500");
            }
            return ResponseData.ok();
        }
    
        public ResponseData testOne(RequestDto request){
            String param1 = request.getParam1();
            String param2 = request.getParam2();
            System.out.println("param1:"+param1);
            System.out.println("param2:"+param2);
            return ResponseData.ok(request);
        }
    }
    /**
     * @author ***
     * @title: TestOneService
     * @projectName strategy
     * @description TODO
     * @date 2022/2/28 13:12
     */
    @Service(ServiceConstant.TEST_ONE)
    public class TestOneService extends AbstractService<RequestDto,RequestDto>{
    
        @Resource
        private RequestService requestService;
        @Override
        public ResponseData<?> handle(RequestDto request) throws Exception {
            return requestService.testOne(request);
        }
    }

    6.util

    /**
     * @author ***
     * @title: Context
     * @projectName strategy
     * @description TODO
     * @date 2022/2/28 12:47
     */
    @Data
    public class Context {
    
        /**
         * 版本号
         */
        private String version;
    
        /**
         * 服务类型
         */
        private String service;
    
    }
    /**
     * @author ***
     * @title: ContextUtil
     * @projectName strategy
     * @description TODO
     * @date 2022/2/28 12:46
     */
    public class ContextUtil {
    
        private ContextUtil() {
        }
    
        private static final Logger LOGGER = LoggerFactory.getLogger(ContextUtil.class);
    
        private static final ThreadLocal<Context> THREAD_LOCAL = ThreadLocal.withInitial(() -> new Context());
    
    
        public static Context getContext() {
            Context context = THREAD_LOCAL.get();
            LOGGER.info("getContext:{}", context);
            return context;
        }
    
        public static void clear() {
            LOGGER.info("clear:{}", THREAD_LOCAL.get());
            THREAD_LOCAL.remove();
        }
    
    
    }
    /**
     * 实体校验工具类
     * 
     */
    public class ValidationUtil {
    
        private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    
        /**
         * 校验实体
         *
         * @param obj
         * @param <T>
         * @return
         */
        public static <T> ValidationResult validateEntity(T obj) {
            ValidationResult result = new ValidationResult();
            Set<ConstraintViolation<T>> set = validator.validate(obj, Default.class);
            if (!CollectionUtils.isEmpty(set)) {
                result.setHasErrors(true);
                Map<String, String> errorMsg = new HashMap<String, String>();
                for (ConstraintViolation<T> cv : set) {
                    errorMsg.put(cv.getPropertyPath().toString(), cv.getMessage());
                }
                result.setErrorMsg(errorMsg);
            }
            return result;
        }
    
        /**
         * 校验属性
         *
         * @param obj
         * @param propertyName
         * @param <T>
         * @return
         */
        public static <T> ValidationResult validateProperty(T obj, String propertyName) {
            ValidationResult result = new ValidationResult();
            Set<ConstraintViolation<T>> set = validator.validateProperty(obj, propertyName, Default.class);
            if (!CollectionUtils.isEmpty(set)) {
                result.setHasErrors(true);
                Map<String, String> errorMsg = new HashMap<String, String>();
                for (ConstraintViolation<T> cv : set) {
                    errorMsg.put(propertyName, cv.getMessage());
                }
                result.setErrorMsg(errorMsg);
            }
            return result;
        }
    
    }

    7.写在最后

    关于springboot中@NotBlank注解使用不生效问题

    1)@NotBlank注解只能写在String类型

    2)入参的时候是否加了@Valid注解

    public String getUsername(@Valid User user){}

    3)如果使用的是validation-api ,还需要依赖 hibernate-validator 库

    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>2.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>6.0.13.Final</version>
    </dependency>

    4)使用JSON接收参数则需要自定义检验规则,详见【6.util.ValidationUtil 】,【4.controller.RequestController】

  • 相关阅读:
    Flask第31课——include标签
    flask第30篇——宏macro和import标签
    HTML第三课——css盒子
    HTML第二课——css【2】
    HTML第二课——css
    HTML第一课——基础知识普及【2】
    转一篇数据库面试题
    自创建数字证书,安装到浏览器
    【转】Base64算法详解
    【转】二维码生成原理
  • 原文地址:https://www.cnblogs.com/mylqm/p/15950652.html
Copyright © 2020-2023  润新知