Server:同步eclipse版至idea版

This commit is contained in:
TommyLemon 2017-02-26 16:10:18 +08:00
parent 1e20c4d223
commit 1a1195da4e
14 changed files with 733 additions and 144 deletions

View File

@ -364,11 +364,11 @@ public class RequestParser {
}
String path = getPath(parentPath, name);
QueryConfig config = StringUtil.isNumer(name) ? parentConfig : null;
boolean nameIsNumber = StringUtil.isNumer(name);
QueryConfig config = nameIsNumber ? parentConfig : null;
if (config == null) {
config = new QueryConfig(requestMethod, name);
}
boolean nameIsNumber = StringUtil.isNumer(name);
final int position = nameIsNumber ? Integer.valueOf(0 + StringUtil.getNumber(name)) : 0;
boolean containRelation = false;

View File

@ -0,0 +1,140 @@
package zuo.biao.apijson;
public class Column {
private int count;//获得所有列的数目及实际列数
private String name;//获得指定列的列名
private String value;//获得指定列的列值
private int type;//获得指定列的数据类型
private String typeName;//获得指定列的数据类型名
private String catalogName;//所在的Catalog名字
private String className;//对应数据类型的类
private int displaySize;//在数据库中类型的最大字符个数
private String label;//默认的列的标题
private String schemaName;//获得列的模式
private int precision;//某列类型的精确度(类型的长度)
private int scale;//小数点后的位数
private String table;//获取某列对应的表名
private boolean autoInctement;// 是否自动递增
private boolean isCurrency;//在数据库中是否为货币型
private int nullable;//是否为空
private boolean readOnly;//是否为只读
private boolean searchable;//能否出现在where中
public Column() {
super();
}
public Column(String name) {
this();
setName(name);
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public String getCatalogName() {
return catalogName;
}
public void setCatalogName(String catalogName) {
this.catalogName = catalogName;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public int getDisplaySize() {
return displaySize;
}
public void setDisplaySize(int displaySize) {
this.displaySize = displaySize;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getSchemaName() {
return schemaName;
}
public void setSchemaName(String schemaName) {
this.schemaName = schemaName;
}
public int getPrecision() {
return precision;
}
public void setPrecision(int precision) {
this.precision = precision;
}
public int getScale() {
return scale;
}
public void setScale(int scale) {
this.scale = scale;
}
public String getTable() {
return table;
}
public void setTable(String table) {
this.table = table;
}
public boolean isAutoInctement() {
return autoInctement;
}
public void setAutoInctement(boolean autoInctement) {
this.autoInctement = autoInctement;
}
public boolean getIsCurrency() {
return isCurrency;
}
public void setIsCurrency(boolean isCurrency) {
this.isCurrency = isCurrency;
}
public int getNullable() {
return nullable;
}
public void setNullable(int nullable) {
this.nullable = nullable;
}
public boolean getReadOnly() {
return readOnly;
}
public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
public boolean getSearchable() {
return searchable;
}
public void setSearchable(boolean searchable) {
this.searchable = searchable;
}
}

View File

@ -119,6 +119,9 @@ public class JSON {
* @return
*/
public static String toJSONString(Object obj) {
if (obj instanceof String) {
return (String) obj;
}
try {
return com.alibaba.fastjson.JSON.toJSONString(obj);
} catch (Exception e) {
@ -133,6 +136,9 @@ public class JSON {
* @return
*/
public static String toJSONString(Object obj, SerializerFeature... features) {
if (obj instanceof String) {
return (String) obj;
}
try {
return com.alibaba.fastjson.JSON.toJSONString(obj, features);
} catch (Exception e) {
@ -146,7 +152,14 @@ public class JSON {
* @return
*/
public static String format(String json) {
return toJSONString(parseObject(json), SerializerFeature.PrettyFormat);
return format(parseObject(json));
}
/**格式化显示更好看
* @param object
* @return
*/
public static String format(JSONObject object) {
return toJSONString(object, SerializerFeature.PrettyFormat);
}

View File

@ -0,0 +1,23 @@
/*Copyright ©2016 TommyLemon(https://github.com/TommyLemon/APIJSON)
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 zuo.biao.apijson;
/**请求方法对应org.springframework.web.bind.annotation.RequestMethod多出一个POST_GET方法
* @author Lemon
*/
public enum RequestMethod {
GET, POST_GET, POST, PUT, DELETE
}

View File

@ -3,6 +3,7 @@ package zuo.biao.apijson;
public class Table {
public static final String ID = "id";
public static final String USER_ID = "userId";
public static final String NAME = "name";
public static final String SEX = "sex";
public static final String PHONE = "phone";

View File

@ -17,6 +17,8 @@ package zuo.biao.apijson.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import zuo.biao.apijson.server.sql.AccessVerifier;
/**application
* @author Lemon
*/
@ -25,5 +27,7 @@ public class APIJSONApplication {
public static void main(String[] args) {
SpringApplication.run(APIJSONApplication.class, args);
AccessVerifier.init();
}
}

View File

@ -14,7 +14,7 @@ limitations under the License.*/
package zuo.biao.apijson.server;
import org.springframework.web.bind.annotation.RequestMethod;
import zuo.biao.apijson.RequestMethod;
/**mock test of client
* @author Lemon

View File

@ -29,34 +29,34 @@ public class Controller {
@RequestMapping("get/{request}")
public String get(@PathVariable String request) {
return new RequestParser(RequestMethod.GET).parse(request);
return new RequestParser(zuo.biao.apijson.RequestMethod.GET).parse(request);
}
@RequestMapping(value="post", method = RequestMethod.POST)
public String post(@RequestBody String request) {
return new RequestParser(RequestMethod.POST).parse(request);
}
/**用POST方法GET数据request和response都非明文浏览器看不到用于对安全性要求高的GET请求
* @param request
* @return
*/
@RequestMapping(value="post_get", method = RequestMethod.POST)
public String post_get(@RequestBody String request) {
return new RequestParser(RequestMethod.GET).parse(request);
return new RequestParser(zuo.biao.apijson.RequestMethod.POST_GET).parse(request);
}
@RequestMapping(value="post", method = RequestMethod.POST)
public String post(@RequestBody String request) {
return new RequestParser(zuo.biao.apijson.RequestMethod.POST).parse(request);
}
/**以下接口继续用POST接口是为了客户端方便只需要做getpost请求也可以改用实际对应的方法
* postput方法名可以改为addupdate等更客户端容易懂的名称
*/
@RequestMapping(value="delete", method = RequestMethod.POST)
public String delete(@RequestBody String request) {
return new RequestParser(RequestMethod.DELETE).parse(request);
}
*/
@RequestMapping(value="put", method = RequestMethod.POST)
public String put(@RequestBody String request) {
return new RequestParser(RequestMethod.PUT).parse(request);
return new RequestParser(zuo.biao.apijson.RequestMethod.PUT).parse(request);
}
@RequestMapping(value="delete", method = RequestMethod.POST)
public String delete(@RequestBody String request) {
return new RequestParser(zuo.biao.apijson.RequestMethod.DELETE).parse(request);
}
}

View File

@ -19,11 +19,10 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.springframework.web.bind.annotation.RequestMethod;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import zuo.biao.apijson.JSON;
import zuo.biao.apijson.RequestMethod;
import zuo.biao.apijson.StringUtil;
import zuo.biao.apijson.Table;
@ -40,8 +39,9 @@ public class QueryConfig {
private String columns;
private String values;
private Map<String, Object> where;
private int limit;
private int count;
private int page;
private String sort;
private int position;
public QueryConfig(RequestMethod method) {
@ -65,19 +65,19 @@ public class QueryConfig {
setColumns(columns);
setValues(values);
}
public QueryConfig(RequestMethod method, int limit, int page) {
public QueryConfig(RequestMethod method, int count, int page) {
this(method);
setLimit(limit);
setCount(count);
setPage(page);
}
public RequestMethod getMethod() {
return method;
}
public QueryConfig setMethod(RequestMethod method) {
if (method == null) {
method = RequestMethod.GET;
}
return method;
}
public QueryConfig setMethod(RequestMethod method) {
this.method = method;
return this;
}
@ -99,7 +99,7 @@ public class QueryConfig {
return this;
}
private String getColumnsString() {
switch (method) {
switch (getMethod()) {
case POST:
return StringUtil.isNotEmpty(columns, true) ? "(" + columns + ")" : "";
default:
@ -114,7 +114,7 @@ public class QueryConfig {
this.id = id;
return this;
}
public String getValues() {
return values;
}
@ -143,11 +143,12 @@ public class QueryConfig {
this.where = where;
return this;
}
public int getLimit() {
return limit;
public int getCount() {
return count;
}
public QueryConfig setLimit(int limit) {
this.limit = limit;
public QueryConfig setCount(int count) {
this.count = count;
return this;
}
public int getPage() {
@ -157,6 +158,13 @@ public class QueryConfig {
this.page = page;
return this;
}
public String getSort() {
return sort;
}
public QueryConfig setSort(String sort) {
this.sort = sort;
return this;
}
public int getPosition() {
return position;
}
@ -169,36 +177,44 @@ public class QueryConfig {
* @return
*/
public String getLimitString() {
return getLimitString(page, limit);// + 1);
return getLimitString(getPage(), getCount());// + 1);
}
/**获取限制数量
* @param limit
* @return
*/
public static String getLimitString(int page, int limit) {
return limit <= 0 ? "" : " limit " + page*limit + ", " + limit;
public static String getLimitString(int page, int count) {
return count <= 0 ? "" : " limit " + page*count + ", " + count;
}
/**获取筛选方法
* @return
*/
public String getWhereString() {
return getWhereString(where);
return getWhereString(getMethod(), getWhere());
}
/**获取筛选方法
* @param where
* @return
*/
public static String getWhereString(Map<String, Object> where) {
public static String getWhereString(RequestMethod method, Map<String, Object> where) {
Set<String> set = where == null ? null : where.keySet();
if (set != null && set.size() > 0) {
if (RequestParser.isGetMethod(method) == false && method != RequestMethod.POST_GET
&& where.containsKey(Table.ID) == false) {
throw new IllegalArgumentException("请设置" + Table.ID + "");
}
String whereString = " where ";
Object value;
for (String key : set) {
//避免筛选到全部 value = key == null ? null : where.get(key);
if (key == null) {
continue;
}
whereString += (key + "='" + where.get(key) + "' and ");
value = where.get(key);
whereString += (key + (value instanceof JSONArray
? getInString(((JSONArray)value).toArray()) : "='" + value + "'") + " and ");
}
if (whereString.endsWith("and ")) {
whereString = whereString.substring(0, whereString.length() - "and ".length());
@ -209,6 +225,22 @@ public class QueryConfig {
}
return "";
}
/**where key in ('key0', 'key1', ... )
* @param in
* @return in ('key0', 'key1', ... )
*/
public static String getInString(Object[] in) {
if (in == null || in.length <= 0) {
return "";
}
String inString = "";
for (int i = 0; i < in.length; i++) {
inString += ((i > 0 ? "," : "") + "'" + in[i] + "'");
}
return " in (" + inString + ") ";
}
/**获取筛选方法
* @return
*/
@ -223,7 +255,7 @@ public class QueryConfig {
Set<String> set = where == null ? null : where.keySet();
if (set != null && set.size() > 0) {
if (where.containsKey(Table.ID) == false) {
return "";
throw new IllegalArgumentException("请设置" + Table.ID + "");
}
String setString = " set ";
for (String key : set) {
@ -270,9 +302,11 @@ public class QueryConfig {
request.remove(KEY_COLUMNS);
Map<String, Object> transferredRequest = new HashMap<String, Object>();
Object value;
for (String key : set) {
if (JSON.parseObject(request.getString(key)) == null) {//非key-value
transferredRequest.put(key, request.get(key));
value = request.get(key);
if (value instanceof JSONObject == false) {//只允许常规Object
transferredRequest.put(key, value);//一样 instanceof JSONArray ? JSON.toJSONString(value) : value);
}
}
config.setWhere(transferredRequest);

View File

@ -24,11 +24,10 @@ import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.springframework.web.bind.annotation.RequestMethod;
import com.alibaba.fastjson.JSONObject;
import zuo.biao.apijson.JSON;
import zuo.biao.apijson.RequestMethod;
import zuo.biao.apijson.StringUtil;
import zuo.biao.apijson.Table;
import zuo.biao.apijson.server.sql.AccessVerifier;
@ -80,7 +79,7 @@ public class RequestParser {
return newErrorResult(e);
}
System.out.println("\n\n\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n " + TAG + requestMethod.name()
+ "/parseResponse request = " + request);
+ "/parseResponse request = " + request);
relationMap = new HashMap<String, String>();
parseRelation = false;
@ -106,7 +105,7 @@ public class RequestParser {
requestObject = AccessVerifier.removeAccessInfo(requestObject);
if (isGetMethod(requestMethod)) {
if (isGetMethod(requestMethod) || requestMethod == RequestMethod.POST_GET) {
requestObject = error == null ? extendSuccessResult(requestObject)
: extendResult(requestObject, 206, "未完成全部请求:\n" + error.getMessage());
}
@ -217,7 +216,7 @@ public class RequestParser {
if (object == null || object.isEmpty()) {
throw new UnsupportedOperationException("非GET请求必须是服务端允许的操作 \n " + error);
}
object = object.getJSONObject("structure");//解决返回值套了一层 "structure":{}
object = getJSONObject(object, "structure");//解决返回值套了一层 "structure":{}
JSONObject target = null;
if (isTableKey(tag) && object.containsKey(tag) == false) {//tag是table名
@ -292,21 +291,13 @@ public class RequestParser {
//填充target
JSONObject transferredRequest = new JSONObject(true);
if (set != null) {
String value;
JSONObject child;
Object value;
JSONObject result;
for (String key : set) {
value = request.getString(key);
child = JSON.parseObject(value);//是不是更准确key:"{}"可能会让child!=null?? request.getJSONObject(key);
if (child == null) {//key - value
if (isContainKeyInArray(key, disallowColumns)) {
throw new IllegalArgumentException(requestName
+ "不允许传 " + key + " 等[" + disallows + "]内的任何字段!");
}
transferredRequest.put(key, value);
} else {//object
value = request.get(key);
if (value instanceof JSONObject) {//JSONObject往下一级提取
if (target.containsKey(key)) {//只填充target有的object
result = fillTarget(method, target.getJSONObject(key), child, key);//往下一级提取
result = fillTarget(method, getJSONObject(target, key), (JSONObject) value, key);//往下一级提取
System.out.println(TAG + "fillTarget key = " + key + "; result = " + result);
if (result == null || result.isEmpty()) {//只添加!=null的值可能数据库返回数据不够count
throw new IllegalArgumentException(requestName
@ -317,6 +308,12 @@ public class RequestParser {
}
transferredRequest.put(key, result);
}
} else {//JSONArray或其它Object
if (isContainKeyInArray(key, disallowColumns)) {
throw new IllegalArgumentException(requestName
+ "不允许传 " + key + " 等[" + disallows + "]内的任何字段!");
}
transferredRequest.put(key, value);
}
}
}
@ -367,11 +364,11 @@ public class RequestParser {
}
String path = getPath(parentPath, name);
QueryConfig config = StringUtil.isNumer(name) ? parentConfig : null;
boolean nameIsNumber = StringUtil.isNumer(name);
QueryConfig config = nameIsNumber ? parentConfig : null;
if (config == null) {
config = new QueryConfig(requestMethod, name);
}
boolean nameIsNumber = StringUtil.isNumer(name);
final int position = nameIsNumber ? Integer.valueOf(0 + StringUtil.getNumber(name)) : 0;
boolean containRelation = false;
@ -380,17 +377,27 @@ public class RequestParser {
JSONObject transferredRequest = new JSONObject(true);
if (set != null) {
Object value;
String valueString;
JSONObject child;
JSONObject result;
boolean isFirst = true;
for (String key : set) {
value = transferredRequest.containsKey(key) ? transferredRequest.get(key) : request.get(key);
valueString = value == null ? null : String.valueOf(value);
child = JSON.parseObject(valueString);
if (child == null) {//key - value
if (value instanceof JSONObject) {//JSONObject往下一级提取
config.setPosition(isFirst && nameIsNumber ? position : 0);
if (isArrayKey(key)) {//json array
result = getArray(path, config, key, (JSONObject) value);
} else {//json object
isFirst = false;
result = getObject(path, config, key, (JSONObject) value);
}
System.out.println(TAG + "getObject key = " + key + "; result = " + result);
if (result != null && result.isEmpty() == false) {//只添加!=null的值可能数据库返回数据不够count
transferredRequest.put(key, result);
}
} else {//JSONArray或其它Object直接填充
transferredRequest.put(key, value);
if (StringUtil.isPath(valueString)) {
//替换path
if (value instanceof String && StringUtil.isPath((String) value)) {
System.out.println("getObject StringUtil.isPath(value) >> parseRelation = " + parseRelation);
if (parseRelation) {
transferredRequest.put(key, getValueByPath(relationMap.get(getPath(path, key))));
@ -398,21 +405,9 @@ public class RequestParser {
} else {
containRelation = true;
relationMap.put(getPath(path, key)//value.contains(parentPath)会因为结构变化而改变
, getPath((valueString.startsWith(SEPARATOR) ? parentPath : ""), valueString));
, getPath((((String) value).startsWith(SEPARATOR) ? parentPath : ""), (String) value));
}
}
} else {
config.setPosition(isFirst && nameIsNumber ? position : 0);
if (isArrayKey(key)) {//json array
result = getArray(path, config, key, child);
} else {//json object
isFirst = false;
result = getObject(path, config, key, child);
}
System.out.println(TAG + "getObject key = " + key + "; result = " + result);
if (result != null && result.isEmpty() == false) {//只添加!=null的值可能数据库返回数据不够count
transferredRequest.put(key, result);
}
}
}
}
@ -423,7 +418,7 @@ public class RequestParser {
QueryConfig config2 = newQueryConfig(name, transferredRequest);
if (parentConfig != null) {
config2.setLimit(parentConfig.getLimit()).setPage(parentConfig.getPage())
config2.setCount(parentConfig.getCount()).setPage(parentConfig.getPage())
.setPosition(parentConfig.getPosition());//避免position > 0的object获取不到
}
@ -485,6 +480,9 @@ public class RequestParser {
}
}
}
if (totalCount <= 0) {//request内部没有JSONObject或者不存在适合条件的table内容
return null;
}
if (count > totalCount) {
count = totalCount;
}
@ -505,25 +503,20 @@ public class RequestParser {
JSONObject transferredRequest = new JSONObject(true);
if (set != null) {
JSONObject parent = null;
String value;
JSONObject child;
Object value;
JSONObject result;
if (parseRelation == false) {
//生成count个
for (int i = 0; i < count; i++) {
parent = new JSONObject(true);
for (String key : set) {
value = request.getString(key);
child = JSON.parseObject(value);
if (child == null) {//key - value
//array里不允许关联只能在object中关联
transferredRequest.put(key, value);
} else {
value = request.get(key);
if (value instanceof JSONObject) {//JSONObject
config.setPosition(i);
if (isArrayKey(key)) {//json array
result = getArray(getPath(path, "" + i), config, key, child);
result = getArray(getPath(path, "" + i), config, key, (JSONObject) value);
} else {//json object
result = getObject(getPath(path, "" + i), config, key, child);
result = getObject(getPath(path, "" + i), config, key, (JSONObject) value);
}
System.out.println(TAG + "getArray parseRelation == false"
+ " >> i = " + i + "result = " + result);
@ -547,6 +540,8 @@ public class RequestParser {
}
}
}
} else {//JSONArray或其它Object直接填充
transferredRequest.put(key, value);//array里不允许关联只能在object中关联
}
}
if (parent.isEmpty() == false) {//可能数据库返回数据不够count
@ -555,19 +550,19 @@ public class RequestParser {
}
} else {
for (String key : set) {
child = JSON.parseObject(request.getString(key));
if (child == null) {//key - value
//array里不允许关联只能在object中关联
} else {
value = request.get(key);
if (value instanceof JSONObject) {//JSONObject往下一级提取
config.setPosition(Integer.valueOf(0 + StringUtil.getNumber(key, true)));
if (isArrayKey(key)) {//json array
result = getArray(path, config, key, child);
result = getArray(path, config, key, (JSONObject) value);
} else {//json object
result = getObject(path, config, key, child);
result = getObject(path, config, key, (JSONObject) value);
}
if (result != null && result.isEmpty() == false) {//只添加!=null的值可能数据库返回数据不够count
transferredRequest.put(key, result);
}
} else {//JSONArray或其它Object
//array里不允许关联只能在object中关联
}
}
}
@ -604,11 +599,14 @@ public class RequestParser {
* @return
*/
private boolean isInRelationMap(String path) {
if (path == null) {
return false;
}
// return relationMap == null ? false : relationMap.containsKey(path);
Set<String> set = relationMap == null ? null : relationMap.keySet();
if (set != null) {
for (String key : set) {
if (key != null && key.contains(path)) {
if (path.equals(key) || key.startsWith(path + "/")) {//解决相同字符导致的错误) {//key.contains(path)) {//
return true;
}
}
@ -706,7 +704,7 @@ public class RequestParser {
*/
private synchronized JSONObject getSQLObject(QueryConfig config) throws Exception {
System.out.println("getSQLObject config = " + JSON.toJSONString(config));
AccessVerifier.verify(requestMethod, requestObject, config == null ? null : config.getTable());
AccessVerifier.verify(requestObject, config);
return QueryHelper.getInstance().select(config);//QueryHelper2.getInstance().select(config);//
}
@ -721,12 +719,12 @@ public class RequestParser {
private static final Pattern bigAlphaPattern = Pattern.compile("[A-Z]");
private static final Pattern namePattern = Pattern.compile("^[0-9a-zA-Z_]+$");//已用55个中英字符测试通过
public static boolean isTableKey(String key) {
key = StringUtil.getString(key);
return StringUtil.isNotEmpty(key, false) && isArrayKey(key) == false
&& bigAlphaPattern.matcher(key.substring(0, 1)).matches();
return StringUtil.isNotEmpty(key, false)
&& bigAlphaPattern.matcher(key.substring(0, 1)).matches()
&& namePattern.matcher(key.substring(1)).matches();
}
public static boolean isArrayKey(String key) {
return key != null && key.endsWith("[]");

View File

@ -1,12 +1,20 @@
package zuo.biao.apijson.server.sql;
import java.rmi.AccessException;
import static zuo.biao.apijson.RequestMethod.DELETE;
import static zuo.biao.apijson.RequestMethod.GET;
import static zuo.biao.apijson.RequestMethod.POST;
import static zuo.biao.apijson.RequestMethod.POST_GET;
import static zuo.biao.apijson.RequestMethod.PUT;
import org.springframework.web.bind.annotation.RequestMethod;
import java.rmi.AccessException;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import zuo.biao.apijson.RequestMethod;
import zuo.biao.apijson.StringUtil;
import zuo.biao.apijson.server.QueryConfig;
/**权限验证类
* @author Lemon
@ -21,39 +29,82 @@ public class AccessVerifier {
public static final String KEY_LOGIN_PASSWORD = "loginPassword";
public static final String KEY_PAY_PASSWORD = "payPassword";
// public static final String[] LOGIN_ACCESS_TABLE_NAMES = {"Work", "Comment"};
public static final String[] PAY_ACCESS_TABLE_NAMES = {"Wallet"};
public static final String[] LOGIN_ACCESS_TABLE_NAMES = {"Wallet"};
public static final String[] PAY_ACCESS_TABLE_NAMES = {};
/**验证权限是否通过
* @param method
* @param request
* @param tableName
* @return
*/
public static boolean verify(RequestMethod method, JSONObject request, String tableName) throws AccessException {
return verify(method, request, getAccessId(tableName));
private static Map<String, RequestMethod[]> accessMap;
public static void init() {
accessMap = new HashMap<String, RequestMethod[]>();
accessMap.put("User", RequestMethod.values());
accessMap.put("Moment", RequestMethod.values());
accessMap.put("Comment", RequestMethod.values());
accessMap.put("Wallet", new RequestMethod[]{POST_GET, POST, PUT, DELETE});
accessMap.put("Password", new RequestMethod[]{POST_GET, POST, PUT, DELETE});
accessMap.put("Login", new RequestMethod[]{POST_GET, POST, DELETE});
accessMap.put("Request", new RequestMethod[]{GET, POST_GET});
}
/**验证权限是否通过
* @param method
* @param request
* @param accessId 可以直接在代码里写ACCESS_LOGIN等或者建一个Access表包括id和需要改权限的table的tableName列表
* @param config
* @return
* @throws AccessException
* @throws Exception
*/
public static boolean verify(RequestMethod method, JSONObject request, int accessId) throws AccessException {
if (accessId < 0 || request == null) {
public static boolean verify(JSONObject request, QueryConfig config) throws Exception {
String table = config == null ? null : config.getTable();
if (table == null) {
return true;
}
if (request == null) {
return false;
}
RequestMethod method = config.getMethod();
verifyMethod(table, method);
long currentUserId = request.getLongValue(KEY_CURRENT_USER_ID);
switch (config.getMethod()) {
case GET:
case POST_GET:
if ("Wallet".equals(table) || "Password".equals(table)) {
verifyUserId(currentUserId, config);
}
break;
case POST:
case PUT:
case DELETE:
verifyUserId(currentUserId, config);
break;
default:
break;
}
return verifyAccess(request, table, method, currentUserId);
}
/**
* @param request
* @param table
* @param method
* @param currentUserId
* @return
* @throws AccessException
*/
private static boolean verifyAccess(JSONObject request, String table, RequestMethod method, long currentUserId) throws AccessException {
int accessId = getAccessId(method, table);
if (accessId < 0) {
return true;
}
if (currentUserId <= 0) {
System.out.println(TAG + "verify accessId = " + accessId
+ " >> currentUserId <= 0, currentUserId = " + currentUserId);
throw new AccessException("请设置"+ KEY_CURRENT_USER_ID + "和对应的password");
}
String password;
switch (accessId) {
case ACCESS_LOGIN:
password = StringUtil.getString(request.getString(KEY_LOGIN_PASSWORD));
@ -63,6 +114,7 @@ public class AccessVerifier {
+ " currentUserId = " + currentUserId + ", loginPassword = " + password);
throw new AccessException(KEY_CURRENT_USER_ID + "" + KEY_LOGIN_PASSWORD + "错误!");
}
break;
case ACCESS_PAY:
password = StringUtil.getString(request.getString(KEY_PAY_PASSWORD));
if (password.equals(StringUtil.getString(getPayPassword(currentUserId))) == false) {
@ -71,9 +123,36 @@ public class AccessVerifier {
+ " currentUserId = " + currentUserId + ", payPassword = " + password);
throw new AccessException(KEY_CURRENT_USER_ID + "" + KEY_PAY_PASSWORD + "错误!");
}
default:
return true;
break;
}
return true;
}
/**
* @param currentUserId
* @param config
* @return
* @throws Exception
*/
private static boolean verifyUserId(long currentUserId, QueryConfig config) throws Exception {
// if (currentUserId <= 0 || config == null) {
// return true;
// }
// Map<String, Object> where = config.getWhere();
// long userId = 0;
// String table = StringUtil.getString(config.getTable());
// if (where != null) {
// try {
// String key = "User".equals(table) ? Table.ID : Table.USER_ID;
// userId = (long) where.get(key);
// } catch (Exception e) {
// // TODO: handle exception
// }
// }
// if (userId != currentUserId) {
// throw new IllegalArgumentException(table + "的userId和currentUserId不一致");
// }
return true;
}
@ -82,17 +161,17 @@ public class AccessVerifier {
* @param tableName
* @return
*/
public static int getAccessId(String tableName) {
if (StringUtil.isNotEmpty(tableName, true) == false) {
public static int getAccessId(RequestMethod method, String table) {
if (StringUtil.isNotEmpty(table, true) == false) {
return -1;
}
// for (int i = 0; i < LOGIN_ACCESS_TABLE_NAMES.length; i++) {
// if (tableName.equals(LOGIN_ACCESS_TABLE_NAMES[i])) {
// return ACCESS_LOGIN;
// }
// }
for (int i = 0; i < LOGIN_ACCESS_TABLE_NAMES.length; i++) {
if (table.equals(LOGIN_ACCESS_TABLE_NAMES[i])) {
return ACCESS_LOGIN;
}
}
for (int i = 0; i < PAY_ACCESS_TABLE_NAMES.length; i++) {
if (tableName.equals(PAY_ACCESS_TABLE_NAMES[i])) {
if (table.equals(PAY_ACCESS_TABLE_NAMES[i])) {
return ACCESS_PAY;
}
}
@ -105,7 +184,7 @@ public class AccessVerifier {
*/
public static String getLoginPassword(long userId) {
// TODO 查询并返回对应userId的登录密码
return "123456";//仅测试用
return "apijson123";//仅测试用
}
/**获取支付密码
@ -130,4 +209,28 @@ public class AccessVerifier {
return requestObject;
}
/**
* @param table
* @param method
* @return
* @throws AccessException
*/
public static boolean verifyMethod(String table, RequestMethod method) throws AccessException {
RequestMethod[] methods = table == null ? null : accessMap.get(table);
if (methods == null || methods.length <= 0) {
throw new AccessException(table + "不允许访问!");
}
if (method == null) {
method = GET;
}
for (int i = 0; i < methods.length; i++) {
if (method == methods[i]) {
return true;
}
}
throw new AccessException(table + "不支持" + method + "方法!");
}
}

View File

@ -23,6 +23,7 @@ import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import zuo.biao.apijson.StringUtil;
@ -105,18 +106,22 @@ public class QueryHelper {
JSONObject object = null;//new JSONObject(true);
ResultSet rs = null;
switch (config.getMethod()) {
case GET:
case POST_GET:
rs = statement.executeQuery(sql);
break;
case POST:
case PUT:
case DELETE:
int updateCount = statement.executeUpdate(sql);//创建数据对象
int updateCount = statement.executeUpdate(sql);
JSONObject result = RequestParser.newResult(updateCount > 0 ? 200 : 404
, updateCount > 0 ? "success" : "可能对象不存在!");
result.put(Table.ID, config.getId());
return result;
default:
rs = statement.executeQuery(sql);//创建数据对象
break;
default://HEAD, OPTIONS, TRACE等
System.out.println(TAG + "select sql = " + sql + " ; method = " + config.getMethod() + " >> return null;");
return null;
}
@ -128,8 +133,22 @@ public class QueryHelper {
}
object = new JSONObject(true);
try {
Object value;
Object json;
for (int i = 0; i < columnArray.length; i++) {
object.put(columnArray[i], rs.getObject(rs.findColumn(columnArray[i])));
value = rs.getObject(rs.findColumn(columnArray[i]));
if (value instanceof String) {
try {
json = JSON.parse((String) value);
if (json != null && StringUtil.isNotEmpty(json, true)) {
value = json;
}
} catch (Exception e) {
// System.out.println(TAG + "select while (rs.next()){ >> i = " + i + " try { json = JSON.parse((String) value);"
// + ">> } catch (Exception e) {\n" + e.getMessage());
}
}
object.put(columnArray[i], value);
}
} catch (Exception e) {
System.out.println(TAG + "select while (rs.next()){ ... >> try { object.put(list.get(i), ..." +
@ -171,6 +190,7 @@ public class QueryHelper {
/**
* @param table
* @param schema
* @return
* @throws Exception
*/
@ -183,15 +203,15 @@ public class QueryHelper {
}
ResultSet rs = statement.executeQuery("SELECT Count(*) FROM " + table);//创建数据对象
int count = 0;
if (rs.next()) {
count = rs.getInt(1);
}
System.out.println(TAG + "getCount count = " + count) ;
rs.close();
return count;
}

View File

@ -141,7 +141,7 @@ public class QueryHelper2 {
rs.close();
//从缓存存取避免 too many connections崩溃
if (position < config.getLimit() - 1) {
if (position < config.getCount() - 1) {
System.out.println("select position < config.getLimit() - 1 >> saveCache(sql, resultList);");
saveCache(sql, resultList);
} else {

View File

@ -0,0 +1,253 @@
/*Copyright ©2016 TommyLemon(https://github.com/TommyLemon/APIJSON)
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 zuo.biao.apijson.server.sql;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import zuo.biao.apijson.Column;
import zuo.biao.apijson.JSON;
import zuo.biao.apijson.StringUtil;
import zuo.biao.apijson.Table;
import zuo.biao.apijson.server.QueryConfig;
import zuo.biao.apijson.server.RequestParser;
/**helper for query MySQL database
* @author Lemon
*/
public class QueryHelper3 {
private static final String TAG = "QueryHelper: ";
private static final String YOUR_MYSQL_URL = "jdbc:mysql://localhost:3306/";//TODO edit to an available one
private static final String YOUR_MYSQL_SCHEMA = "sys";//TODO edit to an available one
private static final String YOUR_MYSQL_ACCOUNT = "root";//TODO edit to an available one
private static final String YOUR_MYSQL_PASSWORD = "apijson";//TODO edit to an available one
private QueryHelper3() {
}
private static QueryHelper3 instance;
public static synchronized QueryHelper3 getInstance() {
if (instance == null) {
instance = new QueryHelper3();
}
return instance;
}
public Connection getConnection() throws Exception {
//调用Class.forName()方法加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
System.out.println(TAG + "成功加载MySQL驱动");
return DriverManager.getConnection(YOUR_MYSQL_URL + YOUR_MYSQL_SCHEMA, YOUR_MYSQL_ACCOUNT, YOUR_MYSQL_PASSWORD);
}
private static Connection connection;
private static Statement statement;
private static DatabaseMetaData metaData;
public void close() {
try {
if (statement != null && statement.isClosed() == false) {
statement.close();
}
if (connection != null && connection.isClosed() == false) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
metaData = null;
statement = null;
}
public JSONObject select(QueryConfig config) throws Exception {
if (config == null || StringUtil.isNotEmpty(config.getTable(), true) == false) {
System.out.println(TAG + "select config==null||StringUtil.isNotEmpty(config.getTable(), true)==false>>return null;");
return null;
}
final String sql = config.getSQL();
System.out.println(TAG + "成功连接到数据库!");
if (connection == null || connection.isClosed()) {
System.out.println(TAG + "select connection " + (connection == null ? " = null" : ("isClosed = " + connection.isClosed()))) ;
connection = getConnection();
statement = connection.createStatement(); //创建Statement对象
metaData = connection.getMetaData();
}
List<Column> columnList = getColumnList(config);
if (columnList == null || columnList.isEmpty()) {
return null;
}
System.out.println(TAG + "select sql = " + sql);
JSONObject object = null;//new JSONObject(true);
ResultSet rs = null;
switch (config.getMethod()) {
case GET:
case POST_GET:
rs = statement.executeQuery(sql);
break;
case POST:
case PUT:
case DELETE:
int updateCount = statement.executeUpdate(sql);
JSONObject result = RequestParser.newResult(updateCount > 0 ? 200 : 404
, updateCount > 0 ? "success" : "可能对象不存在!");
result.put(Table.ID, config.getId());
return result;
default://HEAD, OPTIONS, TRACE等
System.out.println(TAG + "select sql = " + sql + " ; method = " + config.getMethod() + " >> return null;");
return null;
}
int position = -1;
while (rs.next()) {
position ++;
if (position != config.getPosition()) {
continue;
}
object = new JSONObject(true);
try {
Object value;
JSONArray array;
for (Column column : columnList) {
if (column == null || StringUtil.isNotEmpty(column.getLabel(), true) == false) {
continue;
}
value = rs.getObject(rs.findColumn(column.getLabel()));
if (column.getType() == Types.ARRAY) {//value instanceof String) {
array = JSON.parseArray((String)value);
if (array != null && array.isEmpty() == false) {
value = array;
}
}
object.put(column.getLabel(), value);
}
} catch (Exception e) {
System.out.println(TAG + "select while (rs.next()){ ... >> try { object.put(list.get(i), ..." +
" >> } catch (Exception e) {\n" + e.getMessage());
e.printStackTrace();
}
break;
}
rs.close();
return object;
}
/**获取全部字段名列表
* @param config
* @return
* @throws SQLException
*/
public List<Column> getColumnList(QueryConfig config) throws SQLException {
if (config == null) {
return null;
}
List<Column> list = new ArrayList<>();
String columnsString = config.getColumns();
if (StringUtil.isNotEmpty(columnsString, true)) {
String[] columns = StringUtil.split(columnsString);//columns.contains(",") ? columns.split(",") : new String[]{columns};
if (columns != null) {
for (int i = 0; i < columns.length; i++) {
list.add(new Column(columns[i]));
}
}
return list;//只要request中设置了columnsString就不查询
}
String table = config.getTable();
ResultSet rs = metaData.getColumns(YOUR_MYSQL_SCHEMA, null, table, "%");
ResultSetMetaData data = rs.getMetaData();
Column column;
while (rs.next()) {
for (int i = 1; i<= data.getColumnCount(); i++) {
column = new Column();
column.setCount(data.getColumnCount());
column.setName(data.getColumnName(i));
column.setValue(rs.getString(i));
column.setType(data.getColumnType(i));
column.setTypeName(data.getColumnTypeName(i));
column.setCatalogName(data.getCatalogName(i));
column.setClassName(data.getColumnClassName(i));
column.setDisplaySize(data.getColumnDisplaySize(i));
column.setLabel(data.getColumnLabel(i));
column.setSchemaName(data.getSchemaName(i));
column.setPrecision(data.getPrecision(i));
column.setScale(data.getScale(i));
column.setTable(data.getTableName(i));
column.setAutoInctement(data.isAutoIncrement(i));
column.setIsCurrency(data.isCurrency(i));
column.setNullable(data.isNullable(i));
column.setReadOnly(data.isReadOnly(i));
column.setSearchable(data.isSearchable(i));
System.out.println(TAG + "getColumnList column = \n" + JSON.toJSONString(column));
list.add(column);
}
}
rs.close();
return list;
}
/**
* @param table
* @param schema
* @return
* @throws Exception
*/
public int getCount(String table) throws Exception {
if (connection == null || connection.isClosed()) {
System.out.println(TAG + "getCount connection " + (connection == null ? " = null" : ("isClosed = " + connection.isClosed()))) ;
connection = getConnection();
statement = connection.createStatement(); //创建Statement对象
metaData = connection.getMetaData();
}
ResultSet rs = statement.executeQuery("SELECT Count(*) FROM " + table);//创建数据对象
int count = 0;
if (rs.next()) {
count = rs.getInt(1);
}
System.out.println(TAG + "getCount count = " + count) ;
rs.close();
return count;
}
}