Browse Source

first commit

15810770710@163.com 2 years ago
parent
commit
98997eca36
63 changed files with 6770 additions and 0 deletions
  1. 232 0
      pom.xml
  2. 9 0
      setting/online.properties
  3. 9 0
      setting/test.properties
  4. 110 0
      src/main/java/com/sec/xinhua/gateway/beans/ApiCode.java
  5. 102 0
      src/main/java/com/sec/xinhua/gateway/beans/ApiContext.java
  6. 207 0
      src/main/java/com/sec/xinhua/gateway/beans/ApiParam.java
  7. 58 0
      src/main/java/com/sec/xinhua/gateway/beans/ApiParamType.java
  8. 59 0
      src/main/java/com/sec/xinhua/gateway/beans/ApiResult.java
  9. 129 0
      src/main/java/com/sec/xinhua/gateway/beans/ApiResultCache.java
  10. 48 0
      src/main/java/com/sec/xinhua/gateway/beans/GatewayEnv.java
  11. 141 0
      src/main/java/com/sec/xinhua/gateway/beans/GatewaySetting.java
  12. 28 0
      src/main/java/com/sec/xinhua/gateway/beans/InvokeParam.java
  13. 99 0
      src/main/java/com/sec/xinhua/gateway/beans/SimpleApi.java
  14. 106 0
      src/main/java/com/sec/xinhua/gateway/beans/SimpleApiParam.java
  15. 59 0
      src/main/java/com/sec/xinhua/gateway/config/ApiSettingRepository.java
  16. 11 0
      src/main/java/com/sec/xinhua/gateway/config/ConfigLoader.java
  17. 45 0
      src/main/java/com/sec/xinhua/gateway/config/ConfigRepositoryFactory.java
  18. 50 0
      src/main/java/com/sec/xinhua/gateway/config/GatewaySettingRepository.java
  19. 152 0
      src/main/java/com/sec/xinhua/gateway/config/local/FileConfigLoader.java
  20. 50 0
      src/main/java/com/sec/xinhua/gateway/config/remote/ApiRemoteRepository.java
  21. 13 0
      src/main/java/com/sec/xinhua/gateway/handler/ApiHandler.java
  22. 9 0
      src/main/java/com/sec/xinhua/gateway/handler/ApiHandlerChain.java
  23. 145 0
      src/main/java/com/sec/xinhua/gateway/handler/ApiParamValueConvertor.java
  24. 69 0
      src/main/java/com/sec/xinhua/gateway/handler/DefaultApiHandlerChain.java
  25. 190 0
      src/main/java/com/sec/xinhua/gateway/handler/DubboArgumentConvertHandler.java
  26. 98 0
      src/main/java/com/sec/xinhua/gateway/handler/DubboServiceInvokeHandler.java
  27. 165 0
      src/main/java/com/sec/xinhua/gateway/handler/RequestHandler.java
  28. 45 0
      src/main/java/com/sec/xinhua/gateway/handler/SysParamValidateHandler.java
  29. 33 0
      src/main/java/com/sec/xinhua/gateway/parse/HttpParamConstants.java
  30. 180 0
      src/main/java/com/sec/xinhua/gateway/parse/ParamParser.java
  31. 68 0
      src/main/java/com/sec/xinhua/gateway/parse/RequestParam.java
  32. 99 0
      src/main/java/com/sec/xinhua/gateway/parse/SysParam.java
  33. 90 0
      src/main/java/com/sec/xinhua/gateway/service/DubboServiceManager.java
  34. 13 0
      src/main/java/com/sec/xinhua/gateway/service/DubboTimeoutTestService.java
  35. 35 0
      src/main/java/com/sec/xinhua/gateway/service/impl/DubboTimeoutTestServiceImpl.java
  36. 1257 0
      src/main/java/com/sec/xinhua/gateway/thrift/GatewayThriftService.java
  37. 612 0
      src/main/java/com/sec/xinhua/gateway/thrift/ThriftResult.java
  38. 34 0
      src/main/java/com/sec/xinhua/gateway/thrift/impl/GatewayThriftServiceImpl.java
  39. 69 0
      src/main/java/com/sec/xinhua/gateway/thrift/server/GatewayThriftServer.java
  40. 80 0
      src/main/java/com/sec/xinhua/gateway/utils/AbstractLocalCache.java
  41. 17 0
      src/main/java/com/sec/xinhua/gateway/utils/ApiHandlerException.java
  42. 23 0
      src/main/java/com/sec/xinhua/gateway/utils/ApiParamTypeCache.java
  43. 91 0
      src/main/java/com/sec/xinhua/gateway/utils/FileHelper.java
  44. 28 0
      src/main/java/com/sec/xinhua/gateway/utils/HashCodeUtils.java
  45. 49 0
      src/main/java/com/sec/xinhua/gateway/utils/InputStreamCacher.java
  46. 53 0
      src/main/java/com/sec/xinhua/gateway/utils/IpFileCache.java
  47. 17 0
      src/main/java/com/sec/xinhua/gateway/utils/ParamParseException.java
  48. 29 0
      src/main/java/com/sec/xinhua/gateway/utils/SysConstants.java
  49. 82 0
      src/main/java/com/sec/xinhua/gateway/utils/URLHelper.java
  50. 73 0
      src/main/java/com/sec/xinhua/gateway/web/GatewayServlet.java
  51. 140 0
      src/main/resources/ApiSettingRepository.config
  52. 0 0
      src/main/resources/BusinessesIds.config
  53. 8 0
      src/main/resources/GatewaySettingRepository.config
  54. 2 0
      src/main/resources/allow_ip.txt
  55. 13 0
      src/main/resources/applicationContext.xml
  56. 196 0
      src/main/resources/log4j.xml
  57. 47 0
      src/main/webapp/WEB-INF/web.xml
  58. 20 0
      src/main/webapp/load.jsp
  59. 89 0
      src/test/java/com/sec/xinhua/gateway/handler/SignValidateHandlerTest.java
  60. 259 0
      src/test/java/com/sec/xinhua/gateway/web/HttpsClient.java
  61. 109 0
      src/test/java/com/sec/xinhua/gateway/web/OtherTest.java
  62. 362 0
      src/test/java/com/sec/xinhua/gateway/web/PostReqTest.java
  63. 55 0
      src/test/java/com/sec/xinhua/gateway/web/SignUtils.java

+ 232 - 0
pom.xml

@@ -0,0 +1,232 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>yuncredit-public</groupId>
+    <artifactId>sec-gateway</artifactId>
+    <packaging>war</packaging>
+    <version>1.0.0</version>
+    <name>Risk-Gateway Maven Webapp</name>
+    <url>http://maven.apache.org</url>
+
+    <properties>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
+        <java_source_version>1.7</java_source_version>
+        <java_target_version>1.7</java_target_version>
+        <file_encoding>UTF-8</file_encoding>
+        <jetty.version>9.2.2.v20140723</jetty.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.16.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jexl</artifactId>
+            <version>2.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.7.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flume.flume-ng-clients</groupId>
+            <artifactId>flume-ng-log4jappender</artifactId>
+            <version>1.5.0.1</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.rocketmq</groupId>
+            <artifactId>rocketmq-client</artifactId>
+            <version>3.1.3</version>
+        </dependency>
+        <dependency>
+            <groupId>com.101tec</groupId>
+            <artifactId>zkclient</artifactId>
+            <version>0.3</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.zookeeper</groupId>
+                    <artifactId>zookeeper</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.zookeeper</groupId>
+            <artifactId>zookeeper</artifactId>
+            <version>3.4.3</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>junit</groupId>
+                    <artifactId>junit</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>javax.jms</groupId>
+                    <artifactId>jms</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.sun.jdmk</groupId>
+                    <artifactId>jmxtools</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.sun.jmx</groupId>
+                    <artifactId>jmxri</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>dubbo</artifactId>
+            <version>2.5.3</version>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.16</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.sun.jmx</groupId>
+                    <artifactId>jmxri</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.sun.jdmk</groupId>
+                    <artifactId>jmxtools</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>javax.jms</groupId>
+                    <artifactId>jms</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.4</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.thrift</groupId>
+            <artifactId>libthrift</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+            <version>1.54</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>1.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <version>3.1.2.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>2.4.2</version>
+        </dependency>
+    </dependencies>
+
+    <!-- profile 配置 -->
+    <profiles>
+        <profile>
+            <id>test</id>
+            <properties>
+                <package.environment>test</package.environment>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+        <profile>
+            <id>online</id>
+            <properties>
+                <package.environment>online</package.environment>
+            </properties>
+        </profile>
+    </profiles>
+
+    <!-- 编译配置 -->
+    <build>
+        <filters>
+            <filter>setting/${package.environment}.properties</filter>
+        </filters>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>${java_source_version}</source>
+                    <target>${java_target_version}</target>
+                    <encoding>${file_encoding}</encoding>
+                    <showDeprecation>true</showDeprecation>
+                    <showWarnings>true</showWarnings>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.tomcat.maven</groupId>
+                <artifactId>tomcat7-maven-plugin</artifactId>
+                <version>2.0</version>
+                <configuration>
+                    <url>http://localhost:8080</url>
+                    <server>tomcat7</server>
+                    <username>admin</username>
+                    <password>1234</password>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.version}</version>
+                <configuration>
+                    <webAppSourceDirectory>${basedir}/webroot</webAppSourceDirectory>
+                    <webApp>
+                        <contextPath>/${project.artifactId}</contextPath>
+                    </webApp>
+                    <scanIntervalSeconds>100</scanIntervalSeconds>
+                    <stopKey>risk-gateway</stopKey>
+                    <stopPort>9999</stopPort>
+                    <httpConnector>
+                        <port>9090</port>
+                    </httpConnector>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 9 - 0
setting/online.properties

@@ -0,0 +1,9 @@
+
+#GatewaySettings
+zkAddress=110.88.150.66:2181,110.88.150.67:2181,110.88.150.68:2181
+runMode=online
+
+#log4j
+log.dir=/home/altman/logs/sec-gateway
+
+service.dubbo.version=1.0.0

+ 9 - 0
setting/test.properties

@@ -0,0 +1,9 @@
+
+#GatewaySettings
+zkAddress=110.88.150.72:2181
+runMode=test
+
+#log4j
+log.dir=/home/altman/logs/sec-gateway
+
+service.dubbo.version=1.0.0_test

+ 110 - 0
src/main/java/com/sec/xinhua/gateway/beans/ApiCode.java

@@ -0,0 +1,110 @@
+package com.sec.xinhua.gateway.beans;
+
+/**
+ * 网关的响应状态编码
+ */
+public enum ApiCode {
+    /**
+     * 系统部分
+     */
+    //成功
+    SUCCESS(200, "OK"),
+    //网关内部错误
+    GATEWAY_ERROR(999000, "GATEWAY_ERROR"),
+    //签名验证错误
+    SIGN_ERROR(999001, "SIGN_ERROR"),
+
+    /**
+     * API部分
+     */
+    //无效的API请求,基本是不符合格式的请求
+    API_INVALID_REQUEST(999301, "API_INVALID_REQUEST"),
+
+    //没有找到API配置信息
+    API_NOT_FOUND(999302, "API_NOT_FOUND"),
+    //API未授权
+    API_NON_AUTHORIZED(999303, "API_NON_AUTHORIZED"),
+    //API流量限制
+    //API_FLOW_LIMITED替换为:操作太频繁啦,请稍后再试
+    API_FLOW_LIMITED(999304, "操作太频繁啦,请稍后再试"),
+
+    /**
+     * 服务部分
+     */
+    //服务调用超时
+    SERVICE_TIME_OUT(999401, "SERVICE_TIME_OUT"),
+    //服务调用出现错误,例如网络断开
+    SERVICE_INVOKE_ERROR(999402, "SERVICE_INVOKE_ERROR"),
+    //没有找到服务
+    SERVICE_NOT_FOUND(999403, "SERVICE_NOT_FOUND"),
+    //服务返回格式不对
+    SERVICE_RESPONSE_FORMAT_ERROR(999404, "SERVICE_RESPONSE_FORMAT_ERROR");
+    private int    code;
+
+    private String msg;
+
+    private ApiCode(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public static enum ApiSubCode {
+
+        //黑名单限制
+        SUB_FLOW_LIMITED_BLACKIP(9993040, "api flow limited by black ip"),
+        //单机并发量限制
+        SUB_FLOW_LIMITED_CONCURRENT_COUNT(9993041, "api flow limited by concurrent count"),
+        //全局ip限制
+        SUB_FLOW_LIMITED_GLOBAL_IP_COUNT(9993042, "api flow limited by gloal ip count"),
+        //api ip限制
+        SUB_FLOW_LIMITED_API_IP_COUNT(9993043, "api flow limited by api ip count"),
+        //全局uid限制
+        SUB_FLOW_LIMITED_GLOBAL_UID_COUNT(9993044, "api flow limited by gloal uid count"),
+        //api uid限制
+        SUB_FLOW_LIMITED_API_UID_COUNT(9993045, "api flow limited by api uid count"),
+
+        SUB_INVALID_PARAM(9993010, "invalid request invalid param"),
+
+        SUB_INVALID_SIGN(9993011, "invalid request sign not equal"),
+
+        SUB_INVALID_TIMESTAMP(9993012, "invalid request time diff"),
+
+        SUB_INVALID_GET_REQUEST(9993013, "invalid request get method"),
+
+        SUB_INVALID_BODY(9993014, "invalid request body"),
+
+        //无效的apk,不能找到apkmd5
+        SUB_APP_PACKAGE_NOT_FOUND(9993015, "APP PACKAGE NOT FOUND"),
+
+        SUB_APP_PACKAGE_SID_NOT_EQUAL(9993016, "APP PACKAGE INVALID SID"),
+
+        SUB_CLIENT_SOURCE_INVALID(9993017, "INVALID CLIENT SOURCE"),
+
+        SUB_INVALID_EXP(9993018, "invalid request by expression");
+
+        private int    code;
+
+        private String msg;
+
+        private ApiSubCode(int code, String msg) {
+            this.code = code;
+            this.msg = msg;
+        }
+
+        public int getCode() {
+            return code;
+        }
+
+        public String getMsg() {
+            return msg;
+        }
+    }
+}

+ 102 - 0
src/main/java/com/sec/xinhua/gateway/beans/ApiContext.java

@@ -0,0 +1,102 @@
+package com.sec.xinhua.gateway.beans;
+
+import com.sec.xinhua.gateway.parse.RequestParam;
+import com.sec.xinhua.gateway.parse.SysParam;
+
+/**
+ * 网关请求上下文
+ *
+ */
+public class ApiContext {
+
+    private RequestParam httpParam;
+
+    private SysParam sysParam;
+
+    private SimpleApi api;
+
+    private String[]  invokeTypes;
+
+    private Object[]  invokeValues;
+
+    private Object[]  invokeLogValues; // 屏蔽掉密码(用*代替)之后
+
+    private ApiResult apiResult;
+
+    private boolean   fileUpload;
+
+    public SimpleApi getApi() {
+        return api;
+    }
+
+    public void setApi(SimpleApi api) {
+        this.api = api;
+    }
+
+    public String[] getInvokeTypes() {
+        return invokeTypes;
+    }
+
+    public void setInvokeTypes(String[] invokeTypes) {
+        this.invokeTypes = invokeTypes;
+    }
+
+    public Object[] getInvokeValues() {
+        return invokeValues;
+    }
+
+    public void setInvokeValues(Object[] invokeValues) {
+        this.invokeValues = invokeValues;
+    }
+
+    public Object[] getInvokeLogValues() {
+        return invokeLogValues;
+    }
+
+    public void setInvokeLogValues(Object[] invokeLogValues) {
+        this.invokeLogValues = invokeLogValues;
+    }
+
+    public boolean isFileUpload() {
+        return fileUpload;
+    }
+
+    public void setFileUpload(boolean fileUpload) {
+        this.fileUpload = fileUpload;
+    }
+
+    public RequestParam getHttpParam() {
+        return httpParam;
+    }
+
+    public void setHttpParam(RequestParam httpParam) {
+        this.httpParam = httpParam;
+    }
+
+    public ApiResult getApiResult() {
+        return apiResult;
+    }
+
+    public void setApiResult(ApiResult apiResult) {
+        this.apiResult = apiResult;
+    }
+
+    public SysParam getSysParam() {
+        return sysParam;
+    }
+
+    public void setSysParam(SysParam sysParam) {
+        this.sysParam = sysParam;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("ApiContext");
+        sb.append("{httpParam=");
+        sb.append(httpParam);
+        sb.append(", sysParam=");
+        sb.append(sysParam);
+        sb.append("}");
+        return sb.toString();
+    }
+}

+ 207 - 0
src/main/java/com/sec/xinhua/gateway/beans/ApiParam.java

@@ -0,0 +1,207 @@
+package com.sec.xinhua.gateway.beans;
+
+/**
+ * Created by zhangqingxin
+ * Date : 16/7/5
+ * Time : 10:44
+ */
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown=true)
+public class ApiParam {
+    private long id;
+    private long productId;//所属产品Id
+    private long apiId;//所属接口ID
+    private int paramClassification;
+    private String sourceName;//客户端需要填写参数名称
+    private int paramType;//类型 String,long int short double float boolean char byte file
+    private String destName;//dubbo服务提供方参数名称
+    private int wrapperType;//[] list set no
+    private String description;//描述
+    private String defaultValue;//默认值转换
+    private int required;//是否必须
+    private int paramOrder;//排列顺序
+    private long updateTime;//更新时间
+    private long updateUserId;
+
+
+    private long paramId;
+    //对象名称
+    private String className;
+
+    public long getApiId() {
+        return apiId;
+    }
+
+    public void setApiId(long apiId) {
+        this.apiId = apiId;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClassName(String className) {
+        this.className = StringUtils.trim(className);
+    }
+
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = StringUtils.trim(defaultValue);
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = StringUtils.trim(description);
+    }
+
+    public String getDestName() {
+        return destName;
+    }
+
+    public void setDestName(String destName) {
+        this.destName = StringUtils.trim(destName);
+    }
+
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public int getParamClassification() {
+        return paramClassification;
+    }
+
+    public void setParamClassification(int paramClassification) {
+        this.paramClassification = paramClassification;
+    }
+
+    public long getParamId() {
+        return paramId;
+    }
+
+    public void setParamId(long paramId) {
+        this.paramId = paramId;
+    }
+
+    public int getParamOrder() {
+        return paramOrder;
+    }
+
+    public void setParamOrder(int paramOrder) {
+        this.paramOrder = paramOrder;
+    }
+
+    public int getParamType() {
+        return paramType;
+    }
+
+    public void setParamType(int paramType) {
+        this.paramType = paramType;
+    }
+
+    public long getProductId() {
+        return productId;
+    }
+
+    public void setProductId(long productId) {
+        this.productId = productId;
+    }
+
+    public int getRequired() {
+        return required;
+    }
+
+    public void setRequired(int required) {
+        this.required = required;
+    }
+
+    public String getSourceName() {
+        return sourceName;
+    }
+
+    public void setSourceName(String sourceName) {
+        this.sourceName = StringUtils.trim(sourceName);
+    }
+
+    public long getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(long updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public long getUpdateUserId() {
+        return updateUserId;
+    }
+
+    public void setUpdateUserId(long updateUserId) {
+        this.updateUserId = updateUserId;
+    }
+
+    public int getWrapperType() {
+        return wrapperType;
+    }
+
+    public void setWrapperType(int wrapperType) {
+        this.wrapperType = wrapperType;
+    }
+
+    public String getParamTypeString(){
+        return ApiParamType.getByCode(paramType).getClassName();
+    }
+
+    public boolean isPlatfromParam(){
+        if(sourceName.equals("token")||sourceName.equals("api")
+                ||sourceName.equals("apiVersion")||sourceName.equals("appKey")
+                ||sourceName.equals("timestamp")||sourceName.equals("sign")
+                ||sourceName.equals("osVersion")||sourceName.equals("osType")
+                ||sourceName.equals("hwId")||sourceName.equals("appVersion")
+                ||sourceName.endsWith("mobileType")||sourceName.endsWith("clientIp")
+                ||sourceName.endsWith("requestUrl")){
+            return true;
+        }
+        return false;
+    }
+
+    public String getJson(){
+        Map<String,Object> map = new HashMap<String,Object>();
+        map.put("paramClassification", paramClassification);
+        map.put("sourceName", sourceName);
+        map.put("paramType", paramType);
+        map.put("destName", destName);
+        map.put("description", description);
+        map.put("required", required);
+        map.put("paramOrder", paramOrder);
+        map.put("defaultValue", defaultValue);
+        map.put("className", this.className);
+        String json = JSON.toJSONString(map);
+        try {
+            return URLEncoder.encode(json, "utf-8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 58 - 0
src/main/java/com/sec/xinhua/gateway/beans/ApiParamType.java

@@ -0,0 +1,58 @@
+package com.sec.xinhua.gateway.beans;
+
+
+public enum ApiParamType {
+    P_INT(10, "int", "int"),
+    P_LONG(11, "long", "long"),
+    P_SHORT(12, "short", "short"),
+    P_BYTE(13, "byte", "byte"),
+    P_CHAR(14, "char", "char"),
+    P_FLOAT(15, "float", "float"),
+    P_DOUBLE(16, "double", "double"),
+    P_BOOLEAN(17, "boolean", "boolean"),
+    W_INT(20, "Integer", "java.lang.Integer"),
+    W_LONG(21, "Long", "java.lang.Long"),
+    W_SHORT(22, "Short", "java.lang.Short"),
+    W_BYTE(23, "Byte", "java.lang.Byte"),
+    W_CHAR(24, "Character", "java.lang.Character"),
+    W_FLOAT(25, "Float", "java.lang.Float"),
+    W_DOUBLE(26, "Double", "java.lang.Double"),
+    W_BOOLEAN(27, "Boolean", "java.lang.Boolean"),
+    BYTE_ARRAY(40, "[byte", "[B"),
+    STRING(50, "String", "java.lang.String"),
+    OBJECT(60, "Object", "json object"),
+    List(60, "List", "java.util.List"),
+    MAP(70, "Map", "java.util.Map");
+
+    private int code;
+    private String name;
+    private String className;
+
+    private ApiParamType(int code, String name, String className) {
+        this.code = code;
+        this.name = name;
+        this.className = className;
+    }
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public String getClassName() {
+        return this.className;
+    }
+
+    public static ApiParamType getByCode(int code) {
+        ApiParamType[] values = values();
+        for (ApiParamType v : values) {
+            if (v.getCode() == code) {
+                return v;
+            }
+        }
+        return P_INT;
+    }
+}

+ 59 - 0
src/main/java/com/sec/xinhua/gateway/beans/ApiResult.java

@@ -0,0 +1,59 @@
+package com.sec.xinhua.gateway.beans;
+
+public class ApiResult {
+
+    private int    apiCode;
+
+    private String apiMsg;
+
+    private Object data;
+
+    private Object originResult;
+
+    public ApiResult() {
+
+    }
+
+    public ApiResult(int apiCode, String apiMsg) {
+        this.apiCode = apiCode;
+        this.apiMsg = apiMsg;
+    }
+
+    public ApiResult(int apiCode, String apiMsg, Object data) {
+        this.apiCode = apiCode;
+        this.apiMsg = apiMsg;
+        this.data = data;
+    }
+
+    public int getApiCode() {
+        return apiCode;
+    }
+
+    public void setApiCode(int apiCode) {
+        this.apiCode = apiCode;
+    }
+
+    public String getApiMsg() {
+        return apiMsg;
+    }
+
+    public void setApiMsg(String apiMsg) {
+        this.apiMsg = apiMsg;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public Object getOriginResult() {
+        return originResult;
+    }
+
+    public void setOriginResult(Object originResult) {
+        this.originResult = originResult;
+    }
+}

+ 129 - 0
src/main/java/com/sec/xinhua/gateway/beans/ApiResultCache.java

@@ -0,0 +1,129 @@
+package com.sec.xinhua.gateway.beans;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.alibaba.fastjson.JSON;
+import com.sec.xinhua.gateway.config.GatewaySettingRepository;
+import com.sec.xinhua.gateway.utils.URLHelper;
+
+/**
+ * API错误提示的缓存
+ *
+ */
+public class ApiResultCache {
+
+    private static Map<Integer, ApiResult> API_RESULT_CACHE       = new HashMap<Integer, ApiResult>();
+
+    private static Map<Integer, String>    API_RESULT_CHARS_CACHE = new HashMap<Integer, String>();
+
+    static {
+        {
+            ApiResult result = new ApiResult(ApiCode.GATEWAY_ERROR.getCode(), ApiCode.GATEWAY_ERROR.getMsg());
+            API_RESULT_CACHE.put(ApiCode.GATEWAY_ERROR.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.GATEWAY_ERROR.getCode(), JSON.toJSONString(result));
+        }
+
+        {
+            ApiResult result = new ApiResult(ApiCode.API_INVALID_REQUEST.getCode(),
+                ApiCode.API_INVALID_REQUEST.getMsg());
+            API_RESULT_CACHE.put(ApiCode.API_INVALID_REQUEST.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.API_INVALID_REQUEST.getCode(), JSON.toJSONString(result));
+        }
+
+        {
+            ApiResult result = new ApiResult(ApiCode.API_NOT_FOUND.getCode(), ApiCode.API_NOT_FOUND.getMsg());
+            API_RESULT_CACHE.put(ApiCode.API_NOT_FOUND.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.API_NOT_FOUND.getCode(), JSON.toJSONString(result));
+        }
+
+        {
+            ApiResult result = new ApiResult(ApiCode.API_NON_AUTHORIZED.getCode(), ApiCode.API_NON_AUTHORIZED.getMsg());
+            API_RESULT_CACHE.put(ApiCode.API_NON_AUTHORIZED.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.API_NON_AUTHORIZED.getCode(), JSON.toJSONString(result));
+        }
+
+        {
+            ApiResult result = new ApiResult(ApiCode.API_FLOW_LIMITED.getCode(), ApiCode.API_FLOW_LIMITED.getMsg());
+            API_RESULT_CACHE.put(ApiCode.API_FLOW_LIMITED.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.API_FLOW_LIMITED.getCode(), JSON.toJSONString(result));
+        }
+
+        {
+            ApiResult result = new ApiResult(ApiCode.SERVICE_TIME_OUT.getCode(), ApiCode.SERVICE_TIME_OUT.getMsg());
+            API_RESULT_CACHE.put(ApiCode.SERVICE_TIME_OUT.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.SERVICE_TIME_OUT.getCode(), JSON.toJSONString(result));
+        }
+
+        {
+            ApiResult result = new ApiResult(ApiCode.SERVICE_INVOKE_ERROR.getCode(),
+                ApiCode.SERVICE_INVOKE_ERROR.getMsg());
+            API_RESULT_CACHE.put(ApiCode.SERVICE_INVOKE_ERROR.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.SERVICE_INVOKE_ERROR.getCode(), JSON.toJSONString(result));
+        }
+
+        {
+            ApiResult result = new ApiResult(ApiCode.SERVICE_NOT_FOUND.getCode(), ApiCode.SERVICE_NOT_FOUND.getMsg());
+            API_RESULT_CACHE.put(ApiCode.SERVICE_NOT_FOUND.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.SERVICE_NOT_FOUND.getCode(), JSON.toJSONString(result));
+        }
+
+        {
+            ApiResult result = new ApiResult(ApiCode.SERVICE_RESPONSE_FORMAT_ERROR.getCode(),
+                ApiCode.SERVICE_RESPONSE_FORMAT_ERROR.getMsg());
+            API_RESULT_CACHE.put(ApiCode.SERVICE_RESPONSE_FORMAT_ERROR.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.SERVICE_RESPONSE_FORMAT_ERROR.getCode(), JSON.toJSONString(result));
+        }
+
+        {
+            ApiResult result = new ApiResult(ApiCode.SIGN_ERROR.getCode(), ApiCode.SIGN_ERROR.getMsg());
+            API_RESULT_CACHE.put(ApiCode.SIGN_ERROR.getCode(), result);
+            API_RESULT_CHARS_CACHE.put(ApiCode.SIGN_ERROR.getCode(), JSON.toJSONString(result));
+        }
+
+    }
+
+    public static ApiResult getApiResult(ApiCode apiCode) {
+        ApiResult result = API_RESULT_CACHE.get(apiCode.getCode());
+        if (result == null) {
+            result = new ApiResult(apiCode.getCode(), apiCode.getMsg(), new HashMap<String, String>());
+        }
+        return result;
+    }
+
+    public static ApiResult getApiResult(ApiCode apiCode, String detail) {
+        //线上模式不输出详细信息
+        if (GatewaySettingRepository.getInstance().getObject().getRunMode().equalsIgnoreCase("online")) {
+            return getApiResult(apiCode);
+        }
+
+        //详细信息为空不输出
+        if (StringUtils.isEmpty(detail)) {
+            return getApiResult(apiCode);
+        }
+        ApiResult result = new ApiResult(apiCode.getCode(), apiCode.getMsg() + "; " + detail);
+        return result;
+    }
+
+    public static ApiResult getApiResult(ApiCode apiCode, String appendMsg, Throwable e) {
+        //线上模式不输出详细信息
+        if (GatewaySettingRepository.getInstance().getObject().getRunMode().equalsIgnoreCase("online")) {
+            return getApiResult(apiCode);
+        }
+
+        //详细信息为空不输出
+        if (e == null) {
+            return getApiResult(apiCode);
+        }
+
+        ApiResult result = new ApiResult(apiCode.getCode(), apiCode.getMsg() + "; " + appendMsg + ";"
+                                                            + URLHelper.getStackTrace(e));
+        return result;
+    }
+
+    public static String getApiResultChars(ApiCode apiCode) {
+        return API_RESULT_CHARS_CACHE.get(apiCode.getCode());
+    }
+}

+ 48 - 0
src/main/java/com/sec/xinhua/gateway/beans/GatewayEnv.java

@@ -0,0 +1,48 @@
+package com.sec.xinhua.gateway.beans;
+
+/**
+ * Created by zhangqingxin
+ * Date : 16/7/5
+ * Time : 11:45
+ */
+public class GatewayEnv{
+    private String name;
+
+    private String ip;
+
+    private String requestUrl;
+
+    private String remark;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(String ip) {
+        this.ip = ip;
+    }
+
+    public String getRequestUrl() {
+        return requestUrl;
+    }
+
+    public void setRequestUrl(String requestUrl) {
+        this.requestUrl = requestUrl;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+}

+ 141 - 0
src/main/java/com/sec/xinhua/gateway/beans/GatewaySetting.java

@@ -0,0 +1,141 @@
+package com.sec.xinhua.gateway.beans;
+
+/**
+ * 网关配置
+ *
+ * @author xuzhaopeng
+ * @version $Id: ServiceRegistry.java, v 0.1 2015年4月7日 下午4:50:27 Administrator Exp $
+ */
+public class GatewaySetting {
+
+    /**
+     * 环境名称
+     */
+    private String envName;
+
+    private String name;
+
+    /**
+     * dubbo注册中心地址
+     */
+    private String zkAddress;
+
+    /**
+     * 是否记录客户端对Risk的请求
+     */
+    private boolean logRequest;
+
+    /**
+     * 是否记录Risk对客户端的响应结果
+     */
+    private boolean logResponse;
+
+    /**
+     * 是否记录Risk对dubbo的调用请求和结果
+     */
+    private boolean logInvokeResult;
+
+    /**
+     * 网关运行模式
+     */
+    private String runMode = "online";
+
+    /**
+     * 网关返回值按dubbo返回,不添加apiCode和apiMsg
+     */
+    private String originResult;
+
+    public GatewaySetting() {
+
+    }
+
+    public GatewaySetting(String name, String zkAddress) {
+        this.name = name;
+        this.zkAddress = zkAddress;
+    }
+
+    public GatewaySetting(String name, String zkAddress, boolean logRequest, boolean logResponse) {
+        this.name = name;
+        this.zkAddress = zkAddress;
+        this.logRequest = logRequest;
+        this.logResponse = logResponse;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getZkAddress() {
+        return zkAddress;
+    }
+
+    public void setZkAddress(String zkAddress) {
+        this.zkAddress = zkAddress;
+    }
+
+    public boolean isLogRequest() {
+        return logRequest;
+    }
+
+    public void setLogRequest(boolean logRequest) {
+        this.logRequest = logRequest;
+    }
+
+    public boolean isLogResponse() {
+        return logResponse;
+    }
+
+    public void setLogResponse(boolean logResponse) {
+        this.logResponse = logResponse;
+    }
+
+    public boolean isLogInvokeResult() {
+        return logInvokeResult;
+    }
+
+    public void setLogInvokeResult(boolean logInvokeResult) {
+        this.logInvokeResult = logInvokeResult;
+    }
+
+    public String getRunMode() {
+        return runMode;
+    }
+
+    public void setRunMode(String runMode) {
+        this.runMode = runMode;
+    }
+
+    public String getOriginResult() {
+        return originResult;
+    }
+
+    public void setOriginResult(String originResult) {
+        this.originResult = originResult;
+    }
+
+    public String getEnvName() {
+        return envName;
+    }
+
+    public void setEnvName(String envName) {
+        this.envName = envName;
+    }
+
+    @Override
+    public String toString() {
+        return "GatewaySetting{" +
+                "envName='" + envName + '\'' +
+                ", name='" + name + '\'' +
+                ", zkAddress='" + zkAddress + '\'' +
+                ", logRequest=" + logRequest +
+                ", logResponse=" + logResponse +
+                ", logInvokeResult=" + logInvokeResult +
+                ", runMode='" + runMode + '\'' +
+                ", originResult='" + originResult + '\'' +
+                '}';
+    }
+}

+ 28 - 0
src/main/java/com/sec/xinhua/gateway/beans/InvokeParam.java

@@ -0,0 +1,28 @@
+package com.sec.xinhua.gateway.beans;
+
+public class InvokeParam {
+    private String type;
+
+    private Object value;
+
+    public InvokeParam(String type, Object value) {
+        this.type = type;
+        this.value = value;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+}

+ 99 - 0
src/main/java/com/sec/xinhua/gateway/beans/SimpleApi.java

@@ -0,0 +1,99 @@
+package com.sec.xinhua.gateway.beans;
+
+
+import java.util.List;
+
+public class SimpleApi {
+
+    private String envName;
+
+    private String apiName;       //api名称,客户端使用
+
+    private String apiVersion;    //api版本,客户端使用
+
+    private String serviceName;   //接口class,dubbo服务提供方使用
+
+    private String serviceVersion; //接口版本,dubbo服务提供方使用
+
+    private String method;        //接口方法
+
+    private Integer timeout;
+
+    private String defaultResult;
+
+    private List<SimpleApiParam> params;
+
+    public String getApiName() {
+        return apiName;
+    }
+
+    public void setApiName(String apiName) {
+        this.apiName = apiName;
+    }
+
+    public String getApiVersion() {
+        return apiVersion;
+    }
+
+    public void setApiVersion(String apiVersion) {
+        this.apiVersion = apiVersion;
+    }
+
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public void setServiceName(String serviceName) {
+        this.serviceName = serviceName;
+    }
+
+    public String getServiceVersion() {
+        return serviceVersion;
+    }
+
+    public void setServiceVersion(String serviceVersion) {
+        this.serviceVersion = serviceVersion;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public void setMethod(String method) {
+        this.method = method;
+    }
+
+    public List<SimpleApiParam> getParams() {
+        return params;
+    }
+
+    public void setParams(List<SimpleApiParam> params) {
+        this.params = params;
+    }
+
+    public Integer getTimeout() {
+        return timeout;
+    }
+
+    public void setTimeout(Integer timeout) {
+        this.timeout = timeout;
+    }
+
+    public String getDefaultResult() {
+        return defaultResult;
+    }
+
+    public void setDefaultResult(String defaultResult) {
+        this.defaultResult = defaultResult;
+    }
+
+    public String getEnvName() {
+        return envName;
+    }
+
+    public void setEnvName(String envName) {
+        this.envName = envName;
+    }
+
+
+}

+ 106 - 0
src/main/java/com/sec/xinhua/gateway/beans/SimpleApiParam.java

@@ -0,0 +1,106 @@
+package com.sec.xinhua.gateway.beans;
+
+
+import java.io.Serializable;
+import java.util.List;
+
+public class SimpleApiParam implements Serializable {
+
+
+    private String sourceName;  //客户端需要填写参数名称
+
+    private int paramType;   //类型 String,long int short double float boolean char byte file
+
+    private String destName;    //dubbo服务提供方参数名称
+
+    private String defaultValue; //默认值转换
+
+    private int required;    //是否必须
+
+    //对象class名称
+    private String className;
+
+    //对象字段列表,无序
+    private List<SimpleApiParam> fields;
+
+    public static SimpleApiParam resolve(ApiParam apiParam) {
+        SimpleApiParam sap = new SimpleApiParam();
+
+        sap.setSourceName(apiParam.getSourceName());
+        sap.setParamType(apiParam.getParamType());
+        sap.setDestName(apiParam.getDestName());
+        sap.setDefaultValue(apiParam.getDefaultValue());
+        sap.setRequired(apiParam.getRequired());
+
+        return sap;
+    }
+
+    public String getSourceName() {
+        return sourceName;
+    }
+
+    public void setSourceName(String sourceName) {
+        this.sourceName = sourceName;
+    }
+
+    public int getParamType() {
+        return paramType;
+    }
+
+    public void setParamType(int paramType) {
+        this.paramType = paramType;
+    }
+
+    public String getDestName() {
+        return destName;
+    }
+
+    public void setDestName(String destName) {
+        this.destName = destName;
+    }
+
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    public int getRequired() {
+        return required;
+    }
+
+    public void setRequired(int required) {
+        this.required = required;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClassName(String className) {
+        this.className = className;
+    }
+
+    public List<SimpleApiParam> getFields() {
+        return fields;
+    }
+
+    public void setFields(List<SimpleApiParam> fields) {
+        this.fields = fields;
+    }
+
+    @Override
+    public String toString() {
+        return "SimpleApiParam{" +
+                "sourceName='" + sourceName + '\'' +
+                ", paramType=" + paramType +
+                ", destName='" + destName + '\'' +
+                ", defaultValue='" + defaultValue + '\'' +
+                ", required=" + required +
+                ", className='" + className + '\'' +
+                ", fields=" + fields +
+                '}';
+    }
+}

+ 59 - 0
src/main/java/com/sec/xinhua/gateway/config/ApiSettingRepository.java

@@ -0,0 +1,59 @@
+
+package com.sec.xinhua.gateway.config;
+
+import com.sec.xinhua.gateway.beans.SimpleApi;
+
+import java.util.List;
+
+import com.alibaba.fastjson.JSON;
+import com.sec.xinhua.gateway.config.local.FileConfigLoader;
+
+
+/**
+ * Api接口的配置Load
+ */
+public class ApiSettingRepository {
+
+    private static ApiSettingRepository INSTANCE = new ApiSettingRepository();
+
+    private List<SimpleApi> items;
+
+    final protected String configFilePath = getConfigDir() + this.getClass().getSimpleName() + ".config";
+
+    protected ConfigLoader configLoader;
+
+    public ApiSettingRepository() {
+        configLoader = new FileConfigLoader(configFilePath);
+        this.init();
+    }
+
+    public static ApiSettingRepository getInstance() {
+        return INSTANCE;
+    }
+
+    protected String getConfigDir() {
+        return ApiSettingRepository.class.getResource("/").getPath();
+    }
+
+    protected Object getItem() {
+        return items;
+    }
+
+    public List<SimpleApi> getObject() {
+        return items;
+    }
+
+    public List<SimpleApi> getObject(String key) {
+
+        return null;
+    }
+
+    public void init() {
+        try {
+            String content = (String) configLoader.load();
+            items = JSON.parseArray(content, SimpleApi.class);
+        } catch (Exception e) {
+        }
+    }
+
+}

+ 11 - 0
src/main/java/com/sec/xinhua/gateway/config/ConfigLoader.java

@@ -0,0 +1,11 @@
+package com.sec.xinhua.gateway.config;
+
+
+/**
+ * 基于文件的配置加载器
+ *
+ */
+public interface ConfigLoader {
+
+    Object load();
+}

+ 45 - 0
src/main/java/com/sec/xinhua/gateway/config/ConfigRepositoryFactory.java

@@ -0,0 +1,45 @@
+package com.sec.xinhua.gateway.config;
+
+import com.sec.xinhua.gateway.beans.SimpleApi;
+import com.sec.xinhua.gateway.config.remote.ApiRemoteRepository;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ConfigRepositoryFactory {
+
+    public static void initGatewaySetting() {
+        //初始化基本配置
+        initGatewaySettingRepository();
+    }
+
+    public static Map<String, SimpleApi> simpleApiMap = new HashMap<String, SimpleApi>();
+
+    public static ApiRemoteRepository getApiRepository() {
+        return ApiRemoteRepository.getInstance();
+    }
+
+    public static GatewaySettingRepository initGatewaySettingRepository() {
+        return GatewaySettingRepository.getInstance();
+    }
+
+    public static Map<String, SimpleApi> getAllApi() {
+        if (simpleApiMap.size() < 1) {
+            refreshMap();
+        }
+        return simpleApiMap;
+    }
+
+    /**
+     * 刷新Map
+     */
+    public static void refreshMap() {
+        List<SimpleApi> apiList = ApiSettingRepository.getInstance().getObject();
+        if (apiList != null && apiList.size() > 0) {
+            for (SimpleApi api : apiList) {
+                simpleApiMap.put(api.getApiName() + "_" + api.getApiVersion(), api);
+            }
+        }
+    }
+}

+ 50 - 0
src/main/java/com/sec/xinhua/gateway/config/GatewaySettingRepository.java

@@ -0,0 +1,50 @@
+package com.sec.xinhua.gateway.config;
+
+import com.alibaba.fastjson.JSON;
+import com.sec.xinhua.gateway.beans.GatewaySetting;
+import com.sec.xinhua.gateway.config.local.FileConfigLoader;
+
+/**
+ * 网关的全局配置
+ */
+public class GatewaySettingRepository {
+
+    private static GatewaySettingRepository INSTANCE = new GatewaySettingRepository();
+
+    private GatewaySetting item;
+
+    final protected String configFilePath = getConfigDir() + this.getClass().getSimpleName() + ".config";
+
+    protected ConfigLoader configLoader;
+
+    public static GatewaySettingRepository getInstance() {
+        return INSTANCE;
+    }
+
+    public GatewaySettingRepository() {
+        configLoader = new FileConfigLoader(configFilePath);
+        init();
+    }
+
+    protected String getConfigDir() {
+        return GatewaySettingRepository.class.getResource("/").getPath();
+    }
+
+    public GatewaySetting getObject() {
+        return item;
+    }
+
+    public void init() {
+        try {
+            String content = (String) configLoader.load();
+            item = JSON.parseObject(content, GatewaySetting.class);
+        } catch (Exception e) {
+        }
+    }
+
+    public static void main(String[] args) {
+        GatewaySettingRepository.getInstance();
+    }
+
+
+}

+ 152 - 0
src/main/java/com/sec/xinhua/gateway/config/local/FileConfigLoader.java

@@ -0,0 +1,152 @@
+package com.sec.xinhua.gateway.config.local;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.alibaba.fastjson.JSON;
+import com.sec.xinhua.gateway.config.ConfigLoader;
+import com.sec.xinhua.gateway.utils.SysConstants;
+
+/**
+ * 基于文件的配置加载器
+ *
+ */
+public class FileConfigLoader implements ConfigLoader {
+
+    protected String filePath;
+
+    public FileConfigLoader(String filePath) {
+        this.filePath = filePath;
+    }
+
+    @Override
+    public String toString() {
+        return "[FileConfigLoader] file:" + filePath;
+    }
+
+    @Override
+    public String load() {
+        File file = new File(filePath);
+        if (file.exists()) {
+            return readFile(file);
+        } else {
+            try {
+                file.createNewFile();
+            } catch (IOException e) {
+            }
+        }
+        return null;
+    }
+
+    public boolean flush(Object obj) {
+        return writeFile(JSON.toJSONString(obj, true), filePath);
+    }
+
+    protected boolean writeFile(final String content, final String fileName) {
+        boolean result = true;
+        try {
+
+            String tmpFile = fileName + ".tmp";
+            writeFileNotSafe(content, tmpFile);
+
+            String bakFile = fileName + ".bak";
+            String prevContent = readFile(new File(fileName));
+            if (prevContent != null) {
+                writeFileNotSafe(prevContent, bakFile);
+            }
+
+            File file = new File(fileName);
+            file.delete();
+
+            file = new File(tmpFile);
+            file.renameTo(new File(fileName));
+        } catch (Exception e) {
+            result = false;
+        }
+        return result;
+    }
+
+    protected void writeFileNotSafe(final String str, final String fileName) throws IOException {
+        File file = new File(fileName);
+        File fileParent = file.getParentFile();
+        if (fileParent != null) {
+            fileParent.mkdirs();
+        }
+        FileWriter fileWriter = null;
+
+        try {
+            fileWriter = new FileWriter(file);
+            fileWriter.write(str);
+        } catch (IOException e) {
+            throw e;
+        } finally {
+            if (fileWriter != null) {
+                try {
+                    fileWriter.close();
+                } catch (IOException e) {
+                    throw e;
+                }
+            }
+        }
+    }
+
+    protected String readFile(final URL url) {
+        InputStream in = null;
+        String result = null;
+        try {
+            URLConnection urlConnection = url.openConnection();
+            urlConnection.setUseCaches(false);
+            in = urlConnection.getInputStream();
+            result = readFile(in);
+        } catch (Exception e) {
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+
+        return result;
+    }
+
+    protected String readFile(final File file) {
+        if (file == null) {
+            return null;
+        }
+
+        String result = null;
+        if (file.exists()) {
+            InputStream in = null;
+            try {
+                in = new FileInputStream(file);
+                result = readFile(in);
+            } catch (Exception e) {
+            } finally {
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+    protected String readFile(final InputStream in) throws IOException, UnsupportedEncodingException {
+        int len = in.available();
+        byte[] data = new byte[len];
+        in.read(data, 0, len);
+        return new String(data, SysConstants.ENCODE);
+    }
+
+}

+ 50 - 0
src/main/java/com/sec/xinhua/gateway/config/remote/ApiRemoteRepository.java

@@ -0,0 +1,50 @@
+package com.sec.xinhua.gateway.config.remote;
+
+
+import com.sec.xinhua.gateway.beans.SimpleApi;
+import com.sec.xinhua.gateway.config.ConfigRepositoryFactory;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * API本地配置仓库
+ *
+ * @author zhangqingxin
+ * @version $Id: ApiRemoteRepository.java, v 0.1 2016年7月4日 下午5:39:03 Administrator Exp $
+ */
+public class ApiRemoteRepository {
+
+    private static ApiRemoteRepository INSTANCE = new ApiRemoteRepository();
+
+    private Map<String, SimpleApi> items = new HashMap<String, SimpleApi>();
+
+    public static ApiRemoteRepository getInstance() {
+        return INSTANCE;
+    }
+
+    public ApiRemoteRepository() {
+        this.init();
+    }
+
+    public SimpleApi getObject(String key) {
+        return ConfigRepositoryFactory.simpleApiMap.get(key);
+    }
+
+    public void init() {
+        items = ConfigRepositoryFactory.getAllApi();
+    }
+
+    public static void main(String[] args) {
+        INSTANCE.init();
+    }
+
+    public Set<String> keySet() {
+        HashSet<String> set = new HashSet<String>();
+        set.addAll(items.keySet());
+        return set;
+    }
+
+}

+ 13 - 0
src/main/java/com/sec/xinhua/gateway/handler/ApiHandler.java

@@ -0,0 +1,13 @@
+package com.sec.xinhua.gateway.handler;
+
+import com.sec.xinhua.gateway.beans.ApiContext;
+import com.sec.xinhua.gateway.beans.ApiResult;
+import com.sec.xinhua.gateway.utils.ApiHandlerException;
+
+/**
+ * handler定义
+ *
+ */
+public interface ApiHandler {
+    ApiResult handle(ApiContext context) throws ApiHandlerException;
+}

+ 9 - 0
src/main/java/com/sec/xinhua/gateway/handler/ApiHandlerChain.java

@@ -0,0 +1,9 @@
+package com.sec.xinhua.gateway.handler;
+
+import com.sec.xinhua.gateway.beans.ApiContext;
+import com.sec.xinhua.gateway.beans.ApiResult;
+
+public interface ApiHandlerChain {
+
+    ApiResult doHandle(ApiContext apiContext);
+}

+ 145 - 0
src/main/java/com/sec/xinhua/gateway/handler/ApiParamValueConvertor.java

@@ -0,0 +1,145 @@
+package com.sec.xinhua.gateway.handler;
+
+import com.sec.xinhua.gateway.beans.ApiParamType;
+import com.sec.xinhua.gateway.utils.ApiHandlerException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+public class ApiParamValueConvertor {
+
+    private static final Log logger = LogFactory.getLog("RiskGateway");
+
+    public static Object convert(Object httpValue, String name, int type) throws ApiHandlerException {
+        Object invokeValue = null;
+        try {
+
+            //String
+            if (type == ApiParamType.STRING.getCode()) {
+                invokeValue = httpValue;
+            }
+            //说明:使用blank判断,避免客户端或者测试用例使用空字符串
+            //int 
+            else if (type == ApiParamType.P_INT.getCode()) {
+                invokeValue = Integer.parseInt(httpValue.toString());
+            } else if (type == ApiParamType.W_INT.getCode()) {
+                if (httpValue == null || StringUtils.isBlank(httpValue.toString())) {
+                    invokeValue = null;
+                } else {
+                    invokeValue = Integer.parseInt(httpValue.toString());
+                }
+            }
+
+            //double
+            else if (type == ApiParamType.P_DOUBLE.getCode()) {
+                invokeValue = Double.parseDouble(httpValue.toString());
+            } else if (type == ApiParamType.W_DOUBLE.getCode()) {
+                if (httpValue == null || StringUtils.isBlank(httpValue.toString())) {
+                    invokeValue = null;
+                } else {
+                    invokeValue = Double.parseDouble(httpValue.toString());
+                }
+            }
+
+            //byte
+            else if (type == ApiParamType.P_BYTE.getCode()) {
+                invokeValue = Byte.parseByte(httpValue.toString());
+            } else if (type == ApiParamType.W_BYTE.getCode()) {
+                if (httpValue == null || StringUtils.isBlank(httpValue.toString())) {
+                    invokeValue = null;
+                } else {
+                    invokeValue = Byte.parseByte(httpValue.toString());
+                }
+            }
+
+            //float
+            else if (type == ApiParamType.P_FLOAT.getCode()) {
+                invokeValue = Float.parseFloat(httpValue.toString());
+            } else if (type == ApiParamType.W_FLOAT.getCode()) {
+                if (httpValue == null || StringUtils.isBlank(httpValue.toString())) {
+                    invokeValue = null;
+                } else {
+                    invokeValue = Float.parseFloat(httpValue.toString());
+                }
+            }
+
+            //long
+            else if (type == ApiParamType.P_LONG.getCode()) {
+                invokeValue = Long.parseLong(httpValue.toString());
+            } else if (type == ApiParamType.W_LONG.getCode()) {
+                if (httpValue == null || StringUtils.isBlank(httpValue.toString())) {
+                    invokeValue = null;
+                } else {
+                    invokeValue = Long.parseLong(httpValue.toString());
+                }
+            }
+
+            //short
+            else if (type == ApiParamType.P_SHORT.getCode()) {
+                invokeValue = Short.parseShort(httpValue.toString());
+            } else if (type == ApiParamType.W_SHORT.getCode()) {
+                if (httpValue == null || StringUtils.isBlank(httpValue.toString())) {
+                    invokeValue = null;
+                } else {
+                    invokeValue = Short.parseShort(httpValue.toString());
+                }
+            }
+
+            //boolean
+            else if (type == ApiParamType.P_BOOLEAN.getCode()) {
+                String boolStr = httpValue.toString().trim();
+                //修复boolean parse异常
+                ApiParamType apt = ApiParamType.getByCode(type);
+                if (StringUtils.isBlank(boolStr)) {
+
+                    throw new ApiHandlerException("Parse parameter error;type:"
+                                                  + (apt == null ? type : apt.getClassName()) + ",name:" + name
+                                                  + ",value:" + httpValue);
+                } else {
+                    if (boolStr.equalsIgnoreCase("true")) {
+                        invokeValue = true;
+                    } else if (boolStr.equalsIgnoreCase("false")) {
+                        invokeValue = false;
+                    } else {
+                        throw new ApiHandlerException("value is not type:'" + apt.getClassName() + ", param name:"
+                                                      + name + ",param value:" + boolStr);
+                    }
+                }
+            } else if (type == ApiParamType.W_BOOLEAN.getCode()) {
+                ApiParamType apt = ApiParamType.getByCode(type);
+                if (httpValue == null) {
+                    invokeValue = null;
+                } else {
+                    String boolStr = httpValue.toString();
+                    //修正
+                    if (StringUtils.isBlank(httpValue.toString())) {
+                        invokeValue = null;
+                    } else {
+                        if (boolStr.equalsIgnoreCase("true")) {
+                            invokeValue = Boolean.TRUE;
+                        } else if (boolStr.equalsIgnoreCase("false")) {
+                            invokeValue = Boolean.FALSE;
+                        } else {
+                            throw new ApiHandlerException("value is not type:'" + apt.getClassName() + ", param name:"
+                                                          + name + ",param value:" + boolStr);
+                        }
+                    }
+                }
+            } else {
+                logger.error("Unsuported parametertype:'" + type + ", param name:" + name);
+                throw new ApiHandlerException("Unsuported parametertype:'" + type + ", param name:" + name);
+            }
+        } catch (Exception e) {
+            if (e instanceof ApiHandlerException) {
+                throw (ApiHandlerException) e;
+            }
+
+            ApiParamType apt = ApiParamType.getByCode(type);
+            throw new ApiHandlerException("Parse parameter error;type:" + (apt == null ? type : apt.getClassName())
+                                          + ",name:" + name + ",value:" + httpValue, e);
+        }
+
+        return invokeValue;
+    }
+}

+ 69 - 0
src/main/java/com/sec/xinhua/gateway/handler/DefaultApiHandlerChain.java

@@ -0,0 +1,69 @@
+package com.sec.xinhua.gateway.handler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.sec.xinhua.gateway.beans.ApiCode;
+import com.sec.xinhua.gateway.beans.ApiContext;
+import com.sec.xinhua.gateway.beans.ApiResult;
+import com.sec.xinhua.gateway.beans.ApiResultCache;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * 默认的的handler调用链
+ *
+ */
+public class DefaultApiHandlerChain implements ApiHandlerChain {
+
+    private static final Log logger = LogFactory.getLog("errorLogger");
+
+    private static List<ApiHandler> HANDLERS;
+
+    private static DefaultApiHandlerChain instance = new DefaultApiHandlerChain();
+
+    static {
+        HANDLERS = new ArrayList<ApiHandler>();
+        /**
+         * 参数校验
+         */
+        HANDLERS.add(new SysParamValidateHandler());
+        /**
+         * dubbo参数转换
+         */
+        HANDLERS.add(new DubboArgumentConvertHandler());
+        /**
+         * dubbo服务调用
+         */
+        HANDLERS.add(new DubboServiceInvokeHandler());
+    }
+
+    public static DefaultApiHandlerChain getInstance() {
+        return instance;
+    }
+
+    @Override
+    public ApiResult doHandle(ApiContext apiContext) {
+        ApiResult apiResult = null;
+        try {
+            for (int i = 0; i < HANDLERS.size(); i++) {
+                apiResult = HANDLERS.get(i).handle(apiContext);
+                if (apiResult != null) {
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            String error = "[Do handler error]";
+            logger.error(error, e);
+            apiResult = ApiResultCache.getApiResult(ApiCode.GATEWAY_ERROR, error, null);
+        }
+
+        //所有handler都处理完了,结果必须不能为空
+        if (apiResult == null) {
+            String error = "[Do handler error]All handler execute finished,but apiResult was null";
+            logger.error(error);
+            apiResult = ApiResultCache.getApiResult(ApiCode.GATEWAY_ERROR, error);
+        }
+        return apiResult;
+    }
+}

+ 190 - 0
src/main/java/com/sec/xinhua/gateway/handler/DubboArgumentConvertHandler.java

@@ -0,0 +1,190 @@
+package com.sec.xinhua.gateway.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.sec.xinhua.gateway.beans.*;
+import com.sec.xinhua.gateway.utils.ApiHandlerException;
+import com.sec.xinhua.gateway.utils.ApiParamTypeCache;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * dubbo參數映射
+ *
+ * @author zhangqx
+ * @version $Id: DubboArgumentConvertHandler.java, v 0.1 2015年12月9日 下午3:43:21 zhangqx Exp $
+ */
+public class DubboArgumentConvertHandler implements ApiHandler {
+    private static final Log logger = LogFactory.getLog("errorLogger");
+
+    @Override
+    public ApiResult handle(ApiContext apiContext) {
+        if (apiContext.getApi().getParams() == null) {
+            apiContext.setInvokeTypes(null);
+            apiContext.setInvokeValues(null);
+            return null;
+        }
+        List<SimpleApiParam> apiParams = apiContext.getApi().getParams();
+        String[] invokeTypes = new String[apiParams.size()];
+        Object[] invokeValues = new Object[apiParams.size()];
+
+        for (int i = 0; i < apiParams.size(); i++) {
+            try {
+                InvokeParam invokeParam = convert(apiParams.get(i), apiContext);
+                invokeTypes[i] = invokeParam.getType();
+                invokeValues[i] = invokeParam.getValue();
+            } catch (ApiHandlerException e) {
+                logger.info("Parse api param error", e);
+                return ApiResultCache.getApiResult(ApiCode.API_INVALID_REQUEST, e.getMessage());
+            }
+        }
+        apiContext.setInvokeTypes(invokeTypes);
+        apiContext.setInvokeValues(invokeValues);
+        return null;
+    }
+
+    private InvokeParam convert(SimpleApiParam param, ApiContext apiContext) throws ApiHandlerException {
+        if (param.getParamType() == ApiParamType.BYTE_ARRAY.getCode()) {
+            return convertByteArray(apiContext, param);
+        } else if (param.getParamType() == ApiParamType.MAP.getCode()) {
+            return convertMapParam(apiContext, param);
+        } else if (param.getParamType() == ApiParamType.List.getCode()) {
+            return convertListParam(apiContext, param);
+        } else {
+            Object httpValue = apiContext.getHttpParam().getParameter(param.getSourceName());
+            return convertCommon(param, httpValue);
+        }
+    }
+
+    /**
+     * 解析byte[] 类型
+     *
+     * @param apiContext
+     * @param param
+     * @return
+     */
+    private InvokeParam convertByteArray(ApiContext apiContext, SimpleApiParam param) throws ApiHandlerException {
+        SimpleApi api = apiContext.getApi();
+        if (StringUtils.isEmpty(param.getClassName())) {
+            logger
+                    .error("[Invalid api] " + api.getApiName() + "_" + api.getApiVersion() + " byte array class null");
+            throw new ApiHandlerException("[Invalid api param]parameter '" + param.getSourceName()
+                    + "' is byte[] ,but the class name was null");
+        }
+        String invokeType = param.getClassName();
+        byte[] bytes = (byte[]) apiContext.getHttpParam().getParameter(param.getSourceName());
+        return new InvokeParam(invokeType, bytes);
+    }
+
+    /**
+     * 解析Map类型(风控用)
+     *
+     * @param apiContext
+     * @param param
+     * @return
+     * @throws ApiHandlerException
+     */
+    private InvokeParam convertMapParam(ApiContext apiContext, SimpleApiParam param) throws ApiHandlerException {
+        SimpleApi api = apiContext.getApi();
+        if (StringUtils.isEmpty(param.getClassName())) {
+            logger
+                    .error("[Invalid api] " + api.getApiName() + "_" + api.getApiVersion() + " mapping object class null");
+            throw new ApiHandlerException("[Invalid api param]parameter '" + param.getSourceName()
+                    + "' is map ,but the class was null");
+        }
+        String invokeType = param.getClassName();
+        Object mapString = apiContext.getHttpParam().getParameter(param.getSourceName());
+        Map<String, Object> properties = JSON.parseObject(String.valueOf(mapString));
+        return new InvokeParam(invokeType, properties);
+    }
+
+    /**
+     * 解析List类型(风控用)
+     *
+     * @param apiContext
+     * @param param
+     * @return
+     * @throws ApiHandlerException
+     */
+    private InvokeParam convertListParam(ApiContext apiContext, SimpleApiParam param) throws ApiHandlerException {
+        SimpleApi api = apiContext.getApi();
+        if (StringUtils.isEmpty(param.getClassName())) {
+            logger
+                    .error("[Invalid api] " + api.getApiName() + "_" + api.getApiVersion() + " mapping object class null");
+            throw new ApiHandlerException("[Invalid api param]parameter '" + param.getSourceName()
+                    + "' is list ,but the class was null");
+        }
+        String invokeType = param.getClassName();
+        Object mapString = apiContext.getHttpParam().getParameter(param.getSourceName());
+        List<String> properties = JSON.parseArray(String.valueOf(mapString), String.class);
+        return new InvokeParam(invokeType, properties);
+    }
+
+
+    /**
+     * 解析对象类型
+     *
+     * @param param
+     * @param apiContext
+     * @return
+     * @throws ApiHandlerException
+     */
+    private InvokeParam convertObject(ApiContext apiContext, SimpleApiParam param) throws ApiHandlerException {
+        SimpleApi api = apiContext.getApi();
+        if (StringUtils.isEmpty(param.getClassName())) {
+            logger
+                    .error("[Invalid api] " + api.getApiName() + "_" + api.getApiVersion() + " mapping object class null");
+            throw new ApiHandlerException("[Invalid api param]parameter '" + param.getSourceName()
+                    + "' is object ,but the class was null");
+        }
+        Map<String, Object> properties = new HashMap<String, Object>();
+        for (SimpleApiParam f : param.getFields()) {
+            Object pValue = apiContext.getHttpParam().getParameter(f.getSourceName());
+            InvokeParam invokeParam = convertCommon(f, pValue);
+            properties.put(f.getDestName(), invokeParam.getValue());
+        }
+        return new InvokeParam(param.getClassName(), properties);
+    }
+
+    /**
+     * 解析普通类型
+     *
+     * @param param
+     * @return
+     * @throws ApiHandlerException
+     */
+    private InvokeParam convertCommon(SimpleApiParam param, Object httpValue) throws ApiHandlerException {
+
+        // 处理默认值
+        if (httpValue == null) {
+            httpValue = param.getDefaultValue();
+            // 默认值兼容
+            if (StringUtils.isEmpty((String) httpValue)) {
+                if (param.getParamType() >= 10 && param.getParamType() <= 16) {
+                    httpValue = 0;// 基本类型
+                } else if (param.getParamType() == 17) {
+                    httpValue = false;// 布尔类型
+                } else if (param.getParamType() >= 20 && param.getParamType() <= 27) {
+                    httpValue = null;// 包装类型
+                }
+            }
+        }
+
+        // 得到入参类型
+        String invokeType = ApiParamTypeCache.getClassName(param.getParamType());
+        if (invokeType == null) {
+            logger.error("[Invalid api] Unsupported parameter type:'" + param.getParamType() + ", param name:"
+                    + param.getSourceName());
+            throw new ApiHandlerException("Unsupported parameter type:'" + param.getParamType() + ", param name:"
+                    + param.getSourceName());
+        }
+
+        // 得到入参实际值
+        Object invokeValue = ApiParamValueConvertor.convert(httpValue, param.getSourceName(), param.getParamType());
+        return new InvokeParam(invokeType, invokeValue);
+    }
+}

+ 98 - 0
src/main/java/com/sec/xinhua/gateway/handler/DubboServiceInvokeHandler.java

@@ -0,0 +1,98 @@
+package com.sec.xinhua.gateway.handler;
+
+import com.alibaba.dubbo.rpc.RpcContext;
+import com.alibaba.dubbo.rpc.service.GenericService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.sec.xinhua.gateway.beans.*;
+import com.sec.xinhua.gateway.config.GatewaySettingRepository;
+import com.sec.xinhua.gateway.service.DubboServiceManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Map;
+
+/**
+ * dubbo 调用
+ * by Zhangqx 2016.03.30
+ */
+public class DubboServiceInvokeHandler implements ApiHandler {
+    private static final Log gatewayLogger = LogFactory.getLog("riskGatewayLogger");
+    private static final Log errorLogger = LogFactory.getLog("errorLogger");
+
+    @Override
+    public ApiResult handle(ApiContext apiContext) {
+        SimpleApi api = apiContext.getApi();
+        //获取dubbo服务
+        GenericService service = DubboServiceManager.getService(api);
+        if (service == null) {
+            String error = "[Can not found Service];serviceName:" + api.getServiceName() + ",serviceVersion:"
+                    + api.getServiceVersion();
+            errorLogger.error(error);
+            return ApiResultCache.getApiResult(ApiCode.SERVICE_NOT_FOUND, error);
+        }
+
+        //调用dubbo服务
+        Object invokeResult = null;
+        Map<String, String> map = apiContext.getSysParam().getMap();
+        if (map == null) {
+            errorLogger.error("[Risk params map is null]");
+        } else {
+            try {
+                String riskParams = JSON.toJSONString(map);
+                RpcContext.getContext().setAttachment("riskParams", riskParams);
+            } catch (Exception e) {
+                errorLogger.error("[Risk params convert to json fail]", e);
+            }
+        }
+        try {
+            invokeResult = service.$invoke(api.getMethod(), apiContext.getInvokeTypes(), apiContext.getInvokeValues());
+        } catch (Throwable e) {
+            String error = "[Invoke dubbo service error]";
+            errorLogger.error(error, e);
+            return ApiResultCache.getApiResult(ApiCode.SERVICE_INVOKE_ERROR, error, null);
+        } finally {
+            RpcContext.getContext().clearAttachments();
+        }
+
+
+        //请求和响应日志输出
+        try {
+            if (GatewaySettingRepository.getInstance().getObject().isLogInvokeResult()) {
+                StringBuilder sb = new StringBuilder("[Invoke detail]");
+                sb.append("serviceName:").append(api.getServiceName()).append(",");
+                sb.append("serviceVersion:").append(api.getServiceVersion()).append(",");
+                sb.append("method:").append(api.getMethod()).append(",");
+                sb.append("invokeTypes:").append(JSON.toJSONString(apiContext.getInvokeTypes(), false)).append(",");
+                sb.append("invokeResult:").append(invokeResult == null ? null : JSON.toJSONString(invokeResult, false));
+                gatewayLogger.info(sb.toString());
+            }
+        } catch (Exception e) {
+            errorLogger.error("Log invoke detail error", e);
+        }
+        ApiResult apiResult = ApiResultCache.getApiResult(ApiCode.SUCCESS, null);
+        if (invokeResult != null) {
+            JSONObject jsonObj = null;
+            try {
+                jsonObj = (JSONObject) JSON.toJSON(invokeResult);
+                if (jsonObj.get("class") != null) {
+                    jsonObj.remove("class");
+                }
+                if (jsonObj.get("data") != null) {
+                    JSONObject dataObj = (JSONObject) jsonObj.get("data");
+                    if (dataObj != null && dataObj.get("class") != null) {
+                        dataObj.remove("class");
+                        jsonObj.put("data", dataObj);
+                    }
+                }
+                apiResult.setOriginResult(jsonObj);
+                apiResult.setData(jsonObj);
+            } catch (Exception e) {
+                apiResult.setOriginResult(jsonObj);
+                apiResult.setData(invokeResult);
+            }
+        }
+        return apiResult;
+    }
+
+}

+ 165 - 0
src/main/java/com/sec/xinhua/gateway/handler/RequestHandler.java

@@ -0,0 +1,165 @@
+package com.sec.xinhua.gateway.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.sec.xinhua.gateway.beans.*;
+import com.sec.xinhua.gateway.config.GatewaySettingRepository;
+import com.sec.xinhua.gateway.parse.HttpParamConstants;
+import com.sec.xinhua.gateway.parse.ParamParser;
+import com.sec.xinhua.gateway.parse.RequestParam;
+import com.sec.xinhua.gateway.utils.ParamParseException;
+import com.sec.xinhua.gateway.utils.URLHelper;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author zhangqx
+ * @version $Id: RequestHandler.java, v 0.1 2015年12月9日 上午11:02:26 zhangqx Exp $
+ */
+public class RequestHandler {
+    private static final Log statsLogger = LogFactory.getLog("riskStatsLogger");
+    private static final Log logger = LogFactory.getLog("riskGatewayLogger");
+    private static final Log errorLogger = LogFactory.getLog("errorLogger");
+
+    /*
+     * http参数的解析,service调用
+     */
+    public void httpRequestHandle(HttpServletRequest req, HttpServletResponse response) {
+        ApiContext apiContext = new ApiContext();
+        long startTime = System.currentTimeMillis();
+        RequestParam requestParam = null;
+        try {
+            requestParam = ParamParser.parseHttpParams(req);
+            apiContext.setSysParam(requestParam.getSysParam());
+            apiContext.setHttpParam(requestParam);
+        } catch (ParamParseException e) {
+            StringBuilder sb = new StringBuilder("[Request Parse Error]");
+            sb.append(" requestTime:").append(URLHelper.getCurrentTime()).append(",");
+            sb.append(" clientIp:").append(URLHelper.getIpAddr(req)).append(",");
+            sb.append(" url:").append(req.getRequestURI().toString() + "?" + req.getQueryString()).append(",");
+            sb.append(" detail:").append(e.getMessage());
+            errorLogger.info(sb.toString(), e);
+            ApiResult apiResult = ApiResultCache.getApiResult(ApiCode.API_INVALID_REQUEST,
+                    "Parse error:" + e.getMessage(), null);
+            print(response, JSON.toJSONString(apiResult));
+            this.logRequestStatistics(apiContext, apiResult, startTime);
+        }
+
+        // 原始返回
+//        GatewaySetting gatewaySetting = GatewaySettingRepository.getInstance().getObject();
+        ApiResult invokeResult = serviceInvoke(apiContext);
+//        if (gatewaySetting != null) {
+//            String originResult = gatewaySetting.getOriginResult();
+//            if (StringUtils.isNotEmpty(originResult)) {
+//                String curApi = req.getParameter(HttpParamConstants.API);
+//                String curApi = "xinhua.sec.data";
+        // 有些api需要直接返回dubbo返回的值,不需要包装apiCode和apiMsg;
+//                if (originResult.contains(curApi)) {
+        print(response, invokeResult.getOriginResult() == null ? null : invokeResult.getOriginResult().toString());
+        logRequestStatistics(apiContext, invokeResult, startTime);
+        return;
+//                }
+//            }
+//        }
+//        invokeResult.setOriginResult(null);
+//        print(response, JSON.toJSONString(invokeResult));
+//        logRequestStatistics(apiContext, invokeResult, startTime);
+    }
+
+    /*
+     * 用于记录请求耗时
+     */
+    private void logRequestStatistics(ApiContext apiContext, ApiResult apiResult, long startTime) {
+        if (apiContext == null || apiContext.getSysParam() == null || apiResult == null) {
+            return;
+        }
+        try {
+            if (StringUtils.isNotBlank(apiContext.getSysParam().getApi())
+                    && StringUtils.isNotBlank(apiContext.getSysParam().getApiVersion())) {
+                StringBuilder sb = new StringBuilder();
+                sb.append(apiContext.getSysParam().getApi()).append("_")
+                        .append(apiContext.getSysParam().getApiVersion()).append(",");
+                sb.append(apiResult.getApiCode()).append(",");
+                sb.append(System.currentTimeMillis() - startTime);
+                statsLogger.info(sb.toString());
+            }
+        } catch (Exception e1) {
+            errorLogger.error("Log stats error", e1);
+        }
+    }
+
+    /*
+     * 响应流
+     */
+    private void print(HttpServletResponse response, String content) {
+        response.setHeader("Access-Control-Allow-Origin", "*");
+        response.setHeader("Access-Control-Allow-Methods", "GET,PUT,DELETE,POST,OPTIONS");
+        response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,kopds");
+        try {
+            response.getWriter().print(content);
+            response.getWriter().flush();
+        } catch (IOException e) {
+            errorLogger.error("Print response error,response content:" + content, e);
+        }
+    }
+
+    /*
+     * 调用handler链,泛化调用dubbo服务
+     */
+    private ApiResult serviceInvoke(ApiContext apiContext) {
+        ApiResult apiResult = null;
+        try {
+            apiResult = DefaultApiHandlerChain.getInstance().doHandle(apiContext);
+        } catch (Exception e) {
+            errorLogger.error(e.getMessage(), e);
+            apiResult = ApiResultCache.getApiResult(ApiCode.API_INVALID_REQUEST, "System error:" + e.getMessage(), null);
+        } finally {
+            //记录响应结果
+            try {
+                if (GatewaySettingRepository.getInstance().getObject().isLogResponse()) {
+                    StringBuilder sb = new StringBuilder("[Response detail]");
+                    if (apiResult.getApiCode() == ApiCode.SUCCESS.getCode()) {
+                        sb.append("Y");
+                    } else {
+                        sb.append("N");
+                    }
+                    if (apiContext.getApi() != null) {
+                        sb.append(", api:").append(apiContext.getApi().getApiName()).append("_")
+                                .append(apiContext.getApi().getApiVersion());
+                    }
+                    sb.append(", response:").append(JSON.toJSONString(apiResult));
+                    logger.info(sb.toString());
+                }
+            } catch (Exception e) {
+                errorLogger.error("Log response error", e);
+            }
+        }
+        return apiResult;
+    }
+
+    public ApiResult thriftRequestHandle(String apiName, String apiVersion, String jsonData) {
+        ApiContext apiContext = new ApiContext();
+        long startTime = System.currentTimeMillis();
+        RequestParam requestParam = null;
+        try {
+            requestParam = ParamParser.parseThriftParams(apiName, apiVersion, jsonData);
+            apiContext.setSysParam(requestParam.getSysParam());
+            apiContext.setHttpParam(requestParam);
+        } catch (ParamParseException e) {
+            StringBuilder sb = new StringBuilder("[Request Parse Error]");
+            sb.append(" requestTime:").append(URLHelper.getCurrentTime()).append(",");
+            sb.append(" detail:").append(e.getMessage());
+            errorLogger.info(sb.toString(), e);
+            ApiResult apiResult = ApiResultCache.getApiResult(ApiCode.API_INVALID_REQUEST,
+                    "Parse error:" + e.getMessage(), null);
+            this.logRequestStatistics(apiContext, apiResult, startTime);
+        }
+        ApiResult apiResult = serviceInvoke(apiContext);
+        logRequestStatistics(apiContext, apiResult, startTime);
+        return apiResult;
+    }
+}

+ 45 - 0
src/main/java/com/sec/xinhua/gateway/handler/SysParamValidateHandler.java

@@ -0,0 +1,45 @@
+package com.sec.xinhua.gateway.handler;
+
+import com.sec.xinhua.gateway.beans.*;
+import com.sec.xinhua.gateway.config.ConfigRepositoryFactory;
+import com.sec.xinhua.gateway.config.remote.ApiRemoteRepository;
+import com.sec.xinhua.gateway.parse.HttpParamConstants;
+import com.sec.xinhua.gateway.parse.SysParam;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * 平台参数校验
+ */
+public class SysParamValidateHandler implements ApiHandler {
+
+    private static final Log logger  = LogFactory.getLog("errorLogger");
+
+    private ApiRemoteRepository apiRepo = ConfigRepositoryFactory.getApiRepository();
+
+    @Override
+    public ApiResult handle(ApiContext context) {
+        SysParam sp = context.getHttpParam().getSysParam();
+
+        //平台参数校验
+        if (StringUtils.isEmpty(sp.getApi()) || StringUtils.isEmpty(sp.getApiVersion())) {
+            StringBuilder sb = new StringBuilder("[Invalid sys param]some one can't found,sys param:[");
+            sb.append(HttpParamConstants.API).append(":").append(sp.getApi()).append(",");
+            sb.append(HttpParamConstants.API_VERSION).append(":").append(sp.getApiVersion()).append(",");
+            sb.append("]");
+            String error = sb.toString();
+            logger.info(error);
+            return ApiResultCache.getApiResult(ApiCode.API_INVALID_REQUEST, error);
+        }
+
+        //检查API是否存在
+        SimpleApi api = apiRepo.getObject(sp.getApi() + "_" + sp.getApiVersion());
+        if (api == null) {
+            logger.info("[Can not found api]api:" + api + ",apiVersion:" + sp.getApiVersion());
+            return ApiResultCache.getApiResult(ApiCode.API_NOT_FOUND, null);
+        }
+        context.setApi(api);
+        return null;
+    }
+}

+ 33 - 0
src/main/java/com/sec/xinhua/gateway/parse/HttpParamConstants.java

@@ -0,0 +1,33 @@
+package com.sec.xinhua.gateway.parse;
+
+/**
+ * 平台参数名称定义
+ */
+public class HttpParamConstants {
+
+    //api名称
+    public static final String API         = "api";
+
+    //api版本
+    public static final String API_VERSION = "apiVersion";
+
+    //动作
+    public static final String OPTION      = "option";
+
+    //客户端ip
+    public static final String CLIENT_IP   = "clientIp";
+
+    //请求参数
+    public static final String REQUEST_URL = "requestUrl";
+
+    //请求会话session id
+    public static final String SESSION_ID  = "sessionId";
+
+    public static final String REFERER_URL = "refererUrl";
+
+    /**
+     * 业务数据
+     */
+    public static final String BIZ_DATA    = "bizData";
+
+}

+ 180 - 0
src/main/java/com/sec/xinhua/gateway/parse/ParamParser.java

@@ -0,0 +1,180 @@
+package com.sec.xinhua.gateway.parse;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.sec.xinhua.gateway.beans.SimpleApi;
+import com.sec.xinhua.gateway.beans.SimpleApiParam;
+import com.sec.xinhua.gateway.config.ConfigRepositoryFactory;
+import com.sec.xinhua.gateway.utils.InputStreamCacher;
+import com.sec.xinhua.gateway.utils.ParamParseException;
+import com.sec.xinhua.gateway.utils.SysConstants;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 参数解析
+ *
+ * @author zhangqx
+ * @version $Id: ParamParser.java, v 0.1 2015年12月9日 上午11:45:58 zhangqx Exp $
+ */
+public class ParamParser {
+
+    private static final Log parseLog = LogFactory.getLog("parseLogger");
+    private static final String API = "xinhua.sec.data";
+    private static final String VERSION = "1.0.0";
+
+    /**
+     * http参数转化
+     */
+    public static RequestParam parseHttpParams(HttpServletRequest req) throws ParamParseException {
+        SysParam sysParam = new SysParam();
+        RequestParam requestParam = new RequestParam();
+        String contentType = req.getContentType();
+        if (contentType != null && contentType.contains("multipart/form-data")) {
+            fileParamsConvert(req, requestParam);
+        } else {
+            InputStreamCacher streamCacher = null;
+            try {
+                streamCacher = new InputStreamCacher(req.getInputStream());
+                jsonParamsConvert(streamCacher.getInputStream(), requestParam);
+            } catch (Exception e1) {
+                parseLog.info("Params json parse exception : postBody is null, " + e1);
+                try {
+                    paramsConvert(streamCacher.convertString(), requestParam);
+                } catch (Exception e2) {
+                    parseLog.info("Params urlencode parse exception : stream cacher convert string exception, " + e2);
+                }
+            }
+        }
+        if (req.getParameter(HttpParamConstants.API) != null) {
+            sysParam.setApi(req.getParameter(HttpParamConstants.API));
+        } else {
+            sysParam.setApi(API);
+        }
+        sysParam.setApiVersion(VERSION);
+        sysParam.setSessionId(req.getSession().getId());
+        sysParam.setRefererUrl(req.getHeader("referer"));
+        sysParam.setRequestUrl(req.getRequestURI().toString() + "?" + req.getQueryString());
+        requestParam.setSysParam(sysParam);
+        return requestParam;
+    }
+
+    private static void jsonParamsConvert(InputStream input, RequestParam requestParam) throws Exception {
+        String postBody = IOUtils.toString(input, SysConstants.ENCODE);
+        if (StringUtils.isEmpty(postBody)) {
+            throw new ParamParseException("Can not get post param from inputstream , post body is null");
+        }
+        JSONObject jsonData = JSON.parseObject(postBody);
+        if (jsonData == null) {
+            throw new ParamParseException("Http Post body parse complete but json was null;post body:<"
+                    + postBody + ">");
+        }
+        for (String key : jsonData.keySet()) {
+            String jsonValue = jsonData.getString(key);
+            if (jsonValue == null) {
+                throw new ParamParseException("Http Param value was null,name:" + key);
+            }
+            requestParam.putBizParam(key, jsonValue);
+        }
+
+    }
+
+
+    private static void paramsConvert(String paramStr, RequestParam requestParam) {
+        if (StringUtils.isEmpty(paramStr)) {
+            return;
+        }
+        for (String pair : paramStr.split("&")) {
+            String kv[] = pair.split("=");
+            if (kv.length == 2) {
+                requestParam.putBizParam(kv[0], kv[1]);
+            }
+        }
+    }
+
+    public static RequestParam parseThriftParams(String apiName, String apiVersion, String jsonData)
+            throws ParamParseException {
+        SysParam sysParam = new SysParam();
+        RequestParam requestParam = new RequestParam();
+        sysParam.setApi(apiName);
+        sysParam.setApiVersion(apiVersion);
+        requestParam.setSysParam(sysParam);
+        if (!StringUtils.isEmpty(jsonData)) {
+            JSONObject jsonParams = JSON.parseObject(jsonData);
+            if (jsonParams == null) {
+                throw new ParamParseException("Thrift params parse complete but json was null;post body:<" + jsonData
+                        + ">");
+            }
+            for (String key : jsonParams.keySet()) {
+                String jsonValue = jsonParams.getString(key);
+                if (jsonValue == null) {
+                    throw new ParamParseException("Thrift Param value was null,name:" + key);
+                }
+                requestParam.putBizParam(key, jsonValue);
+            }
+        }
+        return requestParam;
+    }
+
+    private static RequestParam fileParamsConvert(HttpServletRequest request, RequestParam requestParam) {
+        Map<String, SimpleApi> apiMap = ConfigRepositoryFactory.getAllApi();
+        String apiKey = request.getParameter(HttpParamConstants.API) + "_" + request.getParameter(HttpParamConstants.API_VERSION);
+        SimpleApi api = apiMap.get(apiKey);
+        List<String> keys = new ArrayList<String>();
+        if (api != null) {
+            List<SimpleApiParam> lists = api.getParams();
+            for (SimpleApiParam param : lists) {
+                if (param.getParamType() == 40) {
+                    keys.add(param.getSourceName());
+                }
+            }
+        }
+        // 超过这个阈值 1M ,文件将被存在临时文件夹中,否则在内存中
+        DiskFileItemFactory factory = new DiskFileItemFactory(1024 * 1024 * 2, new File("temp"));
+        ServletFileUpload upload = new ServletFileUpload(factory);
+        upload.setSizeMax(1024 * 1024 * 2);
+        upload.setFileSizeMax(1024 * 512);
+        String[] fileExts = {"mp4", "png", "jpg", "avi", "txt", "gif", "jpeg"};
+        try {
+            List<FileItem> items = upload.parseRequest(request);
+            if (items == null) {
+                return requestParam;
+            }
+            int size = items.size();
+            int keysSize = keys.size();
+            int fileIndex = 0;
+            for (int i = 0; i < size; i++) {
+                FileItem fileItem = items.get(i);
+                String paramName = fileItem.getFieldName();
+                if (fileItem.isFormField()) {
+                    String paramValue = fileItem.getString("UTF-8");
+                    requestParam.putBizParam(paramName, paramValue);
+                } else {
+                    String fileName = fileItem.getName();
+                    String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
+                    if (Arrays.binarySearch(fileExts, fileExt) != -1 && fileIndex < keysSize) {
+                        requestParam.putBizParam(paramName, fileItem.get());
+                    } else {
+                        parseLog.info("This kind of file type is not allowed , fileName is " + fileName);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            parseLog.info("Multipart data parse exception ", e);
+        }
+        return requestParam;
+    }
+}

+ 68 - 0
src/main/java/com/sec/xinhua/gateway/parse/RequestParam.java

@@ -0,0 +1,68 @@
+package com.sec.xinhua.gateway.parse;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class RequestParam {
+    private SysParam sysParam;
+
+    private Map<String, Object> bizParams = new HashMap<String, Object>();
+
+    private String bizStringCache = null;
+
+    public void putBizParam(String key, Object value) {
+        bizParams.put(key, value);
+    }
+
+    public String getBizParamsChars() {
+        if (bizStringCache != null) {
+            return bizStringCache;
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, Object> entry : bizParams.entrySet()) {
+            sb.append(entry.getKey()).append(":");
+            if (entry.getValue() != null && entry.getValue() instanceof byte[]) {
+                byte[] tmp = (byte[]) entry.getValue();
+                sb.append("byte[").append(tmp.length).append("]");
+            } else {
+                //保密关键字日志转换
+            }
+            sb.append(",");
+        }
+
+        if (sb.length() > 0) {
+            sb.deleteCharAt(sb.length() - 1);
+        }
+        bizStringCache = sb.toString();
+        return bizStringCache;
+    }
+
+    public SysParam getSysParam() {
+        return sysParam;
+    }
+
+    public void setSysParam(SysParam sysParam) {
+        this.sysParam = sysParam;
+    }
+
+    public Object getParameter(String key) {
+        return bizParams.get(key);
+    }
+
+    public Object getSysParameter(String key) {
+        return sysParam.getParam(key);
+    }
+
+    public Map<String, Object> getBizParams() {
+        return bizParams;
+    }
+
+    public void setBizParams(Map<String, Object> bizParams) {
+        this.bizParams = bizParams;
+    }
+
+    @Override
+    public String toString() {
+        return "HttpParam{bizParams=" + bizParams + '}';
+    }
+}

+ 99 - 0
src/main/java/com/sec/xinhua/gateway/parse/SysParam.java

@@ -0,0 +1,99 @@
+package com.sec.xinhua.gateway.parse;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 平台参数
+ */
+public class SysParam {
+    // api名称
+    private String api;
+
+    // api版本
+    private String apiVersion;
+
+    // 请求参数
+    private String requestUrl;
+
+    //referer url
+    private String refererUrl;
+
+    private String sessionId;
+
+    private Map<String, String> map = new HashMap<String, String>();
+
+    public String getApi() {
+        return api;
+    }
+
+    public void setApi(String api) {
+        this.api = api;
+        map.put(HttpParamConstants.API, this.api);
+    }
+
+    public String getApiVersion() {
+        return apiVersion;
+    }
+
+    public void setApiVersion(String apiVersion) {
+        this.apiVersion = apiVersion;
+        map.put(HttpParamConstants.API_VERSION, this.apiVersion);
+    }
+
+    public String getRequestUrl() {
+        return requestUrl;
+    }
+
+    public void setRequestUrl(String requestUrl) {
+        this.requestUrl = requestUrl;
+        map.put(HttpParamConstants.REQUEST_URL, this.requestUrl);
+    }
+
+    public String getRefererUrl() {
+        return refererUrl;
+    }
+
+    public void setRefererUrl(String refererUrl) {
+        this.refererUrl = refererUrl;
+        map.put(HttpParamConstants.REFERER_URL, refererUrl);
+    }
+
+    public Map<String, String> getMap() {
+        return map;
+    }
+
+    public String getParam(String key) {
+        return map.get(key);
+    }
+
+    public String getSessionId() {
+        return sessionId;
+    }
+
+    public void setSessionId(String sessionId) {
+        this.sessionId = sessionId;
+    }
+
+    public String toPlatfromParamString() {
+        StringBuilder sb = new StringBuilder();
+        Set<String> keys = this.map.keySet();
+        for (String key : keys) {
+            String value = map.get(key);
+            if (value != null) {
+                sb.append(key);
+                sb.append(":");
+                sb.append(value);
+                sb.append(",");
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        return "SysParam{" + map + '}';
+    }
+
+}

+ 90 - 0
src/main/java/com/sec/xinhua/gateway/service/DubboServiceManager.java

@@ -0,0 +1,90 @@
+package com.sec.xinhua.gateway.service;
+
+import com.alibaba.dubbo.config.ApplicationConfig;
+import com.alibaba.dubbo.config.ReferenceConfig;
+import com.alibaba.dubbo.config.RegistryConfig;
+import com.alibaba.dubbo.rpc.service.GenericService;
+import com.sec.xinhua.gateway.beans.GatewaySetting;
+import com.sec.xinhua.gateway.beans.SimpleApi;
+import com.sec.xinhua.gateway.config.ConfigRepositoryFactory;
+import com.sec.xinhua.gateway.config.GatewaySettingRepository;
+import com.sec.xinhua.gateway.utils.SysConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class DubboServiceManager {
+    private static final Log logger = LogFactory.getLog(DubboServiceManager.class);
+
+    private static ApplicationConfig APPLICATION;
+
+    private static RegistryConfig REGISTRY;
+
+    private static ConcurrentHashMap<String, GenericService> SERVICE_CACHE = new ConcurrentHashMap<String, GenericService>();
+
+    static {
+        init();
+    }
+
+    public static void init() {
+        APPLICATION = new ApplicationConfig();
+        APPLICATION.setName(SysConstants.APPLICATION_NAME);
+        REGISTRY = new RegistryConfig();
+        GatewaySetting gs = GatewaySettingRepository.getInstance().getObject();
+        REGISTRY.setProtocol("zookeeper");
+        REGISTRY.setAddress(gs.getZkAddress());
+        REGISTRY.setFile(System.getProperty("user.home") + "/risk_gateway_registery.config");
+    }
+
+    public static GenericService getService(SimpleApi simpleApi) {
+        String serviceName = simpleApi.getServiceName();
+        String serviceVersion = simpleApi.getServiceVersion();
+        Integer timeout = simpleApi.getTimeout();
+        String cacheKey = serviceName + "_" + serviceVersion + "_" + timeout;
+        GenericService service = SERVICE_CACHE.get(cacheKey);
+        if (service == null) {
+            //使用ConcurrentHashMap避免锁竞争
+            try {
+                ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
+                reference.setInterface(serviceName);
+                reference.setVersion(serviceVersion);
+                reference.setGeneric(true);
+                reference.setApplication(APPLICATION);
+                /**
+                 * 因为Gatewaysetting 现在是动态配置,所以这里需要重新获取zk地址
+                 */
+                GatewaySetting gs = GatewaySettingRepository.getInstance().getObject();
+                REGISTRY.setAddress(gs.getZkAddress());
+                reference.setRegistry(REGISTRY);
+//                reference.setFilter("DubboConsumerStaticFilter");
+                reference.setTimeout(timeout);
+                reference.setRetries(0);
+                service = reference.get();
+                SERVICE_CACHE.put(cacheKey, service);
+            } catch (Exception e) {
+                logger.error(
+                        "Get dubbo service error;serviceName:" + serviceName + ",serviceVersion:" + serviceVersion, null);
+            }
+        }
+        return service;
+    }
+
+    public static void initAllDubboService() {
+        logger.info("start init dubbo services");
+        Map<String, SimpleApi> apiMap = ConfigRepositoryFactory.getAllApi();
+        Set<String> keys = apiMap.keySet();
+        for (String key : keys) {
+            long start = System.currentTimeMillis();
+            SimpleApi api = apiMap.get(key);
+            DubboServiceManager.getService(api);
+            long end = System.currentTimeMillis();
+            long cost = end - start;
+            logger.info("initService " + api.getServiceName() + " " + api.getServiceVersion() + " cost:" + cost);
+        }
+        logger.info("init dubbo service success");
+    }
+
+}

+ 13 - 0
src/main/java/com/sec/xinhua/gateway/service/DubboTimeoutTestService.java

@@ -0,0 +1,13 @@
+package com.sec.xinhua.gateway.service;
+
+/**
+ * Created by zhangqingxin
+ * Date : 16/8/8
+ * Time : 14:07
+ */
+public interface DubboTimeoutTestService {
+
+    String shortMethod();
+
+    String longMethod();
+}

+ 35 - 0
src/main/java/com/sec/xinhua/gateway/service/impl/DubboTimeoutTestServiceImpl.java

@@ -0,0 +1,35 @@
+package com.sec.xinhua.gateway.service.impl;
+
+import com.sec.xinhua.gateway.service.DubboTimeoutTestService;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by zhangqingxin
+ * Date : 16/8/8
+ * Time : 14:07
+ */
+@Component("dubboTimeoutTestService")
+public class DubboTimeoutTestServiceImpl implements DubboTimeoutTestService {
+
+    @Override
+    public String shortMethod() {
+        try {
+            Thread.sleep(500);
+            return "success";
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        return "failed";
+    }
+
+    @Override
+    public String longMethod() {
+        try {
+            Thread.sleep(2000);
+            return "success";
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        return "failed";
+    }
+}

File diff suppressed because it is too large
+ 1257 - 0
src/main/java/com/sec/xinhua/gateway/thrift/GatewayThriftService.java


+ 612 - 0
src/main/java/com/sec/xinhua/gateway/thrift/ThriftResult.java

@@ -0,0 +1,612 @@
+/**
+ * Autogenerated by Thrift Compiler (0.9.3)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package com.sec.xinhua.gateway.thrift;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Generated;
+
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+import org.apache.thrift.scheme.TupleScheme;
+
+@SuppressWarnings({ "cast", "rawtypes", "serial", "unchecked" })
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = "2015-12-21")
+public class ThriftResult implements org.apache.thrift.TBase<ThriftResult, ThriftResult._Fields>, java.io.Serializable,
+                         Cloneable, Comparable<ThriftResult> {
+    private static final org.apache.thrift.protocol.TStruct           STRUCT_DESC     = new org.apache.thrift.protocol.TStruct(
+                                                                                          "ThriftResult");
+
+    private static final org.apache.thrift.protocol.TField            CODE_FIELD_DESC = new org.apache.thrift.protocol.TField(
+                                                                                          "code",
+                                                                                          org.apache.thrift.protocol.TType.I32,
+                                                                                          (short) 1);
+    private static final org.apache.thrift.protocol.TField            MSG_FIELD_DESC  = new org.apache.thrift.protocol.TField(
+                                                                                          "msg",
+                                                                                          org.apache.thrift.protocol.TType.STRING,
+                                                                                          (short) 2);
+    private static final org.apache.thrift.protocol.TField            DATA_FIELD_DESC = new org.apache.thrift.protocol.TField(
+                                                                                          "data",
+                                                                                          org.apache.thrift.protocol.TType.STRING,
+                                                                                          (short) 3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes         = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+        schemes.put(StandardScheme.class, new ThriftResultStandardSchemeFactory());
+        schemes.put(TupleScheme.class, new ThriftResultTupleSchemeFactory());
+    }
+
+    public int                                                        code;                                                                    // required
+    public String                                                     msg;                                                                     // required
+    public String                                                     data;                                                                    // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+        CODE((short) 1, "code"), MSG((short) 2, "msg"), DATA((short) 3, "data");
+
+        private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+        static {
+            for (_Fields field : EnumSet.allOf(_Fields.class)) {
+                byName.put(field.getFieldName(), field);
+            }
+        }
+
+        /**
+         * Find the _Fields constant that matches fieldId, or null if its not found.
+         */
+        public static _Fields findByThriftId(int fieldId) {
+            switch (fieldId) {
+                case 1: // CODE
+                    return CODE;
+                case 2: // MSG
+                    return MSG;
+                case 3: // DATA
+                    return DATA;
+                default:
+                    return null;
+            }
+        }
+
+        /**
+         * Find the _Fields constant that matches fieldId, throwing an exception
+         * if it is not found.
+         */
+        public static _Fields findByThriftIdOrThrow(int fieldId) {
+            _Fields fields = findByThriftId(fieldId);
+            if (fields == null)
+                throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+            return fields;
+        }
+
+        /**
+         * Find the _Fields constant that matches name, or null if its not found.
+         */
+        public static _Fields findByName(String name) {
+            return byName.get(name);
+        }
+
+        private final short  _thriftId;
+        private final String _fieldName;
+
+        _Fields(short thriftId, String fieldName) {
+            _thriftId = thriftId;
+            _fieldName = fieldName;
+        }
+
+        public short getThriftFieldId() {
+            return _thriftId;
+        }
+
+        public String getFieldName() {
+            return _fieldName;
+        }
+    }
+
+    // isset id assignments
+    private static final int                                                    __CODE_ISSET_ID  = 0;
+    private byte                                                                __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+        Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(
+            _Fields.class);
+        tmpMap.put(_Fields.CODE, new org.apache.thrift.meta_data.FieldMetaData("code",
+            org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(
+                org.apache.thrift.protocol.TType.I32)));
+        tmpMap.put(_Fields.MSG, new org.apache.thrift.meta_data.FieldMetaData("msg",
+            org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(
+                org.apache.thrift.protocol.TType.STRING)));
+        tmpMap.put(_Fields.DATA, new org.apache.thrift.meta_data.FieldMetaData("data",
+            org.apache.thrift.TFieldRequirementType.DEFAULT, new org.apache.thrift.meta_data.FieldValueMetaData(
+                org.apache.thrift.protocol.TType.STRING)));
+        metaDataMap = Collections.unmodifiableMap(tmpMap);
+        org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ThriftResult.class, metaDataMap);
+    }
+
+    public ThriftResult() {
+    }
+
+    public ThriftResult(int code, String msg, String data) {
+        this();
+        this.code = code;
+        setCodeIsSet(true);
+        this.msg = msg;
+        this.data = data;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public ThriftResult(ThriftResult other) {
+        __isset_bitfield = other.__isset_bitfield;
+        this.code = other.code;
+        if (other.isSetMsg()) {
+            this.msg = other.msg;
+        }
+        if (other.isSetData()) {
+            this.data = other.data;
+        }
+    }
+
+    public ThriftResult deepCopy() {
+        return new ThriftResult(this);
+    }
+
+    @Override
+    public void clear() {
+        setCodeIsSet(false);
+        this.code = 0;
+        this.msg = null;
+        this.data = null;
+    }
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public ThriftResult setCode(int code) {
+        this.code = code;
+        setCodeIsSet(true);
+        return this;
+    }
+
+    public void unsetCode() {
+        __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __CODE_ISSET_ID);
+    }
+
+    /** Returns true if field code is set (has been assigned a value) and false otherwise */
+    public boolean isSetCode() {
+        return EncodingUtils.testBit(__isset_bitfield, __CODE_ISSET_ID);
+    }
+
+    public void setCodeIsSet(boolean value) {
+        __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __CODE_ISSET_ID, value);
+    }
+
+    public String getMsg() {
+        return this.msg;
+    }
+
+    public ThriftResult setMsg(String msg) {
+        this.msg = msg;
+        return this;
+    }
+
+    public void unsetMsg() {
+        this.msg = null;
+    }
+
+    /** Returns true if field msg is set (has been assigned a value) and false otherwise */
+    public boolean isSetMsg() {
+        return this.msg != null;
+    }
+
+    public void setMsgIsSet(boolean value) {
+        if (!value) {
+            this.msg = null;
+        }
+    }
+
+    public String getData() {
+        return this.data;
+    }
+
+    public ThriftResult setData(String data) {
+        this.data = data;
+        return this;
+    }
+
+    public void unsetData() {
+        this.data = null;
+    }
+
+    /** Returns true if field data is set (has been assigned a value) and false otherwise */
+    public boolean isSetData() {
+        return this.data != null;
+    }
+
+    public void setDataIsSet(boolean value) {
+        if (!value) {
+            this.data = null;
+        }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+        switch (field) {
+            case CODE:
+                if (value == null) {
+                    unsetCode();
+                } else {
+                    setCode((Integer) value);
+                }
+                break;
+
+            case MSG:
+                if (value == null) {
+                    unsetMsg();
+                } else {
+                    setMsg((String) value);
+                }
+                break;
+
+            case DATA:
+                if (value == null) {
+                    unsetData();
+                } else {
+                    setData((String) value);
+                }
+                break;
+
+        }
+    }
+
+    public Object getFieldValue(_Fields field) {
+        switch (field) {
+            case CODE:
+                return getCode();
+
+            case MSG:
+                return getMsg();
+
+            case DATA:
+                return getData();
+
+        }
+        throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+        if (field == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (field) {
+            case CODE:
+                return isSetCode();
+            case MSG:
+                return isSetMsg();
+            case DATA:
+                return isSetData();
+        }
+        throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (that == null)
+            return false;
+        if (that instanceof ThriftResult)
+            return this.equals((ThriftResult) that);
+        return false;
+    }
+
+    public boolean equals(ThriftResult that) {
+        if (that == null)
+            return false;
+
+        boolean this_present_code = true;
+        boolean that_present_code = true;
+        if (this_present_code || that_present_code) {
+            if (!(this_present_code && that_present_code))
+                return false;
+            if (this.code != that.code)
+                return false;
+        }
+
+        boolean this_present_msg = true && this.isSetMsg();
+        boolean that_present_msg = true && that.isSetMsg();
+        if (this_present_msg || that_present_msg) {
+            if (!(this_present_msg && that_present_msg))
+                return false;
+            if (!this.msg.equals(that.msg))
+                return false;
+        }
+
+        boolean this_present_data = true && this.isSetData();
+        boolean that_present_data = true && that.isSetData();
+        if (this_present_data || that_present_data) {
+            if (!(this_present_data && that_present_data))
+                return false;
+            if (!this.data.equals(that.data))
+                return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        List<Object> list = new ArrayList<Object>();
+
+        boolean present_code = true;
+        list.add(present_code);
+        if (present_code)
+            list.add(code);
+
+        boolean present_msg = true && (isSetMsg());
+        list.add(present_msg);
+        if (present_msg)
+            list.add(msg);
+
+        boolean present_data = true && (isSetData());
+        list.add(present_data);
+        if (present_data)
+            list.add(data);
+
+        return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(ThriftResult other) {
+        if (!getClass().equals(other.getClass())) {
+            return getClass().getName().compareTo(other.getClass().getName());
+        }
+
+        int lastComparison = 0;
+
+        lastComparison = Boolean.valueOf(isSetCode()).compareTo(other.isSetCode());
+        if (lastComparison != 0) {
+            return lastComparison;
+        }
+        if (isSetCode()) {
+            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.code, other.code);
+            if (lastComparison != 0) {
+                return lastComparison;
+            }
+        }
+        lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+        if (lastComparison != 0) {
+            return lastComparison;
+        }
+        if (isSetMsg()) {
+            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.msg, other.msg);
+            if (lastComparison != 0) {
+                return lastComparison;
+            }
+        }
+        lastComparison = Boolean.valueOf(isSetData()).compareTo(other.isSetData());
+        if (lastComparison != 0) {
+            return lastComparison;
+        }
+        if (isSetData()) {
+            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, other.data);
+            if (lastComparison != 0) {
+                return lastComparison;
+            }
+        }
+        return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+        return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+        schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+        schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("ThriftResult(");
+        boolean first = true;
+
+        sb.append("code:");
+        sb.append(this.code);
+        first = false;
+        if (!first)
+            sb.append(", ");
+        sb.append("msg:");
+        if (this.msg == null) {
+            sb.append("null");
+        } else {
+            sb.append(this.msg);
+        }
+        first = false;
+        if (!first)
+            sb.append(", ");
+        sb.append("data:");
+        if (this.data == null) {
+            sb.append("null");
+        } else {
+            sb.append(this.data);
+        }
+        first = false;
+        sb.append(")");
+        return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+        // check for required fields
+        // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+        try {
+            write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(
+                out)));
+        } catch (org.apache.thrift.TException te) {
+            throw new java.io.IOException(te);
+        }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+        try {
+            // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+            __isset_bitfield = 0;
+            read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+        } catch (org.apache.thrift.TException te) {
+            throw new java.io.IOException(te);
+        }
+    }
+
+    private static class ThriftResultStandardSchemeFactory implements SchemeFactory {
+        public ThriftResultStandardScheme getScheme() {
+            return new ThriftResultStandardScheme();
+        }
+    }
+
+    private static class ThriftResultStandardScheme extends StandardScheme<ThriftResult> {
+
+        public void read(org.apache.thrift.protocol.TProtocol iprot, ThriftResult struct)
+                                                                                         throws org.apache.thrift.TException {
+            org.apache.thrift.protocol.TField schemeField;
+            iprot.readStructBegin();
+            while (true) {
+                schemeField = iprot.readFieldBegin();
+                if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+                    break;
+                }
+                switch (schemeField.id) {
+                    case 1: // CODE
+                        if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                            struct.code = iprot.readI32();
+                            struct.setCodeIsSet(true);
+                        } else {
+                            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+                        }
+                        break;
+                    case 2: // MSG
+                        if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                            struct.msg = iprot.readString();
+                            struct.setMsgIsSet(true);
+                        } else {
+                            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+                        }
+                        break;
+                    case 3: // DATA
+                        if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                            struct.data = iprot.readString();
+                            struct.setDataIsSet(true);
+                        } else {
+                            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+                        }
+                        break;
+                    default:
+                        org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+                }
+                iprot.readFieldEnd();
+            }
+            iprot.readStructEnd();
+
+            // check for required fields of primitive type, which can't be checked in the validate method
+            struct.validate();
+        }
+
+        public void write(org.apache.thrift.protocol.TProtocol oprot, ThriftResult struct)
+                                                                                          throws org.apache.thrift.TException {
+            struct.validate();
+
+            oprot.writeStructBegin(STRUCT_DESC);
+            oprot.writeFieldBegin(CODE_FIELD_DESC);
+            oprot.writeI32(struct.code);
+            oprot.writeFieldEnd();
+            if (struct.msg != null) {
+                oprot.writeFieldBegin(MSG_FIELD_DESC);
+                oprot.writeString(struct.msg);
+                oprot.writeFieldEnd();
+            }
+            if (struct.data != null) {
+                oprot.writeFieldBegin(DATA_FIELD_DESC);
+                oprot.writeString(struct.data);
+                oprot.writeFieldEnd();
+            }
+            oprot.writeFieldStop();
+            oprot.writeStructEnd();
+        }
+
+    }
+
+    private static class ThriftResultTupleSchemeFactory implements SchemeFactory {
+        public ThriftResultTupleScheme getScheme() {
+            return new ThriftResultTupleScheme();
+        }
+    }
+
+    private static class ThriftResultTupleScheme extends TupleScheme<ThriftResult> {
+
+        @Override
+        public void write(org.apache.thrift.protocol.TProtocol prot, ThriftResult struct)
+                                                                                         throws org.apache.thrift.TException {
+            TTupleProtocol oprot = (TTupleProtocol) prot;
+            BitSet optionals = new BitSet();
+            if (struct.isSetCode()) {
+                optionals.set(0);
+            }
+            if (struct.isSetMsg()) {
+                optionals.set(1);
+            }
+            if (struct.isSetData()) {
+                optionals.set(2);
+            }
+            oprot.writeBitSet(optionals, 3);
+            if (struct.isSetCode()) {
+                oprot.writeI32(struct.code);
+            }
+            if (struct.isSetMsg()) {
+                oprot.writeString(struct.msg);
+            }
+            if (struct.isSetData()) {
+                oprot.writeString(struct.data);
+            }
+        }
+
+        @Override
+        public void read(org.apache.thrift.protocol.TProtocol prot, ThriftResult struct)
+                                                                                        throws org.apache.thrift.TException {
+            TTupleProtocol iprot = (TTupleProtocol) prot;
+            BitSet incoming = iprot.readBitSet(3);
+            if (incoming.get(0)) {
+                struct.code = iprot.readI32();
+                struct.setCodeIsSet(true);
+            }
+            if (incoming.get(1)) {
+                struct.msg = iprot.readString();
+                struct.setMsgIsSet(true);
+            }
+            if (incoming.get(2)) {
+                struct.data = iprot.readString();
+                struct.setDataIsSet(true);
+            }
+        }
+    }
+
+}

+ 34 - 0
src/main/java/com/sec/xinhua/gateway/thrift/impl/GatewayThriftServiceImpl.java

@@ -0,0 +1,34 @@
+package com.sec.xinhua.gateway.thrift.impl;
+
+import com.sec.xinhua.gateway.thrift.GatewayThriftService;
+import org.apache.thrift.TException;
+import org.springframework.stereotype.Component;
+
+import com.sec.xinhua.gateway.beans.ApiResult;
+import com.sec.xinhua.gateway.handler.RequestHandler;
+import com.sec.xinhua.gateway.thrift.ThriftResult;
+
+/**
+ * 
+ * 
+ * @author zhangqx
+ * @version $Id: GatewayThriftServiceImpl.java, v 0.1 2015年12月2日 下午2:37:00 zhangqx Exp $
+ */
+@Component("gatewayThriftService")
+public class GatewayThriftServiceImpl implements GatewayThriftService.Iface {
+
+    @Override
+    public ThriftResult thriftHandle(String apiName, String apiVersion, String jsonData) throws TException {
+        RequestHandler requestHandle = new RequestHandler();
+        ApiResult apiResult = requestHandle.thriftRequestHandle(apiName, apiVersion, jsonData);
+        return toFilterResult(apiResult);
+    }
+
+    public ThriftResult toFilterResult(ApiResult apiResult) {
+        ThriftResult thriftResult = new ThriftResult();
+        thriftResult.setCode(apiResult.getApiCode());
+        thriftResult.setMsg(apiResult.getApiMsg());
+        thriftResult.setData(String.valueOf(apiResult.getData()));
+        return thriftResult;
+    }
+}

+ 69 - 0
src/main/java/com/sec/xinhua/gateway/thrift/server/GatewayThriftServer.java

@@ -0,0 +1,69 @@
+//package com.kuaidadi.risk.gateway.thrift.server;
+//
+//import javax.servlet.ServletConfig;
+//import javax.servlet.ServletException;
+//import javax.servlet.http.HttpServlet;
+//
+//import org.apache.thrift.TProcessor;
+//import org.apache.thrift.TProcessorFactory;
+//import org.apache.thrift.protocol.TCompactProtocol;
+//import org.apache.thrift.server.THsHaServer;
+//import org.apache.thrift.server.TServer;
+//import org.apache.thrift.transport.TFramedTransport;
+//import org.apache.thrift.transport.TNonblockingServerSocket;
+//import org.apache.thrift.transport.TTransportException;
+//import org.springframework.stereotype.Component;
+//
+//import com.kuaidadi.risk.gateway.thrift.GatewayThriftService;
+//import com.kuaidadi.risk.gateway.thrift.impl.GatewayThriftServiceImpl;
+//
+///**
+// *
+// *
+// * @author zhangqx
+// * @version $Id: GatewayThriftServer.java, v 0.1 2015年12月2日 下午2:36:46 zhangqx Exp $
+// */
+//
+//@Component("gatewayThriftServer")
+//public class GatewayThriftServer extends HttpServlet {
+//    /**  */
+//    private static final long serialVersionUID = -4330276130462154035L;
+//    private static final int  port             = 8586;
+//
+//    @Override
+//    public void init(ServletConfig config) throws ServletException {
+//        /*super.init(config);
+//        //初始化配置(dubbo注册中心等),很重要
+//        ConfigRepositoryFactory.initGatewaySetting();
+//        //初始化所有(dubbo的映射关系)setting
+//        DubboServiceManager.initAllDubboService();
+//        //初始化handler(filter时需要串行执行的handler,包括参数转化,泛化调用)
+//        DefaultApiHandlerChain.getInstance();*/
+//
+//        //启动服务  暂不使用此接口
+////        new Thread(new Runnable() {
+////            public void run() {
+////                serverStart();
+////            }
+////        }).start();
+//    }
+//
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//    public void serverStart() {
+//        try {
+//            TNonblockingServerSocket socket = new TNonblockingServerSocket(port);
+//            TProcessor processor = new GatewayThriftService.Processor(new GatewayThriftServiceImpl());
+//            THsHaServer.Args arg = new THsHaServer.Args(socket);
+//            arg.protocolFactory(new TCompactProtocol.Factory());
+//            arg.transportFactory(new TFramedTransport.Factory());
+//            arg.processorFactory(new TProcessorFactory(processor));
+//            TServer server = new THsHaServer(arg);
+//            System.out.println("==============#Thrift 服务启动#==============");
+//            server.serve();
+//        } catch (TTransportException e) {
+//            e.printStackTrace();
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
+//}

+ 80 - 0
src/main/java/com/sec/xinhua/gateway/utils/AbstractLocalCache.java

@@ -0,0 +1,80 @@
+/**
+ * 
+ */
+package com.sec.xinhua.gateway.utils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 
+ * @author jerry.xu
+ * 
+ * @param <T>
+ */
+public abstract class AbstractLocalCache<T> implements InitializingBean {
+    private static final Log        LOCAL_CACHE_LOGGER          = LogFactory.getLog("errorLogger");
+
+    protected List<T>                cache                       = new ArrayList();
+    private ScheduledExecutorService loadExcutor                 = new ScheduledThreadPoolExecutor(10);
+    //默认60s更新一次
+    private long                     latency                     = 60;
+
+    public long getLatency() {
+        return latency;
+    }
+
+    public void setLatency(long latency) {
+        this.latency = latency;
+    }
+
+    /**
+     * 判断状态是否发生了变更
+     *
+     * @return
+     */
+    private boolean changed() {
+        //TODO 这里改成true
+        return true;
+    }
+
+    private class LoadDataTask implements Runnable {
+
+        @Override
+        public void run() {
+            try {
+                if (changed()) {
+                    List<T> reload = reLoad();
+                    synchronized (cache) {
+                        if (reload == null) {
+                            cache = new ArrayList();
+                        } else {
+                            cache = reload;
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                LOCAL_CACHE_LOGGER.warn("reload cache error",e);
+            }
+        }
+    }
+
+    /**
+     * 重新加载到缓存
+     */
+    protected abstract List<T> reLoad();
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        //延迟1秒加载数据
+        loadExcutor.scheduleAtFixedRate(new LoadDataTask(), 1, latency, TimeUnit.SECONDS);
+    }
+
+}

+ 17 - 0
src/main/java/com/sec/xinhua/gateway/utils/ApiHandlerException.java

@@ -0,0 +1,17 @@
+package com.sec.xinhua.gateway.utils;
+
+public class ApiHandlerException extends Exception {
+    private static final long serialVersionUID = 2866066350090072065L;
+
+    public ApiHandlerException(Throwable t) {
+        super(t);
+    }
+
+    public ApiHandlerException(String message) {
+        super(message);
+    }
+
+    public ApiHandlerException(String message, Throwable t) {
+        super(message, t);
+    }
+}

+ 23 - 0
src/main/java/com/sec/xinhua/gateway/utils/ApiParamTypeCache.java

@@ -0,0 +1,23 @@
+package com.sec.xinhua.gateway.utils;
+
+
+import com.sec.xinhua.gateway.beans.ApiParamType;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ApiParamTypeCache {
+    private static Map<Integer, String> cache;
+
+    static {
+        cache = new HashMap<Integer, String>();
+        ApiParamType[] types = ApiParamType.values();
+        for (ApiParamType t : types) {
+            cache.put(t.getCode(), t.getClassName());
+        }
+    }
+
+    public static String getClassName(Integer key) {
+        return cache.get(key);
+    }
+}

+ 91 - 0
src/main/java/com/sec/xinhua/gateway/utils/FileHelper.java

@@ -0,0 +1,91 @@
+package com.sec.xinhua.gateway.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.log4j.Logger;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+
+public class FileHelper {
+    private static final Logger logger = Logger.getLogger(FileHelper.class);
+
+    public static String readFile(final File file) {
+        if (file == null) {
+            return null;
+        }
+
+        String result = null;
+        if (file.exists()) {
+            InputStream in = null;
+            try {
+                in = new FileInputStream(file);
+                result = readFile(in);
+            } catch (Exception e) {
+                logger.error("Read file error,the file:" + file.getAbsolutePath(), e);
+            } finally {
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (IOException e) {
+                        logger.error("Close stream error,the file:" + file.getAbsolutePath());
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public static String readFile(final InputStream in) throws IOException, UnsupportedEncodingException {
+        int len = in.available();
+        byte[] data = new byte[len];
+        in.read(data, 0, len);
+        return new String(data, SysConstants.ENCODE);
+    }
+
+    public static void writeFileNotSafe(final String str, final String fileName) throws IOException {
+        File file = new File(fileName);
+        File fileParent = file.getParentFile();
+        if (fileParent != null) {
+            fileParent.mkdirs();
+        }
+        FileWriter fileWriter = null;
+
+        try {
+            fileWriter = new FileWriter(file);
+            fileWriter.write(str);
+        } catch (IOException e) {
+            logger.error("Write file error,the file name:" + fileName);
+            throw e;
+        } finally {
+            if (fileWriter != null) {
+                try {
+                    fileWriter.close();
+                } catch (IOException e) {
+                    logger.error("Close file writer error,the file name:" + fileName);
+                    throw e;
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        try {
+            String s = FileHelper.readFile(new FileInputStream(new File("d:/test.txt")));
+            System.out.println(s);
+
+            JSONObject json = JSON.parseObject(s);
+            System.out.println(json.getString("a"));
+            System.out.println(json.getString("b"));
+            System.out.println(json.getString("c"));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 28 - 0
src/main/java/com/sec/xinhua/gateway/utils/HashCodeUtils.java

@@ -0,0 +1,28 @@
+package com.sec.xinhua.gateway.utils;
+
+
+import com.sec.xinhua.gateway.beans.SimpleApi;
+
+/**
+ * Created by zhangqingxin
+ * Date : 16/8/9
+ * Time : 14:25
+ */
+public class HashCodeUtils {
+    public static int simpleApiHash(SimpleApi simpleApi) {
+        int result = 0;
+        if (simpleApi == null) {
+            return result;
+        }
+        result = 31 * result + (simpleApi.getEnvName() != null ? simpleApi.getEnvName().hashCode() : 0);
+        result = 31 * result + (simpleApi.getApiName() != null ? simpleApi.getApiName().hashCode() : 0);
+        result = 31 * result + (simpleApi.getApiVersion() != null ? simpleApi.getApiVersion().hashCode() : 0);
+        result = 31 * result + (simpleApi.getServiceName() != null ? simpleApi.getServiceName().hashCode() : 0);
+        result = 31 * result + (simpleApi.getServiceVersion() != null ? simpleApi.getServiceVersion().hashCode() : 0);
+        result = 31 * result + (simpleApi.getMethod() != null ? simpleApi.getMethod().hashCode() : 0);
+        result = 31 * result + (simpleApi.getTimeout() != null ? simpleApi.getTimeout().hashCode() : 0);
+        result = 31 * result + (simpleApi.getDefaultResult() != null ? simpleApi.getDefaultResult().hashCode() : 0);
+        result = 31 * result + (simpleApi.getParams() != null ? simpleApi.getParams().hashCode() : 0);
+        return result;
+    }
+}

+ 49 - 0
src/main/java/com/sec/xinhua/gateway/utils/InputStreamCacher.java

@@ -0,0 +1,49 @@
+package com.sec.xinhua.gateway.utils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by zhangqingxin
+ * Date : 16/5/26
+ * Time : 02:09
+ * 缓存流
+ */
+public class InputStreamCacher {
+    /**
+     * 将InputStream中的字节保存到ByteArrayOutputStream中。
+     */
+    private ByteArrayOutputStream byteArrayOutputStream = null;
+
+    public InputStreamCacher(InputStream inputStream) {
+        if (inputStream == null)
+            return;
+
+        byteArrayOutputStream = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int len = 0;
+        try {
+            while ((len = inputStream.read(buffer)) > -1) {
+                byteArrayOutputStream.write(buffer, 0, len);
+            }
+            byteArrayOutputStream.flush();
+        } catch (IOException e) {
+
+        }
+    }
+
+    public InputStream getInputStream() {
+        if (byteArrayOutputStream == null)
+            return null;
+
+        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+    }
+
+    public String convertString() throws Exception {
+        if (byteArrayOutputStream == null)
+            return null;
+        return new String(byteArrayOutputStream.toByteArray(), SysConstants.ENCODE);
+    }
+}

+ 53 - 0
src/main/java/com/sec/xinhua/gateway/utils/IpFileCache.java

@@ -0,0 +1,53 @@
+package com.sec.xinhua.gateway.utils;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Created by Administrator on 2017/3/4 0004.
+ */
+public class IpFileCache extends AbstractLocalCache<String> {
+    private static final Log LOCAL_CACHE_LOGGER = LogFactory.getLog("errorLogger");
+
+    private static IpFileCache ipFileCache = null;
+    private List<String> ips = new ArrayList<String>();
+
+    private IpFileCache() {
+        this.reLoad();
+    }
+
+    public static IpFileCache getInstance() {
+        if (ipFileCache == null) {
+            synchronized (IpFileCache.class) {
+                if (ipFileCache == null) {
+                    ipFileCache = new IpFileCache();
+                }
+            }
+        }
+        return ipFileCache;
+    }
+
+    @Override
+    protected List<String> reLoad() {
+        try {
+            String path =IpFileCache.class.getClassLoader().getResource("allow_ip.txt").getPath();
+            File ipFile = new File(path);
+            ips = FileUtils.readLines(ipFile);
+        } catch (Exception e) {
+            LOCAL_CACHE_LOGGER.info("[-IpFileCache-] load ip file exception , " + e);
+        }
+        return ips;
+    }
+
+    public List<String> getIps() {
+        return ips;
+    }
+
+}

+ 17 - 0
src/main/java/com/sec/xinhua/gateway/utils/ParamParseException.java

@@ -0,0 +1,17 @@
+package com.sec.xinhua.gateway.utils;
+
+public class ParamParseException extends Exception {
+    private static final long serialVersionUID = 2866066350090072065L;
+
+    public ParamParseException(Throwable t) {
+        super(t);
+    }
+
+    public ParamParseException(String message) {
+        super(message);
+    }
+
+    public ParamParseException(String message, Throwable t) {
+        super(message, t);
+    }
+}

+ 29 - 0
src/main/java/com/sec/xinhua/gateway/utils/SysConstants.java

@@ -0,0 +1,29 @@
+package com.sec.xinhua.gateway.utils;
+
+/**
+ * 系统级别的常量定义
+ */
+public class SysConstants {
+    /**
+     * 全局的资源编码,包括http请求,响应
+     */
+    public static final String ENCODE           = "UTF-8";
+
+    /**
+     * dubbo application名称
+     */
+    public static final String APPLICATION_NAME = "RISK_GATEWAY";
+
+    /**
+     * API RESULT相关
+     */
+    public static final String API_RESULT_CODE  = "code";
+    public static final String API_RESULT_DATA  = "data";
+    public static final String API_RESULT_MSG   = "msg";
+
+    public static final String HTTP_METHOD      = "http method";
+
+    public static final String INVOKE_TYPE      = "invokeType";
+    public static final String INVOKE_VALUE     = "invokeValue";
+
+}

+ 82 - 0
src/main/java/com/sec/xinhua/gateway/utils/URLHelper.java

@@ -0,0 +1,82 @@
+package com.sec.xinhua.gateway.utils;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.text.SimpleDateFormat;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+
+/**
+ * 比较杂的工具类
+ *
+ */
+public class URLHelper {
+    private static final Logger logger      = Logger.getLogger(URLHelper.class);
+    private static final String TIME_FORMAT = "yyyyMMddHH:mm";
+
+    public static String getIpAddr(HttpServletRequest request) {
+        String ip = request.getHeader("x-forwarded-for");
+        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+
+        return fixIp(ip);
+    }
+
+    /**
+     * x-forwarded-for nginx多层ip处理
+     * @param ip
+     * @return
+     */
+    private static String fixIp(String ip) {
+        if (StringUtils.isNotBlank(ip) && ip.contains(",")) {
+            ip = ip.split(",")[0];
+        }
+        return ip;
+    }
+
+    public static String decode(String param) {
+        if (param == null) {
+            return null;
+        }
+
+        String newStr = null;
+        try {
+            newStr = URLDecoder.decode(param, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            logger.error("Url decode error,orginal value:" + param, e);
+        }
+        return newStr;
+    }
+
+    public static String getStackTrace(Throwable t) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+
+        try {
+            t.printStackTrace(pw);
+            return sw.toString();
+        } finally {
+            pw.close();
+        }
+    }
+
+    public static String getCurrentTime() {
+        return new SimpleDateFormat(TIME_FORMAT).format(System.currentTimeMillis());
+    }
+    
+    public static void main(String[] args) {
+        System.out.println(getCurrentTime());
+    }
+}

+ 73 - 0
src/main/java/com/sec/xinhua/gateway/web/GatewayServlet.java

@@ -0,0 +1,73 @@
+package com.sec.xinhua.gateway.web;
+
+import com.sec.xinhua.gateway.config.ConfigRepositoryFactory;
+import com.sec.xinhua.gateway.handler.DefaultApiHandlerChain;
+import com.sec.xinhua.gateway.handler.RequestHandler;
+import com.sec.xinhua.gateway.service.DubboServiceManager;
+import com.sec.xinhua.gateway.utils.SysConstants;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 风控网关http入口
+ *
+ * @author zhangqx
+ * @version $Id: GatewayServlet.java, v 0.1 2015年12月8日 下午5:48:20 zhangqx Exp $
+ */
+public class GatewayServlet extends HttpServlet {
+    /**  */
+    private static final long serialVersionUID = -2466227266582283749L;
+
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        //初始化配置(dubbo注册中心等),很重要
+        ConfigRepositoryFactory.initGatewaySetting();
+
+        //初始化所有(dubbo的映射关系)setting
+        DubboServiceManager.initAllDubboService();
+
+        //初始化handler(filter时需要串行执行的handler,包括参数转化,泛化调用)
+        DefaultApiHandlerChain.getInstance();
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
+        //编码设置
+        req.setCharacterEncoding(SysConstants.ENCODE);
+        response.setContentType("application/json;charset=utf-8");
+        response.setCharacterEncoding(SysConstants.ENCODE);
+        response.setHeader("Access-Control-Allow-Origin", "*");
+        RequestHandler requestHandler = new RequestHandler();
+        String addr = req.getRemoteAddr();
+
+        /**
+         *  ip白名单功能
+         */
+//        if (StringUtils.isNotBlank(addr)) {
+//            IpFileCache ipFileCache = IpFileCache.getInstance();
+//            List<String> ips = ipFileCache.getIps();
+//            if (ips == null || !ips.contains(addr)) {
+//                print(response, "您好,您的ip无访问权限!");
+//                return;
+//            }
+//        }
+        requestHandler.httpRequestHandle(req, response);
+    }
+
+    private void print(HttpServletResponse response, String content) {
+        response.setHeader("Access-Control-Allow-Origin", "*");
+        response.setHeader("Access-Control-Allow-Methods", "GET,PUT,DELETE,POST,OPTIONS");
+        response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,kopds");
+        try {
+            response.getWriter().print(content);
+            response.getWriter().flush();
+        } catch (IOException e) {
+        }
+    }
+}

+ 140 - 0
src/main/resources/ApiSettingRepository.config

@@ -0,0 +1,140 @@
+[
+    {
+        "apiName": "junxin.sec.data",
+        "apiVersion": "1.0.0",
+        "method": "execute",
+        "params": [
+            {
+                "destName": "api",
+                "file": false,
+                "paramType": 50,
+                "required": 0,
+                "sourceName": "api"
+            },
+            {
+                "destName": "data",
+                "file": false,
+                "paramType": 50,
+                "required": 0,
+                "sourceName": "data"
+            },
+            {
+                "destName": "appKey",
+                "file": false,
+                "paramType": 50,
+                "required": 0,
+                "sourceName": "appKey"
+            },
+            {
+                "destName": "appSecret",
+                "file": false,
+                "paramType": 50,
+                "required": 0,
+                "sourceName": "appSecret"
+            }
+        ],
+        "timeout": 30000,
+        "serviceName": "com.xinhua.sec.biz.service.extend.credit.DataService",
+        "serviceVersion": "${service.dubbo.version}"
+    },
+    {
+            "apiName": "junxin.sec.data_test",
+            "apiVersion": "1.0.0",
+            "method": "executeTest",
+            "params": [
+                {
+                    "destName": "api",
+                    "file": false,
+                    "paramType": 50,
+                    "required": 0,
+                    "sourceName": "api"
+                },
+                {
+                    "destName": "data",
+                    "file": false,
+                    "paramType": 50,
+                    "required": 0,
+                    "sourceName": "data"
+                },
+                {
+                    "destName": "appKey",
+                    "file": false,
+                    "paramType": 50,
+                    "required": 0,
+                    "sourceName": "appKey"
+                }
+            ],
+            "timeout": 60000,
+            "serviceName": "com.xinhua.sec.biz.service.extend.credit.DataServiceTest",
+            "serviceVersion": "${service.dubbo.version}"
+    },
+    {
+        "apiName": "credit.sec.data",
+        "apiVersion": "1.0.0",
+        "method": "execute",
+        "params": [
+            {
+                "destName": "api",
+                "file": false,
+                "paramType": 50,
+                "required": 0,
+                "sourceName": "api"
+            },
+            {
+                "destName": "data",
+                "file": false,
+                "paramType": 50,
+                "required": 0,
+                "sourceName": "data"
+            },
+            {
+                "destName": "appKey",
+                "file": false,
+                "paramType": 50,
+                "required": 0,
+                "sourceName": "appKey"
+            },
+            {
+                "destName": "appSecret",
+                "file": false,
+                "paramType": 50,
+                "required": 0,
+                "sourceName": "appSecret"
+            }
+        ],
+        "timeout": 30000,
+        "serviceName": "com.xinhua.sec.biz.service.extend.credit.DataService",
+        "serviceVersion": "${service.dubbo.version}"
+    },
+    {
+            "apiName": "credit.sec.data_test",
+            "apiVersion": "1.0.0",
+            "method": "executeTest",
+            "params": [
+                {
+                    "destName": "api",
+                    "file": false,
+                    "paramType": 50,
+                    "required": 0,
+                    "sourceName": "api"
+                },
+                {
+                    "destName": "data",
+                    "file": false,
+                    "paramType": 50,
+                    "required": 0,
+                    "sourceName": "data"
+                },
+                {
+                    "destName": "appKey",
+                    "file": false,
+                    "paramType": 50,
+                    "required": 0,
+                    "sourceName": "appKey"
+                }
+            ],
+            "timeout": 60000,
+            "serviceName": "com.xinhua.sec.biz.service.extend.credit.DataServiceTest",
+            "serviceVersion": "${service.dubbo.version}"
+    }
+]

+ 0 - 0
src/main/resources/BusinessesIds.config


+ 8 - 0
src/main/resources/GatewaySettingRepository.config

@@ -0,0 +1,8 @@
+{
+	"logRequest":true,
+	"logResponse":true,
+	"logInvokeResult":true,
+	"name":"sec-gateway",
+	"zkAddress":"${zkAddress}",
+	"runMode":"${runMode}"
+}

+ 2 - 0
src/main/resources/allow_ip.txt

@@ -0,0 +1,2 @@
+192.168.0.1
+127.0.0.1

+ 13 - 0
src/main/resources/applicationContext.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--suppress ALL -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
+
+    <!--<context:annotation-config/>-->
+    <context:annotation-config />
+    <context:component-scan base-package="com.sec.xinhua.gateway" />
+
+</beans>

+ 196 - 0
src/main/resources/log4j.xml

@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="GBK"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+	<logger name="ddosLogger" additivity="false">
+		<level value="info" />
+		<appender-ref ref="ddosAppender" />
+	</logger>
+
+	<logger name="riskStatsLogger" additivity="false">
+		<level value="info" />
+		<appender-ref ref="statsAppender" />
+	</logger>
+
+	<logger name="errorLogger" additivity="false">
+		<level value="INFO" />
+		<appender-ref ref="errorLoggerAppender" />
+	</logger>
+
+	<logger name="riskGatewayLogger" additivity="false">
+		<level value="info" />
+		<appender-ref ref="gatewayAppender"/>
+	</logger>
+
+	<logger name="dubboConsumerStatLogger" additivity="false">
+		<level value="INFO" />
+		<appender-ref ref="dubboConsumerStat" />
+	</logger>
+
+	<logger name="consumerMessageStatLogger" additivity="false">
+		<level value="INFO" />
+		<appender-ref ref="consumerMessageStat" />
+	</logger>
+
+	<logger name="gatewayNotify" additivity="false">
+		<level value="INFO" />
+		<appender-ref ref="notifyAppender" />
+	</logger>
+
+	<logger name="signLogger" additivity="false">
+		<level value="INFO" />
+		<appender-ref ref="signAppender" />
+	</logger>
+
+	<logger name="parseLogger" additivity="false">
+		<level value="INFO" />
+		<appender-ref ref="parseAppender" />
+	</logger>
+
+	<logger name="LocalCacheLogger" additivity="false">
+		<level value="INFO" />
+		<appender-ref ref="LocalCacheAppender" />
+	</logger>
+
+	<appender name="LocalCacheAppender" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="file" value="${log.dir}/settingsChange/settingsChange.log" />
+		<param name="append" value="true" />
+		<param name="encoding" value="UTF-8" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%m%n" />
+		</layout>
+	</appender>
+
+	<appender name="console_appender" class="org.apache.log4j.ConsoleAppender">
+		<param name="encoding" value="UTF-8" />
+		<param name="target" value="System.out" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%-5p %c{2} , %m%n" />
+		</layout>
+	</appender>
+
+	<appender name="notifyAppender" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="Encoding" value="UTF-8" />
+		<param name="File" value="${log.dir}/notify.log" />
+		<param name="Append" value="true" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%m%n" />
+		</layout>
+	</appender>
+
+	<appender name="errorLoggerAppender" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="Encoding" value="UTF-8" />
+		<param name="File" value="${log.dir}/error/error.log" />
+		<param name="Append" value="true" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%m%n" />
+		</layout>
+	</appender>
+
+	<appender name="gatewayAppender" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="file" value="${log.dir}/gateway/gateway.log" />
+		<param name="append" value="true" />
+		<param name="encoding" value="UTF-8" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern"
+				   value="[%X{uuid}] %d{yyy-MM-dd HH\:mm\:ss,SSS} %p %c{1}(%L) - %m%n" />
+		</layout>
+	</appender>
+
+	<appender name="systemAppender" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="file" value="${log.dir}/system/system.log" />
+		<param name="append" value="true" />
+		<param name="encoding" value="UTF-8" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern"
+				   value="[%X{uuid}] %d{yyy-MM-dd HH\:mm\:ss,SSS} %p %c{1}(%L) - %m%n" />
+		</layout>
+	</appender>
+
+	<appender name="consumerMessageStat" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="Encoding" value="UTF-8" />
+		<param name="File" value="${log.dir}/consumerMessageStat.log" />
+		<param name="Append" value="true" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%m%n" />
+		</layout>
+	</appender>
+
+	<appender name="producerMessageStat" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="Encoding" value="UTF-8" />
+		<param name="File" value="${log.dir}/producerMessageStat.log" />
+		<param name="Append" value="true" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%m%n" />
+		</layout>
+	</appender>
+
+	<!-- dubboÐÔÄÜÊÕ¼¯ -->
+	<appender name="dubboConsumerStat" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="Encoding" value="UTF-8" />
+		<param name="Append" value="true" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<param name="file" value="${log.dir}/dubboConsumerStat.log" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%m%n" />
+		</layout>
+	</appender>
+
+	<!-- statistic log  -->
+	<appender name="statsAppender" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="file" value="${log.dir}/statisticReq/statisticReq.log" />
+		<param name="append" value="true" />
+		<param name="encoding" value="UTF-8" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%m%n" />
+		</layout>
+	</appender>
+
+	<!-- ddos¹¥»÷ -->
+	<appender name="ddosAppender" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="file" value="${log.dir}/ddos.log" />
+		<param name="append" value="true" />
+		<param name="encoding" value="UTF-8" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern"
+				   value="[%X{uuid}] %d{yyy-MM-dd HH\:mm\:ss,SSS} %p %c{1}(%L) - %m%n" />
+		</layout>
+	</appender>
+
+	<appender name="signAppender" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="file" value="${log.dir}/signLog/signLog.log" />
+		<param name="append" value="true" />
+		<param name="encoding" value="UTF-8" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%m%n" />
+		</layout>
+	</appender>
+
+	<appender name="parseAppender" class="org.apache.log4j.DailyRollingFileAppender">
+		<param name="file" value="${log.dir}/parse/parse.log" />
+		<param name="append" value="true" />
+		<param name="encoding" value="UTF-8" />
+		<param name="DatePattern" value="'.'yyyy-MM-dd" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%m%n" />
+		</layout>
+	</appender>
+
+	<root>
+		<level value="INFO" />
+		<appender-ref ref="systemAppender" />
+	</root>
+</log4j:configuration>
+

+ 47 - 0
src/main/webapp/WEB-INF/web.xml

@@ -0,0 +1,47 @@
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+
+	<display-name>Archetype Created Web Application</display-name>
+
+	<context-param>
+		<param-name>contextConfigLocation</param-name>
+		<param-value>classpath:applicationContext.xml</param-value>
+	</context-param>
+
+	<listener>
+		<listener-class>
+			org.springframework.web.context.ContextLoaderListener
+		</listener-class>
+	</listener>
+
+	<listener>
+		<listener-class>
+			org.apache.commons.fileupload.servlet.FileCleanerCleanup
+		</listener-class>
+	</listener>
+
+	<servlet>
+		<servlet-name>GatewayServlet</servlet-name>
+		<display-name>GatewayServlet</display-name>
+		<servlet-class>com.sec.xinhua.gateway.web.GatewayServlet</servlet-class>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+	<servlet-mapping>
+		<servlet-name>GatewayServlet</servlet-name>
+		<url-pattern>/credit</url-pattern>
+	</servlet-mapping>
+	<servlet-mapping>
+		<servlet-name>GatewayServlet</servlet-name>
+		<url-pattern>/junxin</url-pattern>
+	</servlet-mapping>
+
+	<!-- 无须使用thrift接口 -->
+	<!--<servlet>-->
+		<!--<servlet-name>thrift</servlet-name>-->
+		<!--<servlet-class>com.kuaidadi.risk.gateway.thrift.server.GatewayThriftServer</servlet-class>-->
+		<!--<load-on-startup>2</load-on-startup>-->
+	<!--</servlet>-->
+</web-app>

+ 20 - 0
src/main/webapp/load.jsp

@@ -0,0 +1,20 @@
+<%@page
+	import="com.sec.xinhua.gateway.config.remote.ApiRemoteRepository"%>
+<%
+    String pwd = request.getParameter("pwd");
+    if (!"wxx".equals(pwd)) {
+        return;
+    }
+
+    String action = request.getParameter("action");
+    if ("loadApi".equals(action)) {
+        ApiRemoteRepository.getInstance().init();
+        response.getWriter().print("load all api ok");
+    }/*  else if ("loadApp".equals(action)) {
+        AppRemoteRepository.getInstance().init();
+        response.getWriter().print("load all app ok");
+    } else if ("loadAuth".equals(action)) {
+        AppAuthRemoteRepository.getInstance().init();
+        response.getWriter().print("load all auth ok");
+    } */
+%>

+ 89 - 0
src/test/java/com/sec/xinhua/gateway/handler/SignValidateHandlerTest.java

@@ -0,0 +1,89 @@
+//package com.sec.xinhua.gateway.handler;
+//
+//import java.io.File;
+//import java.io.FileInputStream;
+//import java.io.FileNotFoundException;
+//import java.io.IOException;
+//import java.net.URLDecoder;
+//import java.net.URLEncoder;
+//import java.util.Map;
+//
+//import junit.framework.TestCase;
+//
+//import com.sec.xinhua.gateway.beans.ApiContext;
+//
+//public class SignValidateHandlerTest extends TestCase {
+//
+//    @SuppressWarnings("rawtypes")
+//    public static void main(String[] args) throws FileNotFoundException, IOException {
+////        String str = "YeaDXXD4VZFKnDJr752R%2B6GIf9aenuWaqSHDqnYPZhhfoC8IlpkoG7Ts1Xrid0UfullWAlMeOk48kdAoUcMFbomMljLHICEzi2GUtYyuCPcFK%2FwFwFZxh2Q2FWh8EaZl%2F0g9Bp%2F7GxNYbeNb%2FVjPuh6MVM%2BoTCxJ8xfgP31YX7R4nKpWKk4tVLIy1FFKLkpNLEkNycxNBXJNjM0sTcxNTIDiqRUFmUXI4pYGZiDxknxXTBkDkExpZoqSlZGFoYm5qYGBsbmFsYWRiY5SUX5OKsSi1JwcJSslQwsDMLAwNVCqBQQAAP%2F%2FKnMkQw%3D%3D";
+////        String decode = URLDecoder.decode(str, "utf-8");
+////        System.out.println(decode);
+////        byte[] bs = Base64.decode(decode.getBytes("utf-8"));
+////        System.out.println(new String(bs, "utf-8"));
+////        String json = IOUtils.toString(new FileInputStream(new File("D:/ret.json")));
+////        System.out.println(json);
+////        String encode = URLEncoder.encode(json, "utf-8");
+////        System.out.println("encode:" + encode);
+////        System.out.println("decode:" + URLDecoder.decode(encode, "utf-8"));
+////        JSONObject object = JSON.parseObject(json);
+////        Map data = object.getObject("data", Map.class);
+////        System.out.println(data.get("echo"));
+//        System.out.println("123".equals(""));
+//    }
+//
+//    //构造context
+//    ApiContext context = new ApiContext();
+//
+//    //    public void setUp() throws Exception {
+//    //        //构造http参数
+//    //        Map<String, Object> httpParams = new HashMap<String, Object>();
+//    //        httpParams.put(PlatfromParamConstants.API, "user.get");
+//    //        httpParams.put(PlatfromParamConstants.API_VERSION, "1.0.0");
+//    //        httpParams.put(PlatfromParamConstants.APP_KEY, "dajia");
+//    //        httpParams.put(PlatfromParamConstants.HW_ID, "123456");
+//    //        httpParams.put(PlatfromParamConstants.OS_TYPE, "1");
+//    //        httpParams.put(PlatfromParamConstants.OS_VERSION, "4.0");
+//    //        httpParams.put(PlatfromParamConstants.TIMESTAMP, "20140102");
+//    //
+//    //        httpParams.put("userId", "20140102");
+//    //        httpParams.put("userPw", "dfd456");
+//    //        httpParams.put("account", "dfd456");
+//    //
+//    //        //构造API
+//    //        SimpleApi api = new SimpleApi();
+//    //        List<SimpleApiParam> sapList = new ArrayList<SimpleApiParam>();
+//    //        SimpleApiParam sap1 = new SimpleApiParam();
+//    //        sap1.setSourceName("userId");
+//    //        sapList.add(sap1);
+//    //        SimpleApiParam sap2 = new SimpleApiParam();
+//    //        sap2.setSourceName("userPw");
+//    //        sapList.add(sap2);
+//    //        SimpleApiParam sap3 = new SimpleApiParam();
+//    //        sap3.setSourceName("account");
+//    //        sapList.add(sap3);
+//    //        api.setParams(sapList);
+//    //
+//    //        //构造APP
+//    //        SimpleApp app = new SimpleApp("dajia", "dajia_sec");
+//    //
+//    //        context.setHttpParams(httpParams);
+//    //        context.setApi(api);
+//    //        context.setApp(app);
+//    //    }
+//    //
+//    //    public void testSign() {
+//    //
+//    //        //随便设定的sign,不通过
+//    //        context.getHttpParams().put(PlatfromParamConstants.SIGN, "suibianshede");
+//    //        ApiResult result = handler.handle(context);
+//    //        assertEquals(ApiCode.API_INVALID_REQUEST.getCode(), result.getCode());
+//    //
+//    //        //真实设置,通过
+//    //        String serverSign = handler.sign(context);
+//    //        System.out.println("serverSign:" + serverSign);
+//    //        context.getHttpParams().put(PlatfromParamConstants.SIGN, serverSign);
+//    //        result = handler.handle(context);
+//    //        assertNull(result);
+//    //    }
+//}

+ 259 - 0
src/test/java/com/sec/xinhua/gateway/web/HttpsClient.java

@@ -0,0 +1,259 @@
+//package com.sec.xinhua.gateway.web;
+//
+//import com.alibaba.fastjson.JSON;
+//import com.google.common.collect.Maps;
+//import org.apache.http.HttpEntity;
+//import org.apache.http.HttpResponse;
+//import org.apache.http.client.methods.HttpPost;
+//import org.apache.http.conn.scheme.Scheme;
+//import org.apache.http.conn.ssl.SSLSocketFactory;
+//import org.apache.http.entity.StringEntity;
+//import org.apache.http.entity.mime.MultipartEntity;
+//import org.apache.http.entity.mime.content.FileBody;
+//import org.apache.http.entity.mime.content.StringBody;
+//import org.apache.http.impl.client.DefaultHttpClient;
+//import org.apache.http.util.EntityUtils;
+//
+//import javax.net.ssl.*;
+//import java.io.File;
+//import java.io.FileInputStream;
+//import java.io.UnsupportedEncodingException;
+//import java.security.KeyStore;
+//import java.security.cert.CertificateException;
+//import java.security.cert.X509Certificate;
+//import java.util.Map;
+//
+//public class HttpsClient extends DefaultHttpClient {
+//
+//    /**
+//     * 绕过服务端证书验证
+//     *
+//     * @throws Exception
+//     */
+//    public HttpsClient() throws Exception {
+//        super();
+//        SSLContext ctx = SSLContext.getInstance("TLS");
+//        X509TrustManager xetm = new X509TrustManager() {
+//            @Override
+//            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+//
+//            }
+//
+//            @Override
+//            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+//
+//            }
+//
+//            @Override
+//            public X509Certificate[] getAcceptedIssuers() {
+//                return new X509Certificate[0];
+//            }
+//        };
+//        ctx.init(null, new TrustManager[]{xetm}, null);
+//        SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+//        this.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, ssf));
+//    }
+//
+//    /**
+//     * 需要服务端证书验证
+//     *
+//     * @param password
+//     * @param keyStorePath
+//     * @param trustStorePath
+//     * @throws Exception
+//     */
+//    public HttpsClient(String password, String keyStorePath, String trustStorePath) throws Exception {
+//        super();
+//        SSLContext ctx = getSSLContext(password, keyStorePath, trustStorePath);
+//        SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+//        this.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, ssf));
+//    }
+//
+//    /**
+//     * 获得KeyStore.
+//     *
+//     * @param keyStorePath 密钥库路径
+//     * @param password     密码
+//     * @return 密钥库
+//     * @throws Exception
+//     */
+//    public static KeyStore getKeyStore(String password, String keyStorePath)
+//            throws Exception {
+//        // 实例化密钥库
+//        KeyStore ks = KeyStore.getInstance("JKS");
+//        // 获得密钥库文件流
+//        FileInputStream is = new FileInputStream(keyStorePath);
+//        // 加载密钥库
+//        ks.load(is, password.toCharArray());
+//        // 关闭密钥库文件流
+//        is.close();
+//        return ks;
+//    }
+//
+//    /**
+//     * 获得SSLSocketFactory.
+//     *
+//     * @param password       密码
+//     * @param keyStorePath   密钥库路径
+//     * @param trustStorePath 信任库路径
+//     * @return SSLSocketFactory
+//     * @throws Exception
+//     */
+//    public static SSLContext getSSLContext(String password,
+//                                           String keyStorePath, String trustStorePath) throws Exception {
+//        // 实例化密钥库
+//        KeyManagerFactory keyManagerFactory = KeyManagerFactory
+//                .getInstance(KeyManagerFactory.getDefaultAlgorithm());
+//        // 获得密钥库
+//        KeyStore keyStore = getKeyStore(password, keyStorePath);
+//        // 初始化密钥工厂
+//        keyManagerFactory.init(keyStore, password.toCharArray());
+//
+//        // 实例化信任库
+//        TrustManagerFactory trustManagerFactory = TrustManagerFactory
+//                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
+//        // 获得信任库
+//        KeyStore trustStore = getKeyStore(password, trustStorePath);
+//        // 初始化信任库
+//        trustManagerFactory.init(trustStore);
+//        // 实例化SSL上下文
+//        SSLContext ctx = SSLContext.getInstance("TLS");
+//        // 初始化SSL上下文
+//        ctx.init(keyManagerFactory.getKeyManagers(),
+//                trustManagerFactory.getTrustManagers(), null);
+//        // 获得SSLSocketFactory
+//        return ctx;
+//    }
+//
+//
+//    /**
+//     * 测试方法.
+//     *
+//     * @param args
+//     * @throws Exception
+//     */
+//    public static void main(String[] args) throws Exception {
+//
+//        /**
+//         * URL,参数,签名构造
+//         */
+//        String appSecret = "4D145C6FA84E38099E49930D9D5B4B73D0C2317D";
+//        String appKey = "190001";
+//
+//        guideRequest(appSecret, appKey);
+//
+//        liveFail(appKey, appKey);
+//
+//        faceVerify(appSecret, appKey);
+////        /**
+////         * 方式一 : 绕过服务端证书验证
+////         */
+////        HttpsClient clientNoValidate = new HttpsClient();
+////        HttpResponse noValidateResponse = clientNoValidate.execute(httpRequest);
+////        System.out.println(EntityUtils.toString(noValidateResponse.getEntity(), "UTF-8"));
+//    }
+//
+//    /**
+//     * 引导接口测试
+//     *
+//     * @param signKey
+//     * @param appKey
+//     * @throws Exception
+//     */
+//    private static void guideRequest(String signKey, String appKey) throws Exception {
+//        Map<String, Object> params = Maps.newHashMap();
+//        params.put("token", "abcd");
+//        params.put("bizCode", 123);
+//        params.put("sdkVersion", "1.0.0");
+//        String signData = SignUtils.getSignData(params);
+//        String sign = SignUtils.getSign(signKey, signData);
+//        String url = "https://10.94.97.117:8443/risk-gateway/gateway?api=risk.face.guide&apiVersion=1.0.0&appKey=" + appKey + "&sign=" + sign;
+//        HttpPost httpRequest = new HttpPost(url);
+//        HttpEntity entity = new StringEntity(JSON.toJSONString(params), "UTF-8");
+//        httpRequest.setEntity(entity);
+//        /**
+//         * 方式二 : 需要服务端证书验证 (jdk生成的keystore)
+//         */
+//        String password = "hzsd.risk";
+//        String keyStorePath = "/usr/local/apache-tomcat-9.0.0/tomcat.keystore";
+//        String trustStorePath = "/usr/local/apache-tomcat-9.0.0/tomcat.keystore";
+//
+//        HttpsClient clientValidate = new HttpsClient(password, keyStorePath, trustStorePath);
+//        HttpResponse validateResponse = clientValidate.execute(httpRequest);
+//        System.out.println("guideRequest result : " + EntityUtils.toString(validateResponse.getEntity(), "UTF-8"));
+//    }
+//
+//    /**
+//     * 活体失败接口测试
+//     *
+//     * @param signKey
+//     * @param appKey
+//     * @throws Exception
+//     */
+//    private static void liveFail(String signKey, String appKey) throws Exception {
+//        Map<String, Object> params = Maps.newHashMap();
+//        params.put("aliveCheckFailParamJson", "aliveCheckFailParamJson-params");
+//        String signData = SignUtils.getSignData(params);
+//        String sign = SignUtils.getSign(signKey, signData);
+//        String url = "https://localhost:8443/risk-gateway/gateway?api=risk.faceplus.alive&apiVersion=1.0.0&appKey=" + appKey + "&sign=" + sign;
+//        HttpPost httpRequest = new HttpPost(url);
+//        HttpEntity entity = new StringEntity(JSON.toJSONString(params), "UTF-8");
+//        httpRequest.setEntity(entity);
+//        /**
+//         * 方式二 : 需要服务端证书验证 (jdk生成的keystore)
+//         */
+//        String password = "hzsd.risk";
+//        String keyStorePath = "/usr/local/apache-tomcat-9.0.0/tomcat.keystore";
+//        String trustStorePath = "/usr/local/apache-tomcat-9.0.0/tomcat.keystore";
+//
+//        HttpsClient clientValidate = new HttpsClient(password, keyStorePath, trustStorePath);
+//        HttpResponse validateResponse = clientValidate.execute(httpRequest);
+//        System.out.println("liveFail result : " + EntityUtils.toString(validateResponse.getEntity(), "UTF-8"));
+//    }
+//
+//    /**
+//     * 人脸验证接口测试
+//     *
+//     * @param signKey
+//     * @param appKey
+//     * @throws Exception
+//     */
+//    private static void faceVerify(String signKey, String appKey) throws Exception {
+//        Map<String, Object> params = Maps.newHashMap();
+//        params.put("token", "abcd");
+//        params.put("delta", "efgh");
+//        String signData = SignUtils.getSignData(params);
+//        String sign = SignUtils.getSign(signKey, signData);
+//        String url = "https://10.94.97.117:8443/risk-gateway/gateway?api=risk.faceplus.compare&apiVersion=1.0.0&appKey=" + appKey + "&sign=" + sign;
+//        HttpPost httpRequest = new HttpPost(url);
+//
+//
+//        MultipartEntity mutiEntity = new MultipartEntity();
+//        File bestPic = new File("/Users/zhangqingxin/test.jpg");
+//        File actionPic1 = new File("/Users/zhangqingxin/test2.png");
+//        File actionPic2 = new File("/Users/zhangqingxin/test2.png");
+//        File actionPic3 = new File("/Users/zhangqingxin/test2.png");
+//        File actionPic4 = new File("/Users/zhangqingxin/test2.png");
+//        mutiEntity.addPart("token", new StringBody("abcd"));
+//        mutiEntity.addPart("delta", new StringBody("efgh"));
+//        mutiEntity.addPart("bestPic", new FileBody(bestPic));
+//        mutiEntity.addPart("actionPic1", new FileBody(actionPic1));
+//        mutiEntity.addPart("actionPic2", new FileBody(actionPic2));
+//        mutiEntity.addPart("actionPic3", new FileBody(actionPic3));
+//        mutiEntity.addPart("actionPic4", new FileBody(actionPic4));
+//        httpRequest.setEntity(mutiEntity);
+//
+//        /**
+//         * 方式二 : 需要服务端证书验证 (jdk生成的keystore)
+//         */
+//        String password = "hzsd.risk";
+//        String keyStorePath = "/usr/local/apache-tomcat-9.0.0/tomcat.keystore";
+//        String trustStorePath = "/usr/local/apache-tomcat-9.0.0/tomcat.keystore";
+//
+//        HttpsClient clientValidate = new HttpsClient(password, keyStorePath, trustStorePath);
+//        HttpResponse validateResponse = clientValidate.execute(httpRequest);
+//        System.out.println("faceVerify result : " + EntityUtils.toString(validateResponse.getEntity(), "UTF-8"));
+//    }
+//
+//
+//}

+ 109 - 0
src/test/java/com/sec/xinhua/gateway/web/OtherTest.java

@@ -0,0 +1,109 @@
+package com.sec.xinhua.gateway.web;
+
+import com.alibaba.dubbo.common.utils.StringUtils;
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * Created by zhangqingxin
+ * Date : 16/4/12
+ * Time : ${Time}
+ */
+public class OtherTest {
+
+    private String value;
+
+    public OtherTest() {
+
+    }
+
+    public OtherTest(String value) {
+        this.value = value;
+    }
+
+    public int hashCode() {
+        return this.value.hashCode();
+    }
+
+    public boolean equals(Object o) {
+        if (o == null) {
+            return false;
+        }
+        if (!(o instanceof OtherTest)) {
+            return false;
+        }
+        return this.value.equals(((OtherTest) o).value);
+    }
+
+    public static void main(String[] args) throws Exception {
+        File f1 = new File("/Users/zhangqingxin/f1.txt");
+        File f2 = new File("/Users/zhangqingxin/f2.txt");
+        List<String> l1 = FileUtils.readLines(f1);
+        List<String> l2 = FileUtils.readLines(f2);
+        Set<String> s1 = new HashSet(l1.size());
+        Set<String> s2 = new HashSet(l2.size());
+        Set<String> s3 = new HashSet(s2.size());
+        System.out.println(l1.size());
+        System.out.println(l2.size());
+        int count = 0;
+        for (String ss : l1) {
+//            if (l1.contains("驾证")) {
+//                continue;
+//            }
+            s1.add(ss.toUpperCase());
+            count++;
+            if (count % 1000 == 0) {
+                System.out.println(count);
+            }
+        }
+        count = 0;
+        for (String sss : l2) {
+            s2.add(sss.toUpperCase());
+            count++;
+            if (count % 1000 == 0) {
+                System.out.println(count);
+            }
+        }
+        count = 0;
+        for (String s : s2) {
+            if (s1.contains(s)) {
+                continue;
+            }
+            s3.add(s);
+            count++;
+            if (count % 1000 == 0) {
+                System.out.println(count);
+            }
+        }
+        List<String> rs = new ArrayList(s3);
+        File f3 = new File("/Users/zhangqingxin/result.txt");
+        FileUtils.writeLines(f3, rs);
+    }
+
+
+    private static String buildDownPoint(String apiName) {
+        StringBuilder pointName = new StringBuilder();
+        String suffix = "ExcPoint";
+        if (StringUtils.isNotEmpty(apiName)) {
+            int len = apiName.split("\\.").length;
+            if (len <= 1) {
+                pointName.append(apiName);
+            } else {
+                pointName.append(apiName.split("\\.")[0]);
+                for (int i = 1; i < len; i++) {
+                    pointName.append(upFirstAlphabet(apiName.split("\\.")[i]));
+                }
+            }
+        }
+        pointName.append(suffix);
+        return pointName.toString();
+    }
+
+    private static String upFirstAlphabet(String word) {
+        StringBuilder sb = new StringBuilder(word);
+        sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
+        return sb.toString();
+    }
+}

File diff suppressed because it is too large
+ 362 - 0
src/test/java/com/sec/xinhua/gateway/web/PostReqTest.java


+ 55 - 0
src/test/java/com/sec/xinhua/gateway/web/SignUtils.java

@@ -0,0 +1,55 @@
+package com.sec.xinhua.gateway.web;
+
+import java.io.File;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by zhangqingxin
+ * Date : 16/5/11
+ * Time : 14:25
+ */
+public class SignUtils {
+    public static String getSignData(Map<String, Object> params) {
+        StringBuffer content = new StringBuffer();
+        // 按照key做排序
+        List<String> keys = new ArrayList<String>(params.keySet());
+        Collections.sort(keys);
+        for (int i = 0; i < keys.size(); i++) {
+            String key = keys.get(i);
+            Object value = params.get(key);
+            if (value instanceof byte[] || value instanceof File) {
+                continue;
+            }
+            if (value == null) {
+                continue;
+            }
+            content.append((i == 0 || content.length() == 0 ? "" : "&") + key + value.toString());
+
+        }
+        return content.toString();
+    }
+
+    public static String getSign(String signKey, String content) {
+        String result = content + "&" + signKey;
+        try {
+            MessageDigest md5 = MessageDigest.getInstance("MD5");
+            byte[] byteArray = result.getBytes("UTF-8");
+            byte[] md5Bytes = md5.digest(byteArray);
+            StringBuffer hexValue = new StringBuffer();
+            for (int i = 0; i < md5Bytes.length; i++) {
+                int val = ((int) md5Bytes[i]) & 0xff;
+                if (val < 16) {
+                    hexValue.append("0");
+                }
+                hexValue.append(Integer.toHexString(val));
+            }
+            return hexValue.toString().toUpperCase();
+        } catch (Exception e) {
+            return "";
+        }
+    }
+}