一、工具方法
1、远程调用接口
/*远程调用
* requestUrl 请求路径
* requestMethod 请求方法 POST GET
* parameter 请求参数
* obj 请求头设置
*/
public static String httpsRequest2(String requestUrl, String requestMethod, String parameter,
Map<String, String> obj) throws IOException {
log.info("远程调用开始 requestUrl:" + requestUrl + ",requestMethod:" + requestMethod + ",parameter:" + parameter);
URL connect = null;
OutputStreamWriter paramout = null;
InputStreamReader inputStreamReader = null;
BufferedReader reader = null;
HttpURLConnection connection = null;
StringBuffer data = new StringBuffer();
try {
connect = new URL(requestUrl);
// 1、打开和url之间的连接
connection = (HttpURLConnection)connect.openConnection();
// 2、设置通用的请求属性
connection.setRequestMethod(requestMethod);// 请求方法post、get
connection.setDoOutput(true);
connection.setReadTimeout(30000);
connection.setConnectTimeout(30000);// 连接超时时间为30秒
connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
connection.setRequestProperty("Charset", "UTF-8");
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
if (!ValidateUtil.isNull(obj)) {// 添加请求头参数
Set<String> keySet = obj.keySet();
String val;
for (String key : keySet) {
val = obj.get(key);
connection.setRequestProperty(key, val);
}
}
if (!ValidateUtil.isNull(parameter)) {
paramout = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
paramout.write(parameter);// 请求参数 json数据
paramout.flush();
}
if (HttpURLConnection.HTTP_OK == connection.getResponseCode()
|| HttpURLConnection.HTTP_CREATED == connection.getResponseCode()
|| HttpURLConnection.HTTP_ACCEPTED == connection.getResponseCode()) {
inputStreamReader = new InputStreamReader(connection.getInputStream(), "UTF-8");
reader = new BufferedReader(inputStreamReader);
String line;
while ((line = reader.readLine()) != null) {
data.append(line);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
reader.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (paramout != null) {
paramout.close();
}
if (connection != null) {
connection.disconnect();
}
}
log.info("远程调用结束 " + data.toString());
return data.toString();
}
2、通过流获取远程接口返回信息
/*
* 通过流获取远程调用返回信息
*/
public static String getHttpParams(HttpServletRequest request) throws IOException {
StringBuffer sb = new StringBuffer();
BufferedReader reader = null;
InputStreamReader inputStreamReader = null;
try {
inputStreamReader = new InputStreamReader(request.getInputStream(), "UTF-8");
reader = new BufferedReader(inputStreamReader);
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
log.info("从业务请求中获取参数失败!!!");
return null;
} finally {
if (reader != null) {
reader.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
}
return sb.toString();
}
3、获取请求真实ip(请求服务器Nginx需要配置)
location / {
proxy_pass http://127.0.0.1:100;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
/*
* 获取请求真实ip
*/
public static String httpsRequestIp(HttpServletRequest request) {
log.info("----------------------获取真实ip开始----------------------------------------");
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
// 根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
log.info(InetAddress.getLoopbackAddress() + "");
} catch (Exception e) {
e.printStackTrace();
}
ip = inet.getHostAddress();
}
}
log.info("ips:" + ip);
// 多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
log.info("----------------------获取真实ip结束-----------------------" + ip);
return ip.trim();
}
4、请求接口参数模拟
Map<String, Object> omap = new HashMap<String, Object>();
omap.put("partnerOrderNo", "123");// 分销商订单编号
omap.put("productId", "1");// 三方产品id
omap.put("goodsId", "2");// 三方商品id
omap.put("quantity", 1);// 订购份数
long timestamp = new Date().getTime();// 请求时间戳
String dataString = HttpRequestUtils.jsonToMap(com.alibaba.fastjson.JSONObject.toJSONString(omap));
String sgin = MD5.string2MD5(SystemConfig.APP_SECRET + timestamp + dataString);// 请求签名(请求参数排序签名)
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("appKey", SystemConfig.APP_KEY);
map1.put("timestamp", timestamp);
map1.put("sgin", sgin);
map1.put("data", omap);
map1.put("otas", "1");
map1.put("sName", "createOrder_execute");
String reslut = null;
try {
reslut = CommonUtils.httpsRequest(APIURL, "POST", JSONObject.fromObject(map1).toString());
} catch (Exception e) {
rst.setResult("1");
rst.setError("创建订单接口错误");
return rst;
}
JSONObject fromObject = JSONObject.fromObject(reslut);
if ("200".equals(fromObject.getString("result")) && "0".equals(fromObject.getString("code"))) {
datas = fromObject.getJSONObject("message").getJSONObject("data");
} else {
rst.addMessage("ustate", "1");
rst.setError(fromObject.getString("error"));
return rst;
}
5、json字符串转顺序Map
/**
* JSON转顺序排序的Map
*
* @param jsonStr
* 原始json
* @return 响应的map
*/
public static String jsonToMap(String jsonStr) {
Map<String, Object> treeMap = new TreeMap();
com.alibaba.fastjson.JSONObject json =
com.alibaba.fastjson.JSONObject.parseObject(jsonStr, Feature.OrderedField);// Feature.OrderedField实现解析后保存不乱序
Iterator<String> keys = json.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next();
Object value = json.get(key);
// 判断传入kay-value中是否含有""或null
if (json.get(key) == null || value == null || value.toString().length() == 0) {
// 当JSON字符串存在null时,不将该kay-value放入Map中,即显示的结果不包括该kay-value
continue;
}
// 判断是否为JSONArray(json数组)
if (value instanceof JSONArray) {
JSONArray jsonArray = (JSONArray)value;
List<Object> arrayList = new ArrayList<>();
for (Object object : jsonArray) {
// 判断是否为JSONObject,如果是 转化成TreeMap
if (object instanceof JSONObject) {
object = jsonToMap(object.toString());
}
arrayList.add(object);
}
treeMap.put(key, arrayList);
} else {
// 判断该JSON中是否嵌套JSON
boolean flag = isJSONValid(value.toString());
if (flag) {
// 若嵌套json了,通过递归再对嵌套的json(即子json)进行排序
value = jsonToMap(value.toString());
}
// 其他基础类型直接放入treeMap
// JSONObject可进行再次解析转换
treeMap.put(key, value);
}
}
return JSONObject.fromObject(treeMap).toString();
}
/**
* 校验是否是JSON字符串
*
* @param json
* 传入数据
* @return 是JSON返回true, 否则false
*/
public final static boolean isJSONValid(String json) {
try {
com.alibaba.fastjson.JSONObject.parseObject(json);
} catch (JSONException ex) {
return false;
}
return true;
}
6、请求接口校验
/*request
* appid
* timestamp 时间戳
* sgin 签名
*/
public static IRestResponse validateRequest(HttpServletRequest request, JSONObject datas) {
IRestResponse rst = new IRestResponse();
rst.setResult(IRestResponse.OK);
rst.setCode("0");
// 1)获取请求参数
String appkey = datas.getString("appKey");// 请求APPid
String timestamp = datas.getString("timestamp");// 请求时间戳
String sgin = datas.getString("sgin");// 请求签名(请求参数排序签名)
String data = datas.getString("data");// 业务数据
// 1)校验请求参数是否为空
if (ValidateUtil.isNull(appkey)) {
log.error("缺少appid");
rst.setCode("1");
rst.setError("缺少appid");
return rst;
}
if (ValidateUtil.isNull(timestamp)) {
log.error("缺少时间戳");
rst.setCode("2");
rst.setError("缺少时间戳");
return rst;
}
if (ValidateUtil.isNull(sgin)) {
log.error("缺少签名");
rst.setCode("4");
rst.setError("缺少签名");
return rst;
}
// 2) 验证账号是否存在
AppSecretList app = baseDao.query(AppSecretList.class, "appkey='" + appkey + "' and state='0'", null);
if (ValidateUtil.isNull(app)) {
rst.setCode("5");
rst.setError("无开发者权限");
return rst;
}
if ("1".equals(app.getState())) {
rst.setCode("6");
rst.setError("无效appid");
return rst;
}
// 3)验证签名是否有效 (秘钥+时间戳+参数)
String dataString = "";
if (!ValidateUtil.isNull(data)) {
dataString = jsonToMap(data);
}
log.info("数据排序" + dataString);
String sgin1 = MD5.string2MD5(app.getAppsecret() + timestamp + dataString);
if (!sgin.equals(sgin1)) {
rst.setCode("11");
rst.setError("无效签名");
return rst;
}
// 4)验证请求时间是否超时(默认时间戳10秒)
long times = new Date().getTime();// 当前系统时间戳
long timestamps = Long.parseLong(timestamp);
long abstime = Math.abs(times - timestamps);
if (abstime > 10000) {
rst.setCode("22");
rst.setError("数据包已失效");
return rst;
}
// 5)验证是否重复请求
Object obj = GuavaCacheUtils.get(sgin1);//默认缓存10秒
if (!ValidateUtil.isNull(obj) && "YES".equals(obj.toString())) {
rst.setCode("23");
rst.setError("非法请求");
return rst;
} else {
GuavaCacheUtils.put(sgin1, "YES");
}
// 6)验证是否是ip白名单
if (ValidateUtil.isNull(app.getIps())) {
rst.setCode("7");
rst.setError("缺少ip白名单");
return rst;
}
String[] ips = app.getIps().split("\\n");
String realIp = HttpRequestUtils.httpsRequestIp(request);// 真实请求ip
log.info("请求ip:" + realIp);
boolean falg = false;
for (String ip : ips) {
log.info("配置白名单" + ip);
if (realIp.equals(ip.trim())) {
falg = true;
break;
}
}
if (!falg) {
rst.setCode("8");
rst.setError("非法ip请求");
return rst;
}
// 7)验证是否有接口访问权限
String msql = "SELECT afm.`methodurl` FROM `app_method_relevance` amr "
+ "INNER JOIN `app_foreign_method` afm ON amr.`methodid`=afm.`id` WHERE amr.`appid`='" + app.getId()
+ "' AND afm.`state`='0'";
List<Map<String, Object>> mList = baseDao.getList(msql, null);
if (mList.size() <= 0) {
rst.setCode("9");
rst.setError("无接口配置");
return rst;
}
String method = request.getServletPath();
log.info("请求接口URL:" + method);
boolean falg1 = false;
for (Map<String, Object> map : mList) {
log.info("所有接口" + map.get("methodurl"));
if (method.equals(map.get("methodurl").toString())) {
falg1 = true;
break;
}
}
if (!falg1) {
rst.setCode("10");
rst.setError("无接口权限");
return rst;
}
rst.addMessage("appid", app.getId());
return rst;
}