commit
49fb6bf15f
@ -1,32 +1,32 @@ |
||||
* [首页](/?t=1564027102043) |
||||
* [首页](/?t=1564057981506) |
||||
* 开发文档 |
||||
* [快速体验](files/10010_快速体验.md?t=1564027102045) |
||||
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1564027102062) |
||||
* [新增接口](files/10020_新增接口.md?t=1564027102062) |
||||
* [业务参数校验](files/10030_业务参数校验.md?t=1564027102062) |
||||
* [错误处理](files/10040_错误处理.md?t=1564027102062) |
||||
* [编写文档](files/10041_编写文档.md?t=1564027102063) |
||||
* [接口交互详解](files/10050_接口交互详解.md?t=1564027102063) |
||||
* [easyopen支持](files/10070_easyopen支持.md?t=1564027102063) |
||||
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1564027102063) |
||||
* [ISV管理](files/10085_ISV管理.md?t=1564027102063) |
||||
* [自定义路由](files/10086_自定义路由.md?t=1564027102063) |
||||
* [路由授权](files/10090_路由授权.md?t=1564027102063) |
||||
* [接口限流](files/10092_接口限流.md?t=1564027102063) |
||||
* [监控日志](files/10093_监控日志.md?t=1564027102063) |
||||
* [SDK开发](files/10095_SDK开发.md?t=1564027102063) |
||||
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1564027102064) |
||||
* [应用授权](files/10097_应用授权.md?t=1564027102064) |
||||
* [更改数据节点名称](files/10099_更改数据节点名称.md?t=1564027102064) |
||||
* [传统web开发](files/10100_传统web开发.md?t=1564027102064) |
||||
* [自定义过滤器](files/10102_自定义过滤器.md?t=1564027102064) |
||||
* [文件上传](files/10104_文件上传.md?t=1564027102064) |
||||
* [nacos注册中心](files/10106_nacos注册中心.md?t=1564027102064) |
||||
* [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1564027102064) |
||||
* [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1564027102064) |
||||
* [快速体验](files/10010_快速体验.md?t=1564057981508) |
||||
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1564057981525) |
||||
* [新增接口](files/10020_新增接口.md?t=1564057981525) |
||||
* [业务参数校验](files/10030_业务参数校验.md?t=1564057981525) |
||||
* [错误处理](files/10040_错误处理.md?t=1564057981525) |
||||
* [编写文档](files/10041_编写文档.md?t=1564057981526) |
||||
* [接口交互详解](files/10050_接口交互详解.md?t=1564057981526) |
||||
* [easyopen支持](files/10070_easyopen支持.md?t=1564057981526) |
||||
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1564057981526) |
||||
* [ISV管理](files/10085_ISV管理.md?t=1564057981526) |
||||
* [自定义路由](files/10086_自定义路由.md?t=1564057981526) |
||||
* [路由授权](files/10090_路由授权.md?t=1564057981526) |
||||
* [接口限流](files/10092_接口限流.md?t=1564057981526) |
||||
* [监控日志](files/10093_监控日志.md?t=1564057981526) |
||||
* [SDK开发](files/10095_SDK开发.md?t=1564057981526) |
||||
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1564057981526) |
||||
* [应用授权](files/10097_应用授权.md?t=1564057981527) |
||||
* [更改数据节点名称](files/10099_更改数据节点名称.md?t=1564057981527) |
||||
* [传统web开发](files/10100_传统web开发.md?t=1564057981527) |
||||
* [自定义过滤器](files/10102_自定义过滤器.md?t=1564057981527) |
||||
* [文件上传](files/10104_文件上传.md?t=1564057981527) |
||||
* [nacos注册中心](files/10106_nacos注册中心.md?t=1564057981527) |
||||
* [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1564057981527) |
||||
* [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1564057981527) |
||||
* 原理分析 |
||||
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1564027102064) |
||||
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1564027102064) |
||||
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1564027102064) |
||||
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1564027102064) |
||||
* [常见问题](files/90100_常见问题.md?t=1564027102065) |
||||
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1564057981527) |
||||
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1564057981527) |
||||
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1564057981528) |
||||
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1564057981528) |
||||
* [常见问题](files/90100_常见问题.md?t=1564057981528) |
||||
|
@ -0,0 +1,74 @@ |
||||
package com.gitee.sop.servercommon.bean; |
||||
|
||||
import java.util.Date; |
||||
|
||||
/** |
||||
* 获取开放平台请求参数。 |
||||
* 可当做接口方法参数,泛型参数填业务参数类,如: |
||||
* <pre> |
||||
* <code>@ApiMapping(value = "alipay.goods.get")</code> |
||||
* public Goods getGoods(OpenRequest<GoodsParam> openRequest){...}</code> <br/> |
||||
* </pre> |
||||
* 可通过<code>OpenRequest openRequest = ServiceContext.getCurrentContext().getOpenRequest();</code>方式进行获取 |
||||
* OpenContext |
||||
* OpenParam |
||||
* @author tanghc |
||||
* |
||||
*/ |
||||
public interface OpenContext<T> { |
||||
|
||||
/** |
||||
* 返回appid |
||||
* @return 返回appid |
||||
*/ |
||||
String getAppId(); |
||||
|
||||
/** |
||||
* 返回业务参数json字符串 |
||||
* @return 返回字符串业务参数 |
||||
*/ |
||||
String getBizContent(); |
||||
|
||||
/** |
||||
* 返回业务对象 |
||||
* @return 业务对象 |
||||
*/ |
||||
T getBizObject(); |
||||
|
||||
/** |
||||
* 返回字符编码 |
||||
* @return 如UTF-8 |
||||
*/ |
||||
String getCharset(); |
||||
|
||||
/** |
||||
* 返回接口名 |
||||
* @return 如:alipay.goods.get |
||||
*/ |
||||
String getMethod(); |
||||
|
||||
/** |
||||
* 返回版本号 |
||||
* @return 如:1.0 |
||||
*/ |
||||
String getVersion(); |
||||
|
||||
/** |
||||
* 返回参数格式化 |
||||
* @return 如:json |
||||
*/ |
||||
String getFormat(); |
||||
|
||||
/** |
||||
* 返回签名类型 |
||||
* @return 如:RSA2 |
||||
*/ |
||||
String getSignType(); |
||||
|
||||
/** |
||||
* 返回时间戳 |
||||
* @return |
||||
*/ |
||||
Date getTimestamp(); |
||||
|
||||
} |
@ -0,0 +1,73 @@ |
||||
package com.gitee.sop.servercommon.bean; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
|
||||
import java.util.Date; |
||||
|
||||
import static com.gitee.sop.servercommon.bean.ParamNames.API_NAME; |
||||
import static com.gitee.sop.servercommon.bean.ParamNames.APP_KEY_NAME; |
||||
import static com.gitee.sop.servercommon.bean.ParamNames.BIZ_CONTENT_NAME; |
||||
import static com.gitee.sop.servercommon.bean.ParamNames.CHARSET_NAME; |
||||
import static com.gitee.sop.servercommon.bean.ParamNames.FORMAT_NAME; |
||||
import static com.gitee.sop.servercommon.bean.ParamNames.SIGN_TYPE_NAME; |
||||
import static com.gitee.sop.servercommon.bean.ParamNames.TIMESTAMP_NAME; |
||||
import static com.gitee.sop.servercommon.bean.ParamNames.VERSION_NAME; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
public class OpenContextImpl<T> implements OpenContext<T> { |
||||
private JSONObject jsonObject; |
||||
private T bizObject; |
||||
|
||||
public OpenContextImpl(JSONObject jsonObject, Class<?> bizClass) { |
||||
this.jsonObject = jsonObject; |
||||
JSONObject bizJsonObj = this.jsonObject.getJSONObject(BIZ_CONTENT_NAME); |
||||
bizObject = (bizClass == null || bizJsonObj == null) ? null : (T) bizJsonObj.toJavaObject(bizClass); |
||||
} |
||||
|
||||
@Override |
||||
public String getAppId() { |
||||
return jsonObject.getString(APP_KEY_NAME); |
||||
} |
||||
|
||||
@Override |
||||
public T getBizObject() { |
||||
return bizObject; |
||||
} |
||||
|
||||
@Override |
||||
public String getBizContent() { |
||||
return jsonObject.getString(BIZ_CONTENT_NAME); |
||||
} |
||||
|
||||
@Override |
||||
public String getCharset() { |
||||
return jsonObject.getString(CHARSET_NAME); |
||||
} |
||||
|
||||
@Override |
||||
public String getMethod() { |
||||
return jsonObject.getString(API_NAME); |
||||
} |
||||
|
||||
@Override |
||||
public String getVersion() { |
||||
return jsonObject.getString(VERSION_NAME); |
||||
} |
||||
|
||||
@Override |
||||
public String getFormat() { |
||||
return jsonObject.getString(FORMAT_NAME); |
||||
} |
||||
|
||||
@Override |
||||
public String getSignType() { |
||||
return jsonObject.getString(SIGN_TYPE_NAME); |
||||
} |
||||
|
||||
@Override |
||||
public Date getTimestamp() { |
||||
return jsonObject.getDate(TIMESTAMP_NAME); |
||||
} |
||||
} |
@ -0,0 +1,85 @@ |
||||
package com.gitee.sop.servercommon.util; |
||||
|
||||
import com.alibaba.fastjson.JSON; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.apache.commons.io.IOUtils; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import java.io.IOException; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
@Slf4j |
||||
public class OpenUtil { |
||||
|
||||
private static final String CONTENT_TYPE_URLENCODED = "application/x-www-form-urlencoded"; |
||||
private static final String CONTENT_TYPE_JSON = "application/json"; |
||||
private static final String CONTENT_TYPE_TEXT = "text/plain"; |
||||
|
||||
private static final String UTF8 = "UTF-8"; |
||||
|
||||
/** |
||||
* 从request中获取参数。如果提交方式是application/x-www-form-urlencoded,则组装成json格式。 |
||||
* |
||||
* @param request request对象 |
||||
* @return 返回json |
||||
* @throws IOException |
||||
*/ |
||||
public static JSONObject getRequestParams(HttpServletRequest request) { |
||||
String requestJson = "{}"; |
||||
String contentType = request.getContentType(); |
||||
if (StringUtils.isBlank(contentType)) { |
||||
return new JSONObject(); |
||||
} |
||||
contentType = contentType.toLowerCase(); |
||||
if (StringUtils.containsAny(contentType, CONTENT_TYPE_JSON, CONTENT_TYPE_TEXT)) { |
||||
try { |
||||
requestJson = IOUtils.toString(request.getInputStream(), UTF8); |
||||
} catch (IOException e) { |
||||
log.error("获取文本数据流失败", e); |
||||
} |
||||
} else if (StringUtils.containsAny(contentType, CONTENT_TYPE_URLENCODED)) { |
||||
Map<String, Object> params = convertRequestParamsToMap(request); |
||||
requestJson = JSON.toJSONString(params); |
||||
} |
||||
return JSON.parseObject(requestJson); |
||||
} |
||||
|
||||
/** |
||||
* request中的参数转换成map |
||||
* |
||||
* @param request request对象 |
||||
* @return 返回参数键值对 |
||||
*/ |
||||
public static Map<String, Object> convertRequestParamsToMap(HttpServletRequest request) { |
||||
Map<String, String[]> paramMap = request.getParameterMap(); |
||||
if(paramMap == null || paramMap.isEmpty()) { |
||||
return Collections.emptyMap(); |
||||
} |
||||
Map<String, Object> retMap = new HashMap<String, Object>(paramMap.size()); |
||||
|
||||
Set<Map.Entry<String, String[]>> entrySet = paramMap.entrySet(); |
||||
|
||||
for (Map.Entry<String, String[]> entry : entrySet) { |
||||
String name = entry.getKey(); |
||||
String[] values = entry.getValue(); |
||||
if (values.length == 1) { |
||||
retMap.put(name, values[0]); |
||||
} else if (values.length > 1) { |
||||
retMap.put(name, values); |
||||
} else { |
||||
retMap.put(name, ""); |
||||
} |
||||
} |
||||
|
||||
return retMap; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,41 @@ |
||||
package com.gitee.sop.storyweb.controller; |
||||
|
||||
import com.gitee.sop.servercommon.annotation.ApiMapping; |
||||
import com.gitee.sop.servercommon.bean.ServiceContext; |
||||
import com.gitee.sop.servercommon.bean.OpenContext; |
||||
import com.gitee.sop.story.api.domain.Story; |
||||
import com.gitee.sop.storyweb.controller.param.StoryParam; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
@RestController |
||||
public class PostJsonController { |
||||
|
||||
/** |
||||
* 演示客户端使用json方式请求(application/json) |
||||
* @param param |
||||
* @return |
||||
*/ |
||||
@ApiMapping("demo.post.json") |
||||
public Story postJson(StoryParam param) { |
||||
// 获取开放平台请求参数
|
||||
OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext(); |
||||
List<Object> params = Arrays.asList( |
||||
openContext.getAppId(), |
||||
openContext.getMethod(), |
||||
openContext.getVersion() |
||||
); |
||||
Story story = new Story(); |
||||
story.setId(1); |
||||
story.setName("参数:" + param.getName() + ", openParams:" + StringUtils.join(params)); |
||||
return story; |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,56 @@ |
||||
package com.gitee.sop.test; |
||||
|
||||
import com.alibaba.fastjson.JSON; |
||||
import com.gitee.sop.test.alipay.AlipaySignature; |
||||
import org.junit.Test; |
||||
|
||||
import java.text.SimpleDateFormat; |
||||
import java.util.Date; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 以json方式请求(application/json) |
||||
*/ |
||||
public class PostJsonTest extends TestBase { |
||||
|
||||
String url = "http://localhost:8081/api"; // zuul
|
||||
String appId = "2019032617262200001"; |
||||
// 支付宝私钥
|
||||
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ="; |
||||
|
||||
@Test |
||||
public void testPostJson() throws Exception { |
||||
|
||||
// 公共请求参数
|
||||
Map<String, String> params = new HashMap<String, String>(); |
||||
params.put("app_id", appId); |
||||
params.put("method", "demo.post.json"); |
||||
params.put("format", "json"); |
||||
params.put("charset", "utf-8"); |
||||
params.put("sign_type", "RSA2"); |
||||
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); |
||||
params.put("version", "1.0"); |
||||
|
||||
// 业务参数
|
||||
Map<String, String> bizContent = new HashMap<>(); |
||||
bizContent.put("name", "葫芦娃"); |
||||
|
||||
params.put("biz_content", JSON.toJSONString(bizContent)); |
||||
|
||||
System.out.println("----------- 请求信息 -----------"); |
||||
System.out.println("请求参数:" + buildParamQuery(params)); |
||||
System.out.println("商户秘钥:" + privateKey); |
||||
String content = AlipaySignature.getSignContent(params); |
||||
System.out.println("待签名内容:" + content); |
||||
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8"); |
||||
System.out.println("签名(sign):" + sign); |
||||
|
||||
params.put("sign", sign); |
||||
|
||||
System.out.println("----------- 返回结果 -----------"); |
||||
String responseData = get(url, params);// 发送请求
|
||||
System.out.println(responseData); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue