
cn.bestwu.api.test.GenApiJson Maven / Gradle / Ivy
package cn.bestwu.api.test;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 生成 api.json api说明
*
* 例子
* {
* "httpMethod": "GET",
* "name": "检查版本号",
* "params": [
* ],
* "resourceType": "基本",
* "results": [
* "id",
* "versiontext",
* "isForce",
* "time",
* "versionCode",
* "versionName",
* "downloadLink"
* ],
* "url": "/clientVersions"
* },
*
* @author Peter Wu
*/
public class GenApiJson {
public static String gen(Class> clazz) throws IntrospectionException {
String apiJson = "";
if (clazz.isAnnotationPresent(Controller.class) || clazz
.isAnnotationPresent(RestController.class)) {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
String gen = gen(method);
if (gen != null) {
apiJson += gen + ",\n";
}
}
}
return apiJson;
}
public static String gen(Method method) throws IntrospectionException {
RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
if (methodAnnotation != null) {
String url = "";
String resourceType = "";
String name = methodAnnotation.name();
Class> declaringClass = method.getDeclaringClass();
RequestMapping classRequestMapping = declaringClass
.getAnnotation(RequestMapping.class);
if (classRequestMapping != null) {
String[] value = classRequestMapping.value();
url = value.length > 0 ? value[0] : "";
resourceType = classRequestMapping.name();
}
String[] value = methodAnnotation.value();
url += value.length > 0 ? value[0] : "";
String httpMethod = "";
RequestMethod[] requestMethods = methodAnnotation.method();
for (int i = 0; i < requestMethods.length; i++) {
httpMethod += requestMethods[i];
if (i < requestMethods.length - 1) {
httpMethod += ",";
}
}
String $regex = "\\$\\{.*:?(.*?)\\}";
Pattern $pattern = Pattern.compile($regex);
Matcher $matcher = $pattern.matcher(url);
while ($matcher.find()) {
String group = $matcher.group();
String param = group.replaceAll("\\$\\{.*:(.*?)\\}", "$1");
url = url.replace(group, param);
}
String regex = "\\{(.*?)\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(url);
int i = 0;
String urlParamsStr = "";
List urlParams = new ArrayList<>();
while (matcher.find()) {
String group = matcher.group();
String param = group.replaceAll(regex, "$1");
urlParams.add(param);
if (i > 0) {
urlParamsStr += "&\n\t\t";
}
urlParamsStr += "\"" + urlParams.get(i) + "\"";
i++;
}
if ("".equals(urlParamsStr)) {
urlParamsStr = "\"\"";
}
DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
String[] paramNames = parameterNameDiscoverer.getParameterNames(method);
Map params = new LinkedHashMap<>(paramNames.length);
for (String paramName : paramNames) {
params.put(paramName, "");
}
Class>[] parameterTypes = method.getParameterTypes();
Set keySet = params.keySet();
String[] keys = keySet.toArray(new String[keySet.size()]);
for (int j = parameterTypes.length - 1; j >= 0; j--) {
MethodParameter methodParameter = new MethodParameter(method, j);
Class> parameterType = methodParameter.getParameterType();
String key = keys[j];
if (ServletRequest.class.isAssignableFrom(parameterType) || ServletResponse.class
.isAssignableFrom(parameterType) || Map.class.isAssignableFrom(parameterType)) {
params.remove(key);
} else if (!isJavaNativeClass(parameterType) && !parameterType.isEnum()) {
params.remove(key);
BeanInfo beanInfo = Introspector.getBeanInfo(parameterType, Object.class);
for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
String propertyName = propertyDescriptor.getName();
Object paramVal = propertyDescriptor.getValue(propertyName);
params.put(propertyName, paramVal == null ? "" : String.valueOf(paramVal));
}
} else {
PathVariable pathVariable = methodParameter
.getParameterAnnotation(PathVariable.class);
if (pathVariable != null) {
params.remove(key);
} else {
RequestParam requestParam = methodParameter
.getParameterAnnotation(RequestParam.class);
if (requestParam != null) {
params.put(key, requestParam.defaultValue());
}
}
}
}
String paramsStr = "";
int j = 0;
for (String key : keySet) {
paramsStr += "\t\t\"" + key + "\": \"" + params.get(key) + "\"";
if (j < keySet.size() - 1) {
paramsStr += ",\n";
} else {
paramsStr += "\n";
}
j++;
}
String results = "{\n\t},";
return "{\n"
+ "\t\"httpMethod\": \"" + httpMethod + "\",\n"
+ "\t\"name\": \"" + name + "\",\n"
+ "\t\"desc\": \"\",\n"
+ "\t\"params\": {\n"
+ paramsStr
+ "\t},\n"
+ "\t\"resourceType\": \"" + resourceType + "\",\n"
+ "\t\"results\": "
+ results
+ "\n"
+ "\t\"urlParams\": " + urlParamsStr + ",\n"
+ "\t\"url\": \"" + url + "\"\n"
+ "}";
}
return null;
}
public static boolean isJavaNativeClass(final Class> clz) {
return clz != null && clz.getClassLoader() == null;
}
}