mirror of https://github.com/jeecgboot/jeecg-boot
openapi全量功能
parent
00252f392f
commit
f7f6d0ff88
|
@ -180,6 +180,8 @@ public class ShiroConfig {
|
|||
// 企业微信证书排除
|
||||
filterChainDefinitionMap.put("/WW_verify*", "anon");
|
||||
|
||||
filterChainDefinitionMap.put("/openapi/**", "anon");
|
||||
|
||||
// 添加自己的过滤器并且取名为jwt
|
||||
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
|
||||
//如果cloudServer为空 则说明是单体 需要加载跨域配置【微服务跨域切换】
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
package org.jeecg.modules.openapi.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiAuth;
|
||||
import org.jeecg.modules.openapi.generator.AKSKGenerator;
|
||||
import org.jeecg.modules.openapi.service.OpenApiAuthService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 9:54
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/openapi/auth")
|
||||
public class OpenApiAuthController extends JeecgController<OpenApiAuth, OpenApiAuthService> {
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param openApiAuth
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(OpenApiAuth openApiAuth, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
QueryWrapper<OpenApiAuth> queryWrapper = QueryGenerator.initQueryWrapper(openApiAuth, req.getParameterMap());
|
||||
Page<OpenApiAuth> page = new Page<>(pageNo, pageSize);
|
||||
IPage<OpenApiAuth> pageList = service.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param openApiAuth
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody OpenApiAuth openApiAuth) {
|
||||
service.save(openApiAuth);
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param openApiAuth
|
||||
* @return
|
||||
*/
|
||||
@PutMapping(value = "/edit")
|
||||
public Result<?> edit(@RequestBody OpenApiAuth openApiAuth) {
|
||||
service.updateById(openApiAuth);
|
||||
return Result.ok("修改成功!");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
service.removeById(id);
|
||||
return Result.ok("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
|
||||
this.service.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
OpenApiAuth openApiAuth = service.getById(id);
|
||||
return Result.ok(openApiAuth);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成AKSK
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("genAKSK")
|
||||
public Result<String[]> genAKSK() {
|
||||
return Result.ok(AKSKGenerator.genAKSKPair());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,463 @@
|
|||
package org.jeecg.modules.openapi.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fasterxml.classmate.ResolvedType;
|
||||
import com.fasterxml.classmate.TypeBindings;
|
||||
import com.fasterxml.classmate.TypeResolver;
|
||||
import com.fasterxml.classmate.types.ResolvedObjectType;
|
||||
import com.fasterxml.jackson.databind.type.ArrayType;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.openapi.entity.OpenApi;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiHeader;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiParam;
|
||||
import org.jeecg.modules.openapi.generator.PathGenerator;
|
||||
import org.jeecg.modules.openapi.service.OpenApiHeaderService;
|
||||
import org.jeecg.modules.openapi.service.OpenApiParamService;
|
||||
import org.jeecg.modules.openapi.service.OpenApiService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import springfox.documentation.schema.*;
|
||||
import springfox.documentation.service.*;
|
||||
import springfox.documentation.spring.web.DocumentationCache;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 9:11
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/openapi")
|
||||
public class OpenApiController extends JeecgController<OpenApi, OpenApiService> {
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
@Autowired
|
||||
private OpenApiParamService openApiParamService;
|
||||
@Autowired
|
||||
private OpenApiHeaderService openApiHeaderService;
|
||||
@Autowired
|
||||
private DocumentationCache documentationCache;
|
||||
@Autowired
|
||||
private TypeResolver typeResolver;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param openApi
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(OpenApi openApi, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
QueryWrapper<OpenApi> queryWrapper = QueryGenerator.initQueryWrapper(openApi, req.getParameterMap());
|
||||
Page<OpenApi> page = new Page<>(pageNo, pageSize);
|
||||
IPage<OpenApi> pageList = service.page(page, queryWrapper);
|
||||
for (OpenApi api : pageList.getRecords()) {
|
||||
api.setParams(openApiParamService.findByApiId(api.getId()));
|
||||
api.setHeaders(openApiHeaderService.findByApiId(api.getId()));
|
||||
}
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param openApi
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody OpenApi openApi) {
|
||||
if (service.save(openApi)) {
|
||||
if (!CollectionUtils.isEmpty(openApi.getHeaders())) {
|
||||
openApiHeaderService.saveBatch(openApi.getHeaders());
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(openApi.getParams())) {
|
||||
openApiParamService.saveBatch(openApi.getParams());
|
||||
}
|
||||
}
|
||||
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param openApi
|
||||
* @return
|
||||
*/
|
||||
@PutMapping(value = "/edit")
|
||||
public Result<?> edit(@RequestBody OpenApi openApi) {
|
||||
if (service.updateById(openApi)) {
|
||||
openApiHeaderService.deleteByApiId(openApi.getId());
|
||||
openApiParamService.deleteByApiId(openApi.getId());
|
||||
|
||||
if (!CollectionUtils.isEmpty(openApi.getHeaders())) {
|
||||
openApiHeaderService.saveBatch(openApi.getHeaders());
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(openApi.getParams())) {
|
||||
openApiParamService.saveBatch(openApi.getParams());
|
||||
}
|
||||
}
|
||||
return Result.ok("修改成功!");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
service.removeById(id);
|
||||
return Result.ok("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
|
||||
this.service.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
OpenApi OpenApi = service.getById(id);
|
||||
return Result.ok(OpenApi);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口调用
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/call/{path}", method = {RequestMethod.GET,RequestMethod.POST})
|
||||
public Result<?> call(@PathVariable String path, @RequestBody(required = false) String json, HttpServletRequest request) {
|
||||
OpenApi openApi = service.findByPath(path);
|
||||
if (Objects.isNull(openApi)) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("code", 404);
|
||||
result.put("data", null);
|
||||
return Result.error("失败", result);
|
||||
}
|
||||
List<OpenApiHeader> headers = openApiHeaderService.findByApiId(openApi.getId());
|
||||
|
||||
String url = openApi.getOriginUrl();
|
||||
String method = openApi.getRequestMethod();
|
||||
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
for (OpenApiHeader header : headers) {
|
||||
httpHeaders.put(header.getKey(), Lists.newArrayList(request.getHeader(header.getKey())));
|
||||
}
|
||||
|
||||
HttpEntity<String> httpEntity = new HttpEntity<>(json, httpHeaders);
|
||||
|
||||
return restTemplate.exchange(url, HttpMethod.resolve(method), httpEntity, Result.class, request.getParameterMap()).getBody();
|
||||
}
|
||||
|
||||
@GetMapping("/call/add")
|
||||
public void addSwagger() {
|
||||
Documentation documentation = documentationCache.documentationByGroup("default");
|
||||
|
||||
List<ApiListing> apis = new ArrayList<>();
|
||||
|
||||
Set<String> produces = new HashSet<>();
|
||||
produces.add("application/json");
|
||||
Set<String> consumes = new HashSet<>();
|
||||
consumes.add("application/json");
|
||||
|
||||
Set<String> tags = new HashSet<>();
|
||||
Tag tag = new Tag("openapi", "openapi");
|
||||
tags.add("openapi");
|
||||
Set<Tag> apiTags = new HashSet<>();
|
||||
apiTags.add(tag);
|
||||
documentation.getTags().add(tag);
|
||||
|
||||
Model resultModel = documentation.getApiListings().get("login-controller").get(0).getModels().get("接口返回对象«JSONObject»");
|
||||
|
||||
ModelRef stringModelRef = new ModelRef("string");
|
||||
|
||||
ResolvedType stringResolvedType = typeResolver.resolve(String.class);
|
||||
|
||||
|
||||
HashMap<String, ModelProperty> propertyMap = new HashMap<>();
|
||||
ModelProperty modelProperty = new ModelProperty("abc", stringResolvedType, "java.lang.String", 0, true, false, false, false, "姓名", null, null, null, null, null, new ArrayList<>());
|
||||
propertyMap.put("abc", modelProperty);
|
||||
ModelProperty modelProperty1 = new ModelProperty("bcd", stringResolvedType, "java.lang.String", 0, true, false, false, false, "姓名", null, null, null, null, null, new ArrayList<>());
|
||||
propertyMap.put("bcd", modelProperty1);
|
||||
|
||||
ResolvedType mapResolvedType = typeResolver.resolve(HashMap.class);
|
||||
|
||||
List<ModelReference> subTypes = new ArrayList<>();
|
||||
subTypes.add(stringModelRef);
|
||||
|
||||
Model bodyModel = new Model("path_body", "body", mapResolvedType, "java.util.HashMap", propertyMap, "请求体结构", "", "", subTypes, null, null);
|
||||
ModelRef bodyRef = new ModelRef("bodyModel", "bodyModel", null, null, "path_body");
|
||||
|
||||
Set<ResponseMessage> responseMessages = documentation.getApiListings().get("login-controller").get(0).getApis().get(2).getOperations().get(0).getResponseMessages();
|
||||
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
// header-->请求参数的获取:@RequestHeader()
|
||||
// query-->请求参数的获取:@RequestParam()
|
||||
// path-->请求参数的获取:@PathVariable()
|
||||
// body-->请求参数的获取:@RequestBody()
|
||||
// form(不常用)
|
||||
Parameter body = new Parameter("body",
|
||||
"请求体",
|
||||
"",
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
bodyRef,
|
||||
Optional.of(mapResolvedType),
|
||||
null,
|
||||
"body",
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
2147483647,
|
||||
null,
|
||||
new HashMap<>(),
|
||||
new ArrayList<>());
|
||||
|
||||
parameters.add(body);
|
||||
|
||||
Parameter parameter = new Parameter("name",
|
||||
"姓名",
|
||||
"张三",
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
stringModelRef,
|
||||
Optional.empty(),
|
||||
null,
|
||||
"query",
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
2147483647,
|
||||
null,
|
||||
new HashMap<>(),
|
||||
new ArrayList<>());
|
||||
|
||||
parameters.add(parameter);
|
||||
|
||||
ModelRef modelRef = new ModelRef(resultModel.getType().getTypeName(),
|
||||
resultModel.getQualifiedType(),
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
resultModel.getId());
|
||||
|
||||
Operation operation = new Operation(HttpMethod.resolve("GET"),
|
||||
"模拟第一个openapi接口",
|
||||
"模拟第一个openapi接口",
|
||||
modelRef,
|
||||
"abcUsingGET",
|
||||
0, tags, produces, consumes,
|
||||
new LinkedHashSet<>(),
|
||||
new ArrayList<>(),
|
||||
parameters,
|
||||
responseMessages,
|
||||
"false",
|
||||
false,
|
||||
new ArrayList<>());
|
||||
|
||||
List<Operation> operations = new ArrayList<>();
|
||||
operations.add(operation);
|
||||
|
||||
ApiDescription apiDescription = new ApiDescription("openapi",
|
||||
"/jeecg-boot/openapi/call/abc", "openapi", operations, false);
|
||||
|
||||
List<ApiDescription> apiList = new ArrayList<>();
|
||||
apiList.add(apiDescription);
|
||||
|
||||
Map<String, Model> responseModel = new HashMap<>();
|
||||
responseModel.put("接口返回对象«JSONObject»", resultModel);
|
||||
responseModel.put("bodyModel", bodyModel);
|
||||
|
||||
ApiListing api = new ApiListing("1.0",
|
||||
"/",
|
||||
"/openapi/call/abc",
|
||||
produces, consumes,
|
||||
"", new HashSet<>(), new ArrayList<>(), apiList, responseModel, "abc", 0, apiTags);
|
||||
|
||||
apis.add(api);
|
||||
|
||||
documentation.getApiListings().put("openapi", apis);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成接口路径
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("genPath")
|
||||
public Result<String> genPath() {
|
||||
Result<String> r = new Result<String>();
|
||||
r.setSuccess(true);
|
||||
r.setCode(CommonConstant.SC_OK_200);
|
||||
r.setResult(PathGenerator.genPath());
|
||||
return r;
|
||||
}
|
||||
|
||||
public void resetOpenapiSwagger() {
|
||||
List<OpenApi> openapis = service.list();
|
||||
Documentation documentation = documentationCache.documentationByGroup("default");
|
||||
List<ApiListing> apis = new ArrayList<>();
|
||||
|
||||
// --------------------- swagger common --------------
|
||||
|
||||
// http参数
|
||||
Set<String> produces = new HashSet<>();
|
||||
produces.add("application/json");
|
||||
Set<String> consumes = new HashSet<>();
|
||||
consumes.add("application/json");
|
||||
|
||||
// 标题栏
|
||||
Set<String> tags = new HashSet<>();
|
||||
Tag tag = new Tag("openapi", "openapi");
|
||||
tags.add("openapi");
|
||||
Set<Tag> apiTags = new HashSet<>();
|
||||
apiTags.add(tag);
|
||||
documentation.getTags().add(tag);
|
||||
ModelRef stringModelRef = new ModelRef("string", null, false);
|
||||
|
||||
// 响应文档
|
||||
Model resultModel = documentation.getApiListings().get("login-controller").get(0).getModels().get("接口返回对象«JSONObject»");
|
||||
Set<ResponseMessage> responseMessages = documentation.getApiListings().get("login-controller").get(0).getApis().get(2).getOperations().get(0).getResponseMessages();
|
||||
ModelRef modelRef = new ModelRef(resultModel.getType().getTypeName(),
|
||||
resultModel.getQualifiedType(),
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
resultModel.getId());
|
||||
// --------------------- swagger common --------------
|
||||
|
||||
for (OpenApi openapi : openapis) {
|
||||
openapi.setParams(openApiParamService.findByApiId(openapi.getId()));
|
||||
openapi.setHeaders(openApiHeaderService.findByApiId(openapi.getId()));
|
||||
|
||||
// 参数,包含header\query\path\body\form 五类数据
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
// header-->请求参数的获取:@RequestHeader()
|
||||
// query-->请求参数的获取:@RequestParam()
|
||||
// path-->请求参数的获取:@PathVariable()
|
||||
// body-->请求参数的获取:@RequestBody()
|
||||
// form(不常用)
|
||||
for (OpenApiHeader openApiHeader : openapi.getHeaders()) {
|
||||
Parameter parameter = new Parameter(openApiHeader.getKey(),
|
||||
openApiHeader.getNote(),
|
||||
openApiHeader.getDefaultValue(),
|
||||
openApiHeader.getIsBlank() == 1,
|
||||
false,
|
||||
true,
|
||||
stringModelRef,
|
||||
Optional.empty(),
|
||||
null,
|
||||
"header",
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
2147483647,
|
||||
null,
|
||||
new HashMap<>(),
|
||||
new ArrayList<>());
|
||||
parameters.add(parameter);
|
||||
}
|
||||
|
||||
for (OpenApiParam openApiParam : openapi.getParams()) {
|
||||
Parameter parameter = new Parameter(openApiParam.getKey(),
|
||||
openApiParam.getNote(),
|
||||
openApiParam.getDefaultValue(),
|
||||
openApiParam.getIsBlank() == 1,
|
||||
false,
|
||||
true,
|
||||
stringModelRef,
|
||||
Optional.empty(),
|
||||
null,
|
||||
"query",
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
2147483647,
|
||||
null,
|
||||
new HashMap<>(),
|
||||
new ArrayList<>());
|
||||
|
||||
parameters.add(parameter);
|
||||
}
|
||||
|
||||
Operation operation = new Operation(HttpMethod.resolve("GET"),
|
||||
"模拟第一个openapi接口",
|
||||
"模拟第一个openapi接口",
|
||||
modelRef,
|
||||
"abcUsingGET",
|
||||
0, tags, produces, consumes,
|
||||
new LinkedHashSet<>(),
|
||||
new ArrayList<>(),
|
||||
parameters,
|
||||
responseMessages,
|
||||
"false",
|
||||
false,
|
||||
new ArrayList<>());
|
||||
|
||||
List<Operation> operations = new ArrayList<>();
|
||||
operations.add(operation);
|
||||
|
||||
ApiDescription apiDescription = new ApiDescription("openapi",
|
||||
"/jeecg-boot/openapi/call/abc", "openapi", operations, false);
|
||||
|
||||
List<ApiDescription> apiList = new ArrayList<>();
|
||||
apiList.add(apiDescription);
|
||||
|
||||
Map<String, Model> responseModel = new HashMap<>();
|
||||
responseModel.put("接口返回对象«JSONObject»", resultModel);
|
||||
|
||||
ApiListing api = new ApiListing("1.0",
|
||||
"/",
|
||||
"/openapi/call/abc",
|
||||
produces, consumes,
|
||||
"", new HashSet<>(), new ArrayList<>(), apiList, responseModel, "abc", 0, apiTags);
|
||||
|
||||
apis.add(api);
|
||||
}
|
||||
|
||||
documentation.getApiListings().put("openapi", apis);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.jeecg.modules.openapi.controller;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @date 2024/12/20 14:04
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/openapi/demo")
|
||||
public class OpenApiIndexController {
|
||||
|
||||
@GetMapping("index")
|
||||
@IgnoreAuth
|
||||
public Result<Map<String, String>> index() {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
result.put("first", "Hello World");
|
||||
return Result.ok(result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package org.jeecg.modules.openapi.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiRecord;
|
||||
import org.jeecg.modules.openapi.service.OpenApiRecordService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 9:57
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/openapi/record")
|
||||
public class OpenApiRecordController extends JeecgController<OpenApiRecord, OpenApiRecordService> {
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param openApiRecord
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(OpenApiRecord openApiRecord, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
QueryWrapper<OpenApiRecord> queryWrapper = QueryGenerator.initQueryWrapper(openApiRecord, req.getParameterMap());
|
||||
Page<OpenApiRecord> page = new Page<>(pageNo, pageSize);
|
||||
IPage<OpenApiRecord> pageList = service.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param openApiRecord
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody OpenApiRecord openApiRecord) {
|
||||
service.save(openApiRecord);
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param openApiRecord
|
||||
* @return
|
||||
*/
|
||||
@PutMapping(value = "/edit")
|
||||
public Result<?> edit(@RequestBody OpenApiRecord openApiRecord) {
|
||||
service.updateById(openApiRecord);
|
||||
return Result.ok("修改成功!");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
service.removeById(id);
|
||||
return Result.ok("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
|
||||
this.service.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.ok("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
OpenApiRecord openApiRecord = service.getById(id);
|
||||
return Result.ok(openApiRecord);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package org.jeecg.modules.openapi.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 接口表
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class OpenApi implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 接口名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 请求方式,如POST、GET
|
||||
*/
|
||||
private String requestMethod;
|
||||
|
||||
/**
|
||||
* 对外开放的相对接口路径
|
||||
*/
|
||||
private String requestUrl;
|
||||
|
||||
/**
|
||||
* IP 黑名单
|
||||
*/
|
||||
private String blackList;
|
||||
|
||||
/**
|
||||
* 请求头列表
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<OpenApiHeader> headers;
|
||||
|
||||
/**
|
||||
* 请求参数列表
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<OpenApiParam> params;
|
||||
|
||||
/**
|
||||
* 目前仅支持json
|
||||
*/
|
||||
private String body;
|
||||
|
||||
/**
|
||||
* 原始接口路径
|
||||
*/
|
||||
private String originUrl;
|
||||
|
||||
/**
|
||||
* 状态(1:正常 2:废弃 )
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 删除状态(0,正常,1已删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private Integer delFlag;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package org.jeecg.modules.openapi.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 权限表
|
||||
* @date 2024/12/10 9:38
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class OpenApiAuth implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5933153354153738498L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 受权名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* access key
|
||||
*/
|
||||
private String ak;
|
||||
|
||||
/**
|
||||
* secret key
|
||||
*/
|
||||
private String sk;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package org.jeecg.modules.openapi.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 请求头表
|
||||
* @date 2024/12/10 14:37
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class OpenApiHeader implements Serializable {
|
||||
private static final long serialVersionUID = 5032708503120184683L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 接口ID
|
||||
*/
|
||||
private String apiId;
|
||||
|
||||
/**
|
||||
* key
|
||||
*/
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 是否必填(0:否,1:是)
|
||||
*/
|
||||
private Integer isBlank;
|
||||
|
||||
/**
|
||||
* 默认值
|
||||
*/
|
||||
private String defaultValue;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
private String note;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package org.jeecg.modules.openapi.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* query部分参数表
|
||||
* @date 2024/12/10 14:37
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class OpenApiParam implements Serializable {
|
||||
private static final long serialVersionUID = -6174831468578022357L;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 接口ID
|
||||
*/
|
||||
private String apiId;
|
||||
|
||||
/**
|
||||
* key
|
||||
*/
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 是否必填(0:否,1:是)
|
||||
*/
|
||||
private Integer isBlank;
|
||||
|
||||
/**
|
||||
* 默认值
|
||||
*/
|
||||
private String defaultValue;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
private String note;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.jeecg.modules.openapi.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
*
|
||||
* @date 2024/12/19 17:41
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class OpenApiPermission implements Serializable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 接口ID
|
||||
*/
|
||||
private String apiId;
|
||||
|
||||
/**
|
||||
* 认证ID
|
||||
*/
|
||||
private String apiAuthId;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.jeecg.modules.openapi.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 调用记录表
|
||||
* @date 2024/12/10 9:41
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class OpenApiRecord implements Serializable {
|
||||
private static final long serialVersionUID = -5870384488947863579L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 接口ID
|
||||
*/
|
||||
private String apiId;
|
||||
|
||||
/**
|
||||
* 调用ID
|
||||
*/
|
||||
private String callAuthId;
|
||||
|
||||
/**
|
||||
* 调用时间
|
||||
*/
|
||||
private Date callTime;
|
||||
|
||||
/**
|
||||
* 耗时
|
||||
*/
|
||||
private Long usedTime;
|
||||
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
private Date responseTime;
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
package org.jeecg.modules.openapi.filter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.modules.openapi.entity.OpenApi;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiAuth;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiRecord;
|
||||
import org.jeecg.modules.openapi.service.OpenApiAuthService;
|
||||
import org.jeecg.modules.openapi.service.OpenApiPermissionService;
|
||||
import org.jeecg.modules.openapi.service.OpenApiRecordService;
|
||||
import org.jeecg.modules.openapi.service.OpenApiService;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2024/12/19 16:55
|
||||
*/
|
||||
@Slf4j
|
||||
public class ApiAuthFilter implements Filter {
|
||||
|
||||
private OpenApiRecordService openApiRecordService;
|
||||
private OpenApiAuthService openApiAuthService;
|
||||
private OpenApiPermissionService openApiPermissionService;
|
||||
private OpenApiService openApiService;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
long startTime = System.currentTimeMillis();
|
||||
Date callTime = new Date();
|
||||
|
||||
HttpServletRequest request = (HttpServletRequest)servletRequest;
|
||||
String ip = request.getRemoteAddr();
|
||||
|
||||
String appkey = request.getHeader("appkey");
|
||||
String signature = request.getHeader("signature");
|
||||
String timestamp = request.getHeader("timestamp");
|
||||
|
||||
OpenApi openApi = findOpenApi(request);
|
||||
|
||||
// IP 黑名单核验
|
||||
checkBlackList(openApi, ip);
|
||||
|
||||
// 签名核验
|
||||
checkSignValid(appkey, signature, timestamp);
|
||||
|
||||
OpenApiAuth openApiAuth = openApiAuthService.getByAppkey(appkey);
|
||||
// 认证信息核验
|
||||
checkSignature(appkey, signature, timestamp, openApiAuth);
|
||||
// 业务核验
|
||||
checkPermission(openApi, openApiAuth);
|
||||
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
long endTime = System.currentTimeMillis();
|
||||
|
||||
OpenApiRecord record = new OpenApiRecord();
|
||||
record.setApiId(openApi.getId());
|
||||
record.setCallAuthId(openApiAuth.getId());
|
||||
record.setCallTime(callTime);
|
||||
record.setUsedTime(endTime - startTime);
|
||||
record.setResponseTime(new Date());
|
||||
openApiRecordService.save(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
ServletContext servletContext = filterConfig.getServletContext();
|
||||
WebApplicationContext applicationContext = (WebApplicationContext)servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
|
||||
this.openApiService = applicationContext.getBean(OpenApiService.class);
|
||||
this.openApiRecordService = applicationContext.getBean(OpenApiRecordService.class);
|
||||
this.openApiAuthService = applicationContext.getBean(OpenApiAuthService.class);
|
||||
this.openApiPermissionService = applicationContext.getBean(OpenApiPermissionService.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* IP 黑名单核验
|
||||
* @param openApi
|
||||
* @param ip
|
||||
*/
|
||||
protected void checkBlackList(OpenApi openApi, String ip) {
|
||||
if (!StringUtils.hasText(openApi.getBlackList())) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> blackList = Arrays.asList(openApi.getBlackList().split(","));
|
||||
if (blackList.contains(ip)) {
|
||||
throw new JeecgBootException("目标接口限制IP[" + ip + "]进行访问,IP已记录,请停止访问");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名验证
|
||||
* @param appkey
|
||||
* @param signature
|
||||
* @param timestamp
|
||||
* @return
|
||||
*/
|
||||
protected void checkSignValid(String appkey, String signature, String timestamp) {
|
||||
if (!StringUtils.hasText(appkey)) {
|
||||
throw new JeecgBootException("appkey为空");
|
||||
}
|
||||
if (!StringUtils.hasText(signature)) {
|
||||
throw new JeecgBootException("signature为空");
|
||||
}
|
||||
if (!StringUtils.hasText(timestamp)) {
|
||||
throw new JeecgBootException("timastamp时间戳为空");
|
||||
}
|
||||
if (!timestamp.matches("[0-9]*")) {
|
||||
throw new JeecgBootException("timastamp时间戳不合法");
|
||||
}
|
||||
if (System.currentTimeMillis() - Long.parseLong(timestamp) > 5 * 60 * 1000) {
|
||||
throw new JeecgBootException("signature签名已过期(超过五分钟)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证信息核验
|
||||
* @param appKey
|
||||
* @param signature
|
||||
* @param timestamp
|
||||
* @param openApiAuth
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
protected void checkSignature(String appKey, String signature, String timestamp, OpenApiAuth openApiAuth) {
|
||||
if(openApiAuth==null){
|
||||
throw new JeecgBootException("不存在认证信息");
|
||||
}
|
||||
|
||||
if(!appKey.equals(openApiAuth.getAk())){
|
||||
throw new JeecgBootException("appkey错误");
|
||||
}
|
||||
|
||||
if (!signature.equals(md5(appKey + openApiAuth.getSk() + timestamp))) {
|
||||
throw new JeecgBootException("signature签名错误");
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkPermission(OpenApi openApi, OpenApiAuth openApiAuth) {
|
||||
List<OpenApiPermission> permissionList = openApiPermissionService.findByAuthId(openApiAuth.getId());
|
||||
|
||||
boolean hasPermission = false;
|
||||
for (OpenApiPermission permission : permissionList) {
|
||||
if (permission.getApiId().equals(openApi.getId())) {
|
||||
hasPermission = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasPermission) {
|
||||
throw new JeecgBootException("该appKey未授权当前接口");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String 返回类型
|
||||
* @Title: MD5
|
||||
* @Description: 【MD5加密】
|
||||
*/
|
||||
protected static String md5(String sourceStr) {
|
||||
String result = "";
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(sourceStr.getBytes("utf-8"));
|
||||
byte[] hash = md.digest();
|
||||
int i;
|
||||
StringBuffer buf = new StringBuffer(32);
|
||||
for (int offset = 0; offset < hash.length; offset++) {
|
||||
i = hash[offset];
|
||||
if (i < 0) {
|
||||
i += 256;
|
||||
}
|
||||
if (i < 16) {
|
||||
buf.append("0");
|
||||
}
|
||||
buf.append(Integer.toHexString(i));
|
||||
}
|
||||
result = buf.toString();
|
||||
} catch (Exception e) {
|
||||
log.error("sign签名错误", e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected OpenApi findOpenApi(HttpServletRequest request) {
|
||||
String uri = request.getRequestURI();
|
||||
String path = uri.substring(uri.lastIndexOf("/") + 1);
|
||||
return openApiService.findByPath(path);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.jeecg.modules.openapi.filter;
|
||||
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @date 2024/12/19 17:09
|
||||
*/
|
||||
@Configuration
|
||||
public class ApiFilterConfig {
|
||||
|
||||
/**
|
||||
*
|
||||
* @Description: 【注册api加密过滤器】
|
||||
*/
|
||||
@Bean
|
||||
public FilterRegistrationBean<ApiAuthFilter> authFilter() {
|
||||
FilterRegistrationBean<ApiAuthFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(new ApiAuthFilter());
|
||||
registration.setName("apiAuthFilter");
|
||||
registration.addUrlPatterns("/openapi/call/*");
|
||||
return registration;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package org.jeecg.modules.openapi.generator;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* AK/SK生成器
|
||||
*/
|
||||
public class AKSKGenerator {
|
||||
private static final String CHAR_POOL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
private static final int AK_LENGTH = 16; // Adjust as per requirements
|
||||
private static final int SK_LENGTH = 32;
|
||||
|
||||
public static String[] genAKSKPair() {
|
||||
return new String[]{genAK(), genSK()};
|
||||
}
|
||||
|
||||
public static String genAK() {
|
||||
return "ak-" + generateRandomString(AK_LENGTH);
|
||||
}
|
||||
|
||||
public static String genSK() {
|
||||
return generateRandomString(SK_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
private static String generateRandomString(int length) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
StringBuilder sb = new StringBuilder(length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
sb.append(CHAR_POOL.charAt(random.nextInt(CHAR_POOL.length())));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.jeecg.modules.openapi.generator;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 10:00
|
||||
*/
|
||||
@UtilityClass
|
||||
public class PathGenerator {
|
||||
|
||||
// Base62字符集
|
||||
private static final String BASE62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
/**
|
||||
* 生成随机路径
|
||||
* @return
|
||||
*/
|
||||
public static String genPath() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
Random random = new Random();
|
||||
for (int i=0; i<8; i++) {
|
||||
result.append(BASE62.charAt(random.nextInt(62)));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.jeecg.modules.openapi.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiAuth;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 9:49
|
||||
*/
|
||||
@Mapper
|
||||
public interface OpenApiAuthMapper extends BaseMapper<OpenApiAuth> {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.jeecg.modules.openapi.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiHeader;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 14:47
|
||||
*/
|
||||
@Mapper
|
||||
public interface OpenApiHeaderMapper extends BaseMapper<OpenApiHeader> {
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.jeecg.modules.openapi.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.jeecg.modules.openapi.entity.OpenApi;
|
||||
|
||||
@Mapper
|
||||
public interface OpenApiMapper extends BaseMapper<OpenApi> {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.jeecg.modules.openapi.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiParam;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 14:48
|
||||
*/
|
||||
@Mapper
|
||||
public interface OpenApiParamMapper extends BaseMapper<OpenApiParam> {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.jeecg.modules.openapi.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
||||
|
||||
/**
|
||||
* @date 2024/12/19 17:43
|
||||
*/
|
||||
@Mapper
|
||||
public interface OpenApiPermissionMapper extends BaseMapper<OpenApiPermission> {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.jeecg.modules.openapi.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiRecord;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 9:50
|
||||
*/
|
||||
@Mapper
|
||||
public interface OpenApiRecordMapper extends BaseMapper<OpenApiRecord> {
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.jeecg.modules.openapi.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiAuth;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 9:50
|
||||
*/
|
||||
public interface OpenApiAuthService extends IService<OpenApiAuth> {
|
||||
OpenApiAuth getByAppkey(String appkey);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.jeecg.modules.openapi.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiHeader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 14:48
|
||||
*/
|
||||
public interface OpenApiHeaderService extends IService<OpenApiHeader> {
|
||||
|
||||
boolean deleteByApiId(String apiId);
|
||||
|
||||
List<OpenApiHeader> findByApiId(String apiId);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.jeecg.modules.openapi.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 14:49
|
||||
*/
|
||||
public interface OpenApiParamService extends IService<OpenApiParam> {
|
||||
boolean deleteByApiId(String apiId);
|
||||
|
||||
List<OpenApiParam> findByApiId(String apiId);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package org.jeecg.modules.openapi.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2024/12/19 17:44
|
||||
*/
|
||||
public interface OpenApiPermissionService extends IService<OpenApiPermission> {
|
||||
List<OpenApiPermission> findByAuthId(String authId);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.jeecg.modules.openapi.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiRecord;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 9:51
|
||||
*/
|
||||
public interface OpenApiRecordService extends IService<OpenApiRecord> {
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.jeecg.modules.openapi.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.openapi.entity.OpenApi;
|
||||
|
||||
public interface OpenApiService extends IService<OpenApi> {
|
||||
OpenApi findByPath(String path);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.jeecg.modules.openapi.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiAuth;
|
||||
import org.jeecg.modules.openapi.mapper.OpenApiAuthMapper;
|
||||
import org.jeecg.modules.openapi.service.OpenApiAuthService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 9:51
|
||||
*/
|
||||
@Service
|
||||
public class OpenApiAuthServiceImpl extends ServiceImpl<OpenApiAuthMapper, OpenApiAuth> implements OpenApiAuthService {
|
||||
@Override
|
||||
public OpenApiAuth getByAppkey(String appkey) {
|
||||
return baseMapper.selectOne(Wrappers.lambdaUpdate(OpenApiAuth.class).eq(OpenApiAuth::getAk, appkey), false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.jeecg.modules.openapi.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiHeader;
|
||||
import org.jeecg.modules.openapi.mapper.OpenApiHeaderMapper;
|
||||
import org.jeecg.modules.openapi.service.OpenApiHeaderService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 14:49
|
||||
*/
|
||||
@Service
|
||||
public class OpenApiHeaderServiceImpl extends ServiceImpl<OpenApiHeaderMapper, OpenApiHeader> implements OpenApiHeaderService {
|
||||
@Override
|
||||
public boolean deleteByApiId(String apiId) {
|
||||
return baseMapper.delete(Wrappers.lambdaUpdate(OpenApiHeader.class).eq(OpenApiHeader::getApiId, apiId)) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OpenApiHeader> findByApiId(String apiId) {
|
||||
return baseMapper.selectList(Wrappers.lambdaQuery(OpenApiHeader.class).eq(OpenApiHeader::getApiId, apiId));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.jeecg.modules.openapi.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiParam;
|
||||
import org.jeecg.modules.openapi.mapper.OpenApiParamMapper;
|
||||
import org.jeecg.modules.openapi.service.OpenApiParamService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 14:50
|
||||
*/
|
||||
@Service
|
||||
public class OpenApiParamServiceImpl extends ServiceImpl<OpenApiParamMapper, OpenApiParam> implements OpenApiParamService {
|
||||
@Override
|
||||
public boolean deleteByApiId(String apiId) {
|
||||
return baseMapper.delete(Wrappers.lambdaUpdate(OpenApiParam.class).eq(OpenApiParam::getApiId, apiId)) > 0;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OpenApiParam> findByApiId(String apiId) {
|
||||
return baseMapper.selectList(Wrappers.lambdaQuery(OpenApiParam.class).eq(OpenApiParam::getApiId, apiId));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.jeecg.modules.openapi.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
||||
import org.jeecg.modules.openapi.mapper.OpenApiPermissionMapper;
|
||||
import org.jeecg.modules.openapi.service.OpenApiPermissionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2024/12/19 17:44
|
||||
*/
|
||||
@Service
|
||||
public class OpenApiPermissionServiceImpl extends ServiceImpl<OpenApiPermissionMapper, OpenApiPermission> implements OpenApiPermissionService {
|
||||
@Override
|
||||
public List<OpenApiPermission> findByAuthId(String authId) {
|
||||
return baseMapper.selectList(Wrappers.lambdaQuery(OpenApiPermission.class).eq(OpenApiPermission::getApiAuthId, authId));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.jeecg.modules.openapi.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.openapi.entity.OpenApiRecord;
|
||||
import org.jeecg.modules.openapi.mapper.OpenApiRecordMapper;
|
||||
import org.jeecg.modules.openapi.service.OpenApiRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @date 2024/12/10 9:53
|
||||
*/
|
||||
@Service
|
||||
public class OpenApiRecordServiceImpl extends ServiceImpl<OpenApiRecordMapper, OpenApiRecord> implements OpenApiRecordService {
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.jeecg.modules.openapi.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.openapi.entity.OpenApi;
|
||||
import org.jeecg.modules.openapi.mapper.OpenApiMapper;
|
||||
import org.jeecg.modules.openapi.service.OpenApiService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class OpenApiServiceImpl extends ServiceImpl<OpenApiMapper, OpenApi> implements OpenApiService {
|
||||
@Override
|
||||
public OpenApi findByPath(String path) {
|
||||
return baseMapper.selectOne(Wrappers.lambdaQuery(OpenApi.class).eq(OpenApi::getRequestUrl, path), false);
|
||||
}
|
||||
}
|
|
@ -163,9 +163,9 @@ spring:
|
|||
slow-sql-millis: 5000
|
||||
datasource:
|
||||
master:
|
||||
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
|
||||
url: jdbc:mysql://172.16.10.227:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: root
|
||||
password: root@2023
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
# 多数据源配置
|
||||
#multi-datasource1:
|
||||
|
@ -176,9 +176,9 @@ spring:
|
|||
#redis 配置
|
||||
redis:
|
||||
database: 0
|
||||
host: 127.0.0.1
|
||||
host: 172.16.10.227
|
||||
port: 6379
|
||||
password: ''
|
||||
password: 'Whdsj@redis0523'
|
||||
#mybatis plus 设置
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath*:org/jeecg/**/xml/*Mapper.xml
|
||||
|
|
Loading…
Reference in New Issue