java封装controllerModel,重写RequestMappingHandlerMapping自动生成增删改以及全属性查询接口

## controller通过继承一个model模板类,不需要编写基础的接口,效果如下:

没有编写任何接口:
在这里插入图片描述

成功调用:
在这里插入图片描述

1、公用模板类,拥有基础的增删改查、分页、条件查询等接口:

package com.zx.repository.controller;

import com.zx.repository.annotation.ModelMapping;
import com.zx.repository.service.MyRepository;
import com.zx.repository.util.MyBaseConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

/**
 * @author: zhaoxu
 * 公用controller
 */
public class MyControllerModel<S, E> implements ApplicationRunner {
    private static final Logger logger = LoggerFactory.getLogger(MyControllerModel.class);

    public MyRepository myRepository;

    private Type[] actualTypeArguments;

    private MyBaseConverter myBaseConverter = new MyBaseConverter();

    private ReflectUtil reflectUtil = new ReflectUtil();

    @RequestMapping(path = "", method = RequestMethod.POST)
    @ModelMapping
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public synchronized void add(@RequestBody S entityVO) {
        Object entity = myBaseConverter.convertSingleObject(entityVO, (Class<?>) actualTypeArguments[1]);
        try {
            reflectUtil.setValue(entity, "valid", 1);
        } catch (Exception e) {
            logger.warn("没有找到属性:valid");
        }

        myRepository.save(entity);
    }

    @RequestMapping(path = "", method = RequestMethod.PUT)
    @ModelMapping
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public void update(@RequestBody S entityVO) {
        Object entity = myBaseConverter.convertSingleObject(entityVO, (Class<?>) actualTypeArguments[1]);
        try {
            reflectUtil.setValue(entity, "valid", 1);
        } catch (Exception e) {
            logger.warn("没有找到属性:valid");
        }
        myRepository.save(entity);
    }

    @RequestMapping(path = "/{ids}", method = RequestMethod.DELETE)
    @ModelMapping
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public void deleteValid(@PathVariable String ids) {
        myRepository.deleteValid(ids);
    }

    @RequestMapping(path = "/{attr}/{condition}", method = RequestMethod.GET)
    @ModelMapping
    public Object findByAttr(@PathVariable String attr, @PathVariable String condition) {
        return myBaseConverter.convertSingleObject(myRepository.findOneByAttr(attr, condition), (Class<?>) actualTypeArguments[0]);
    }

    @RequestMapping(path = "/list/{attr}/{condition}", method = RequestMethod.GET)
    @ModelMapping
    public List findByAttrs(@PathVariable String attr,
                            @PathVariable String condition,
                            @RequestParam(name = "conditionType", required = false) String conditionType) {
        if (!StringUtils.isEmpty(conditionType) && Constants.LIST_TYPE.equals(conditionType)) {
            return myBaseConverter.convertMultiObjectToList((List<? extends Object>) myRepository.findByAttrs(attr, condition), (Class<?>) actualTypeArguments[0]);
        }
        return myBaseConverter.convertMultiObjectToList((List<? extends Object>)myRepository.findByAttr(attr, condition), (Class<?>) actualTypeArguments[0]);
    }

    @RequestMapping(path = "/findAll", method = RequestMethod.GET)
    @ModelMapping
    public List findAllByConditions(@RequestParam Map<String, Object> tableMap,
                                    @RequestParam(name = "excludeAttr", required = false) String excludeAttr) {
        String sortAttr;
        List<String> excludeAttrs;
        //取消模糊查询不为空并且排序不为空
        if (!StringUtils.isEmpty(excludeAttr) & (tableMap.get(Constants.SORTER) != null && !Constants.EMPTY_SORTER.equals(tableMap.get(Constants.SORTER)))) {
            excludeAttrs = Arrays.asList(excludeAttr.split(","));
            JSONObject sorter = JSONObject.parseObject(tableMap.get(Constants.SORTER).toString());
            Iterator<String> iterator = sorter.keySet().iterator();
            sortAttr = iterator.next();
            return myBaseConverter.convertMultiObjectToList((List<? extends Object>) myRepository.findByConditions(tableMap, excludeAttrs, sortAttr), (Class<?>) actualTypeArguments[0]);

        } else if (!StringUtils.isEmpty(excludeAttr)) {
            //取消模糊查询不为空
            excludeAttrs = Arrays.asList(excludeAttr.split(","));
            return myBaseConverter.convertMultiObjectToList((List<? extends Object>)myRepository.findByConditions(tableMap, excludeAttrs), (Class<?>) actualTypeArguments[0]);

        } else if ((tableMap.get(Constants.SORTER) != null && !Constants.EMPTY_SORTER.equals(tableMap.get(Constants.SORTER)))) {
            //排序不为空
            JSONObject sorter = JSONObject.parseObject(tableMap.get(Constants.SORTER).toString());
            Iterator<String> iterator = sorter.keySet().iterator();
            sortAttr = iterator.next();
            return myBaseConverter.convertMultiObjectToList((List<? extends Object>)myRepository.findByConditions(tableMap, null, sortAttr), (Class<?>) actualTypeArguments[0]);

        }

        return myBaseConverter.convertMultiObjectToList((List<? extends Object>)myRepository.findByConditions(tableMap), (Class<?>) actualTypeArguments[0]);
    }

    @RequestMapping(path = "/findByPage", method = RequestMethod.GET)
    @ModelMapping
    public Map findByPage(@RequestParam Map<String, Object> tableMap,
                                          @RequestParam(name = "excludeAttr", required = false) String excludeAttr) {
        String sortAttr;
        List<String> excludeAttrs;
        //取消模糊查询不为空并且排序不为空
        if (!StringUtils.isEmpty(excludeAttr) & (tableMap.get(Constants.SORTER) != null && !Constants.EMPTY_SORTER.equals(tableMap.get(Constants.SORTER)))) {
            excludeAttrs = Arrays.asList(excludeAttr.split(","));
            JSONObject sorter = JSONObject.parseObject(tableMap.get(Constants.SORTER).toString());
            Iterator<String> iterator = sorter.keySet().iterator();
            sortAttr = iterator.next();
            Page byPage = myRepository.findByPage(tableMap, excludeAttrs, sortAttr);

            return myBaseConverter.convertMultiObjectToMap(byPage, (Class<?>) actualTypeArguments[0]);
        } else if (!StringUtils.isEmpty(excludeAttr)) {
            //取消模糊查询不为空
            excludeAttrs = Arrays.asList(excludeAttr.split(","));
            Page byPage = myRepository.findByPage(tableMap, excludeAttrs);
            return myBaseConverter.convertMultiObjectToMap(byPage, (Class<?>) actualTypeArguments[0]);

        } else if (tableMap.get(Constants.SORTER) != null && !Constants.EMPTY_SORTER.equals(tableMap.get(Constants.SORTER))) {
            //排序不为空
            JSONObject sorter = JSONObject.parseObject(tableMap.get(Constants.SORTER).toString());
            Iterator<String> iterator = sorter.keySet().iterator();
            sortAttr = iterator.next();
            Page byPage = myRepository.findByPage(tableMap, null, sortAttr);
            return myBaseConverter.convertMultiObjectToMap(byPage, (Class<?>) actualTypeArguments[0]);

        }

        Page<E> byPage = myRepository.findByPage(tableMap);
        return myBaseConverter.convertMultiObjectToMap(byPage, (Class<?>) actualTypeArguments[0]);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Class<? extends MyControllerModel> aClass = this.getClass();
        //获取泛型类型
        Type genericSuperclass = aClass.getGenericSuperclass();
        ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        this.actualTypeArguments = actualTypeArguments;
        //查找Repository
        List<String> strings = Arrays.asList(aClass.getName().split("\\."));
        String controllerName = strings.get(strings.size() - 1);
        String serviceApi = Character.toLowerCase(controllerName.charAt(0)) + controllerName.split("Controller")[0].substring(1);
        this.myRepository = (MyRepository) SpringTool.getBean(serviceApi + "Repository");
    }
}

2、注解类ModelMapping

package com.zx.repository.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author : zhaoxu
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ModelMapping {
}

3、MyRequestMappingHandlerMapping.class

package com.zx.repository.mvc;

import com.zx.repository.annotation.ModelMapping;
import lombok.SneakyThrows;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.condition.RequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author : zhaoxu
 */
public class MyRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
    RequestMappingInfo.BuilderConfiguration config = new RequestMappingInfo.BuilderConfiguration();

    public MyRequestMappingHandlerMapping() {
    }

    @SneakyThrows
    @Override
    public void afterPropertiesSet() {
        Field config = this.getClass().getSuperclass().getDeclaredField("config");
        config.setAccessible(true);
        this.config = (RequestMappingInfo.BuilderConfiguration) config.get(this);
        super.afterPropertiesSet();
    }

    @Override
    protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) {
        RequestMappingInfo info = super.getMappingForMethod(method, handlerType);
        // 读取方法上的RequestMapping注解信息
        RequestMapping methodAnnotation = method.getDeclaredAnnotation(RequestMapping.class);
        if (method.isAnnotationPresent(ModelMapping.class)) {
            RequestCondition methodCondition = getCustomMethodCondition(method);
            info = createRequestMappingInfo(methodAnnotation, methodCondition);

            // 读取类上的RequestMapping注解信息
            RequestMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);

            // 生成类上的匹配条件,并合并方法上的
            List<String> strings = Arrays.asList(handlerType.getName().split("\\."));
            if (CollectionUtils.isEmpty(strings)) {
                return null;
            }
            String controllerName = strings.get(strings.size() - 1);
            String serviceApi = Character.toLowerCase(controllerName.charAt(0)) + controllerName.split("Controller")[0].substring(1);

            RequestCondition typeCondition = getCustomTypeCondition(handlerType);
            if (typeAnnotation != null) {
                // 生成类上的匹配条件,并合并方法上的
                info = createRequestMappingInfo(typeAnnotation, typeCondition).combine(RequestMappingInfo.paths(serviceApi).build().combine(info));
            } else {
                info = RequestMappingInfo.paths(serviceApi).build().combine(info);
            }
        }
        return info;
    }

    @Override
    protected RequestMappingInfo createRequestMappingInfo(RequestMapping requestMapping, RequestCondition customCondition) {
        return RequestMappingInfo
                .paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
                .methods(requestMapping.method())
                .params(requestMapping.params())
                .headers(requestMapping.headers())
                .consumes(requestMapping.consumes())
                .produces(requestMapping.produces())
                .mappingName(requestMapping.name())
                .customCondition(customCondition)
                .options(this.config)
                .build();
    }
}

4、配置类:

package com.zx.repository.mvc;

import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@Configuration
/**
 * @author : zhaoxu
 * 这个是自定义repository工厂
 */
@EnableJpaRepositories(basePackages = {"test.supcon"}, repositoryFactoryBeanClass = BaseJpaRepositoryFactoryBean.class)
public class MyJpaRepositoryConfig extends WebMvcConfigurationSupport {
    @Override
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        return new MyRequestMappingHandlerMapping();
    }
}

最后每一个controller继承就可以了,借口url路径为类上方的requestMapping+controller类名(比如TestController则为test)+模板类里面的路径

5、例子:

controller如下:
在这里插入图片描述

新增save方法的接口为:http://localhost:8889/oms/test

查找某一个实体方法findByAttr的接口为:http://localhost:8889/oms/test/name/李白

GitHub地址:https://github.com/zhao458114067/zx-util

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值