![JAR search and dependency download from the Maven repository](/logo.png)
com.cpj.swagger.APIParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cpj-swagger Show documentation
Show all versions of cpj-swagger Show documentation
cpj-swagger通过与swagger ui一起快速为您的web项目产生接口文档,并且支持在线测试接口。cpj-swagger可以很方便的与struts2、spring mvc、servlet集成使用
The newest version!
/*
* Copyright 2011-2017 CPJIT Group.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cpj.swagger;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSONWriter;
import com.cpj.swagger.annotation.API;
import com.cpj.swagger.annotation.APISchema;
import com.cpj.swagger.annotation.APISchemaPropertie;
import com.cpj.swagger.annotation.APISchemas;
import com.cpj.swagger.annotation.APITag;
import com.cpj.swagger.annotation.APITags;
import com.cpj.swagger.annotation.APIs;
import com.cpj.swagger.annotation.DataType;
import com.cpj.swagger.annotation.Item;
import com.cpj.swagger.annotation.Items;
import com.cpj.swagger.annotation.Param;
import com.cpj.swagger.util.ReflectUtils;
/**
* 接口解析器。
*
* 可以通过如下的方式来构建一个接口解析器:
*
*
* // 创建一个构建器
* String host = "127.0.0.1/app";
* String file = "c:/apis.json";
* String[] packageToScan = new String[]{"com.cpj.demo.api"};
* APIParser.Builder builder = new APIParser.Builder(host, file, packageToScan);
*
* // 设置可选参数
* builder.basePath("/");
*
* // 构建解析器
* APIParser parser = builder.build();
* // 解析
* parser.parse();
*
* 或者通过这种方式来构建一个接口解析器:
*
* APIParser.newInstance(props);
*
* @author yonghaun
* @since 1.0.0
*/
public final class APIParser implements APIParseable {
private final static Logger sLogger = Logger.getLogger(APIParser.class);
/**
* 创建一个解析器。
* @param props properties。
* @throws IOException
* @see APIParser.Builder
*/
public final static APIParser newInstance(Properties props) throws IOException {
String[] packageToScan = props.getProperty("packageToScan").split(";");
Builder builder = new Builder(props.getProperty("apiHost"), props.getProperty("apiFile"), packageToScan)
.basePath(props.getProperty("apiBasePath"))
.description(props.getProperty("apiDescription"))
.termsOfService(props.getProperty("termsOfService"))
.title(props.getProperty("apiTitle"))
.version(props.getProperty("apiVersion"))
.suffix(props.getProperty("suffix"));
return new APIParser(builder);
}
private APIParser(Builder builder) {
// 扫描class并生成文件所需要的参数
this.host = builder.host;
this.file = builder.file;
this.packageToScan = builder.packageToScan;
try {
packages = ReflectUtils.scanPackages(this.packageToScan, true);
} catch (Exception e) {
throw new IllegalStateException("扫描包信息失败", e);
}
this.basePath = builder.basePath;
this.suffix = builder.suffix;
// API文档信息
info = new APIDocInfo.Builder()
.contact(builder.contact)
.description(builder.description)
.license(builder.license)
.termsOfService(builder.termsOfService)
.title(builder.title)
.version(builder.version).build();
}
private String host;
private String basePath;
private String suffix = "";
/**
* @author yonghuan
*/
public static class Builder {
// required args
private String host;
private String file;
private List packageToScan;
/**
* 创建一个构建器。
*
* @param host
* API访问地址(不包含协议)
* @param file
* 解析产生的文件的存放路径
* @param packageToScan
* 待扫描的包
*/
public Builder(String host, String file, String[] packageToScan) {
this(host, file, Arrays.asList(packageToScan));
}
/**
* 创建一个构建器。
*
* @param host
* API访问地址(不包含协议)
* @param file
* 解析产生的文件的存放路径
* @param packageToScan
* 待扫描的包
*/
public Builder(String host, String file, List packageToScan) {
this.host = host;
this.file = file;
this.packageToScan = packageToScan;
}
/**
* 构建解析器。
*
* @return
*/
public APIParser build() {
return new APIParser(this);
}
private String basePath;
/**
* 设置API相对于host(API访问地址)的基路径
*
* @param val
* API相对于host(API访问地址)的基路径
* @return
*/
public Builder basePath(String val) {
this.basePath = val;
return this;
}
private String suffix = "";
/**
* 设置请求地址的后缀,如:.do、.action。
* @param suffix 请求地址的后缀
* @return
*/
public Builder suffix(String suffix) {
if(StringUtils.isNotBlank(suffix)) {
this.suffix = suffix;
}
return this;
}
private String description;
/**
* 设置API描述
* @param val
* API描述
* @return
*/
public Builder description(String val) {
this.description = val;
return this;
}
private String version;
/**
* 设置API版本
*
* @param val
* API版本
* @return
*/
public Builder version(String val) {
this.version = val;
return this;
}
private String title;
/**
* 设置API标题
*
* @param val
* API标题
* @return
*/
public Builder title(String val) {
this.title = val;
return this;
}
private String termsOfService;
/**
* 设置API开发团队的服务地址
*
* @param val
* API开发团队的服务地址
* @return
*/
public Builder termsOfService(String val) {
this.termsOfService = val;
return this;
}
private String contact;
/**
* 设置API开发团队的联系人
*
* @param val
* API开发团队的联系人
* @return
*/
public Builder contact(String val) {
this.contact = val;
return this;
}
private License license;
/**
* 设置API遵循的协议(如apahce开源协议)
*
* @param val
* API遵循的协议(如apahce开源协议)
* @return
*/
public Builder license(License val) {
try {
this.license = val.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
return this;
}
}
private APIDocInfo info;
private String file;
/**
* @return 解析完成后存放JSON数据的文件路径。
*/
public String getFile() {
return file;
}
private List packageToScan;
/**
* @return 待解析接口所在包
*/
public List getPackageToScan() {
return packageToScan;
}
private List packages;
private Map items;
@Override
public void parse() throws Exception {
/* 将结果写入文件 */
File f = new File(file);
sLogger.debug("生成的文件保存在=>" + f.getAbsolutePath());
JSONWriter writer = new JSONWriter(new FileWriter(f));
APIDoc api = (APIDoc) parseAndNotStore();
writer.writeObject(api);
writer.flush();
writer.close();
}
@Override
public Object parseAndNotStore() throws Exception {
APIDoc api = new APIDoc();
String[] schemes = new String[] { "http" };
api.setSchemes(schemes);
api.setHost(host);
api.setBasePath(basePath);
api.setInfo(info);
/* 解析全部item */
items = parseItem();
/* 解析全部tag */
List tags = parseTag();
api.setTags(tags);
/* 解析全部path */
Map> paths = parsePath();
api.setPaths(paths);
/* 解析全部definition */
Map definitions = parseDefinition();
api.setDefinitions(definitions);
return api;
}
private Map parseItem() throws Exception {
Map items = new HashMap();
for (Package pk : packages) {
Items items2 = pk.getAnnotation(Items.class);
if (items2 == null) {
continue;
}
Item[] is = items2.items();
for (Item i : is) {
items.put(i.value(), i);
}
}
return items;
}
/**
* url -> [ path ]
*
* @return
* @throws Exception
*/
private Map> parsePath() throws Exception,
IllegalArgumentException {
Map> paths = new HashMap>();
List> clazzs = ReflectUtils.scanClazzs(packageToScan, true); // 扫描包以获取包中的类
for(Class> clazz : clazzs) {
APIs apis = clazz.getAnnotation(APIs.class);
if(apis == null || apis.hide()) {
continue;
}
List apiMethods = scanAPIMethod(clazz);
for (Method method : apiMethods) {
API service = method.getAnnotation(API.class);
if(service.hide()) {
continue;
}
boolean isMultipart = hasMultipart(service);
String url;
if("".equals(service.value())) {
url = apis.value() + suffix;
} else {
url = apis.value() + "/" + service.value() + suffix;
}
Map path = paths.get(url); // get/psot/put/delete
if (path == null) {
path = new HashMap();
paths.put(url, path);
}
Path p = path.get(service.method());
if (p == null) {
p = new Path();
path.put(service.method().toLowerCase(), p);
}
if (StringUtils.isNotBlank(service.description())) {
p.setDescription(service.description());
} else {
p.setDescription(service.summary());
}
if (StringUtils.isNotBlank(service.operationId())) {
p.setOperationId(service.operationId());
} else { // 未设置operationId,
p.setOperationId(method.getName());
}
List tags = Arrays.asList(service.tags());
if(service.tags().length == 0) {
String ns = apis.value();
if(ns.startsWith("/")) {
ns = ns.substring(1);
}
tags = Arrays.asList(ns);
}
p.setTags(tags);
p.setSummary(service.summary());
if (isMultipart) { // multipart/form-data
p.setConsumes(Arrays.asList("multipart/form-data"));
} else {
p.setConsumes(Arrays.asList(service.consumes()));
}
p.setProduces(Arrays.asList(service.produces()));
p.setDeprecated(service.deprecated());
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy