public class SwaggerController extends Controller { private static Ret swagger = null; /** * 首页的处理 */ public void index() { this.redirect("/lib/swagger/index.html"); } /** * */ public void json() throws NoSuchFieldException, IllegalAccessException { //https://github.com/swagger-api/swagger-ui if (!FrameworkConfig.SWAGGER_ENABLE && !FrameworkConfig.DEV_MODE) { this.renderJson(Ret.fail("禁止访问")); return; } if (swagger == null) { synchronized (this.getClass()) { if (swagger == null) { swagger = Ret.ok(); initSwagger(swagger); } } } this.renderJson(swagger); } private void initSwagger(Ret swagger) throws NoSuchFieldException, IllegalAccessException { Field actionMappingField = JFinal.class.getDeclaredField("actionMapping"); actionMappingField.setAccessible(true); ActionMapping actionMapping = (ActionMapping) actionMappingField.get(JFinal.me()); Field mappingField = ActionMapping.class.getDeclaredField("mapping"); mappingField.setAccessible(true); Map<String, Action> actions = (Map<String, Action>) mappingField.get(actionMapping); Map<? extends Class<? extends Controller>, List<Action>> controllerActionsMap = actions.stream().collect(Collectors.groupingBy(Action::getControllerClass)); List<Kv> tags = new ArrayList<>(); Map<String, Kv> paths = new LinkedHashMap<>(); for (Map.Entry<? extends Class<? extends Controller>, List<Action>> entry : controllerActionsMap.entrySet()) { Class<? extends Controller> controller = entry.getKey(); List<Action> controllerActions = entry.getValue(); RouteMapping routeMapping = controller.getAnnotation(RouteMapping.class); if (routeMapping == null) { continue; } String routePath = routeMapping.value().startsWith("/") ? routeMapping.value() : "/" + routeMapping.value(); if (controllerActions.stream().noneMatch(e -> e.getMethod().getAnnotation(ApiName.class) != null)) { continue; } tags.add(Kv.by("name", routePath).set("description", routeMapping.name())); controllerActions.sort((Action first, Action second) -> { String firstMethodName = first.getMethodName(); String secondMethodName = second.getMethodName(); return getMethodIndex(firstMethodName) - getMethodIndex(secondMethodName); }); for (Action action : controllerActions) { Method method = action.getMethod(); ApiName apiName = method.getAnnotation(ApiName.class); if (apiName == null) { continue; } Parameter[] paras = method.getParameters(); Class<?>[] parameterTypes = method.getParameterTypes(); List<Kv> parameters = new ArrayList<>(); ApiParams apiParams = method.getAnnotation(ApiParams.class); if (apiParams != null) { for (ApiParam apiParam : apiParams.value()) { Class<?> parameterType = apiParam.type(); if (parameterType.equals(PageVo.class)) { addPageParameter(parameters); continue; } String typeName = parameterType.getSimpleName().toLowerCase(); Kv parameter = Kv.by("name", apiParam.name()) .set("in", "formData") .set("description", apiParam.value()) .set("type", (typeName.equals(UploadFile.class.getSimpleName().toLowerCase()) || typeName.equals(UploadFileBean.class.getSimpleName().toLowerCase())) ? "file" : typeName); parameter.set("required", apiParam.required()); parameters.add(parameter); } } else { for (int i = 0; i < paras.length; i++) { Parameter para = paras[i]; Para paraAnno = para.getAnnotation(Para.class); String name = Optional.ofNullable(paraAnno).map(Para::value).filter(e -> !Para.NULL_VALUE.equals(e)).orElse(para.getName()); ApiParam apiParam = para.getAnnotation(ApiParam.class); Class<?> parameterType = parameterTypes[i]; if (parameterType.equals(PageVo.class)) { addPageParameter(parameters); continue; } String typeName = parameterType.getSimpleName().toLowerCase(); Kv parameter = Kv.by("name", name) .set("in", "formData") .set("description", apiParam == null ? name : apiParam.value()) .set("type", (typeName.equals(UploadFile.class.getSimpleName().toLowerCase()) || typeName.equals(UploadFileBean.class.getSimpleName().toLowerCase())) ? "file" : typeName); if (apiParam != null) { parameter.set("required", apiParam.required()); } parameters.add(parameter); } } Kv responses = Kv.by("200", new Kv()); Kv post = Kv.by("tags", Arrays.asList(routePath)) .set("description", apiName.value() + "(" + action.getActionKey() + ")") .set("parameters", parameters) .set("consumes", Arrays.asList("application/x-www-form-urlencoded")) .set("produces", Arrays.asList("application/json")) .set("responses", responses); Deprecated annotation = method.getAnnotation(Deprecated.class); if (annotation != null) { post.set("deprecated", true); } paths.put(action.getActionKey(), Kv.by("post", post)); } } tags.sort(Comparator.comparing(o -> o.getStr("name"))); List<String> descriptions = new ArrayList<>(); descriptions.add("token名称:" + FrameworkConst.TOKEN_NAME); swagger.set("schemes", Arrays.asList("HTTP", "HTTPS")) .set("swagger", "2.0") .set("basePath", "") .set("info", Kv.by("version", "3.0").set("title", "至道Api").set("description", StrKit.join(descriptions, ";"))) .set("tags", tags) .set("paths", paths) ; } private void addPageParameter(List<Kv> parameters) { Kv pageNumber = Kv.by("name", "offset") .set("in", "formData") .set("description", "数据偏移量") .set("type", Integer.class.getSimpleName().toLowerCase()); parameters.add(pageNumber); Kv pageSize = Kv.by("name", "limit") .set("in", "formData") .set("description", "每页显示的条数") .set("type", Integer.class.getSimpleName().toLowerCase()); parameters.add(pageSize); } private int getMethodIndex(String methodName) { if (methodName.startsWith("index")) { return 1; } if (methodName.startsWith("list")) { return 2; } if (methodName.startsWith("page")) { return 3; } if (methodName.startsWith("add")) { return 4; } if (methodName.startsWith("save")) { return 5; } if (methodName.startsWith("edit")) { return 6; } if (methodName.startsWith("update")) { return 7; } if (methodName.startsWith("delete")) { return 8; } return 10; } }
@RouteMapping(value = "/stayApply", name = "留宿申请", viewPath = "/_admin/stayApply") public class StayApplyController extends AdminBaseController { private static StayApplyServiceImpl stayApplyService = Aop.get(StayApplyServiceImpl.class); @ApiName("初始化参数") public void index() { Ret ret = Ret.ok(); this.renderJson(ret); } @ApiName("列表(分页)") public void list(PageVo pageVo) { Page<StayApply> page = stayApplyService.page(this.getUserLogin(), pageVo); this.renderJson(Ret.page(page)); } @ApiName("打开新增") public void add() { this.renderJson(Ret.ok()); } @ApiName("保存") //@Before(StayApplyValidator.class) public void save( @ApiParam(value = "表格id", required = true) Integer tableId, @ApiParam(value = "内容", required = true) String content, @ApiParam(value = "内容", required = true) Integer contentId, @ApiParam(value = "状态", required = true) Integer status, @ApiParam(value = "年份", required = false) Integer year, @ApiParam(value = "学期", required = false) Integer term, @ApiParam(value = "名称", required = true) String name, @ApiParam(value = "留宿开始时间", required = true) Date beginTime, @ApiParam(value = "留宿结束时间", required = true) Date endTime ) { StayApply stayApply = new StayApply(); stayApply.setTableId(tableId); stayApply.setContent(content); stayApply.setContentId(contentId); stayApply.setStatus(status); stayApply.setYear(year); stayApply.setTerm(term); stayApply.setName(name); stayApply.setBeginTime(beginTime); stayApply.setEndTime(endTime); stayApplyService.save(this.getUserLogin(), stayApply); this.renderJson(Ret.saveOk()); } @ApiName("打开编辑") public void edit(@ApiParam(value = "唯一身份id", required = true) Integer id) { StayApply stayApply = stayApplyService.findById(this.getUserLogin(), id); this.renderJson(Ret.ok().set("value", stayApply)); } @ApiName("更新") //@Before(StayApplyValidator.class) public void update( @ApiParam(value = "id", required = true) Integer id, @ApiParam(value = "表格id", required = true) Integer tableId, @ApiParam(value = "内容", required = true) String content, @ApiParam(value = "内容", required = true) Integer contentId, @ApiParam(value = "状态", required = true) Integer status, @ApiParam(value = "年份", required = false) Integer year, @ApiParam(value = "学期", required = false) Integer term, @ApiParam(value = "名称", required = true) String name, @ApiParam(value = "留宿开始时间", required = true) Date beginTime, @ApiParam(value = "留宿结束时间", required = true) Date endTime ) { StayApply stayApply = new StayApply(); stayApply.setId(id); stayApply.setTableId(tableId); stayApply.setContent(content); stayApply.setContentId(contentId); stayApply.setStatus(status); stayApply.setYear(year); stayApply.setTerm(term); stayApply.setName(name); stayApply.setBeginTime(beginTime); stayApply.setEndTime(endTime); stayApplyService.update(this.getUserLogin(),stayApply); this.renderJson(Ret.updateOK()); } @ApiName("删除") public void delete(@ApiParam(value = "唯一身份id", required = true) Integer id) { stayApplyService.delete(this.getUserLogin(), id); this.renderJson(Ret.deleteOk()); }
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ApiName { String value(); }
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface ApiParam { String value() default ""; boolean required() default false; String name() default ""; Class<?> type() default Void.class; }
如果需要非空判断,需要和JFinal的Interceptor结合,涉及细节较多,就不一一贴代码
for(String uri : JFinal.me().getAllActionKeys()){
Action action = JFinal.me().getAction(uri, null);
}