## 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