java内网环境使用代理访问外网api

java内网环境使用代理访问阿里云api
最近在开发一个app推送功能,我们选用了阿里云和极光的推送接口,在本地有网络的情况都推送成功了,用的阿里云的java_sdk。但是发布测试环境的时候,却推送失败了,是因为服务器属于内网环境,不可直接访问外网接口,所以需要通过代理服务器正向代理访问。

阿里云推送服务文档 https://help.aliyun.com/document_detail/48088.html.

  • 本人通过阿里云官方文档多次测试无果!
    java内网环境使用代理访问外网api_第1张图片

  • 所以准备不通过sdk的方式,而是通过http直接访问阿里云的open_api
    在翻读阿里云java_sdk的源代码后 找到了用于加密和签名的工具类

  • com.aliyuncs.utils.ParameterHelper.class 时间工具类 获取东八区

  • com.aliyuncs.auth.ShaHmac1.class Hmac-SHA1参数签名工具

  • com.aliyuncs.auth.RpcSignatureComposer.class 重写此方法加密参数获取Signature

maven

		<!--阿里云推送依赖-->
		<dependency>
			<groupId>com.aliyun</groupId>
			<artifactId>aliyun-java-sdk-push</artifactId>
			<version>3.10.0</version>
		</dependency>
		<dependency>
			<groupId>com.aliyun</groupId>
			<artifactId>aliyun-java-sdk-core</artifactId>
			<version>3.2.8</version>
		</dependency>

封装推送Open_Api

    @Value("${xxx.xxx.http.proxyHost:10.1.1.2}")
    private String aliProxyHost; //代理服务器地址

    @Value("${xxx.xxx.http.port:8888}") //代理服务器端口
    private int aliPort; 

    private static final String ALI_URL = "http://cloudpush.aliyuncs.com";

  /**
     * @param queries 推送必传参数,不同系统参数不同
     * @return
     */
    private PushResultDTO pushNotice(Map<String, String> queries) {
        PushResultDTO pushResultDTO = new PushResultDTO();
        String iso8601Time = ParameterHelper.getISO8601Time(new Date());
        queries.put("Format", "XML");
        queries.put("RegionId", regionId);
        queries.put("Version", "2016-08-01");
        queries.put("AccessKeyId", accessKeyId);
        queries.put("SignatureMethod", "HMAC-SHA1");
        queries.put("SignatureNonce", String.valueOf(System.currentTimeMillis()));
        queries.put("SignatureVersion", "1.0");
        queries.put("Timestamp", iso8601Time);
        String StringToSign = composeStringToSign(MethodType.POST, queries);
        System.out.println(StringToSign);
        ShaHmac1 shaHmac1 = new ShaHmac1();
        String secret = "";
        try {
            secret = shaHmac1.signString(StringToSign, accessKeySecret + "&");
            System.out.println(secret);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        queries.put("Signature", secret);
        log.info("开始代理请求 >>>>>>>>>>>>>>>>>>>");
        HttpHost proxy = new HttpHost(aliProxyHost, aliPort);
        String result = httpPostWithParam(ALI_URL, queries, proxy);
        log.info("代理结束{}", result);
        pushResultDTO.setPushMsg(result);
        pushResultDTO.setPushFlag(true);
        return pushResultDTO;
    }

    /**
     * 获取签名 
     * @param method  请求方式
     * @param queries 请求参数
     * @return
     */
    private static String composeStringToSign(MethodType method, Map<String, String> queries) {
        String[] sortedKeys = (String[]) queries.keySet().toArray(new String[0]);
        Arrays.sort(sortedKeys);
        StringBuilder canonicalizedQueryString = new StringBuilder();

        try {
            String[] arr$ = sortedKeys;
            int len$ = sortedKeys.length;

            for (int i$ = 0; i$ < len$; ++i$) {
                String key = arr$[i$];
                canonicalizedQueryString.append("&").append(AcsURLEncoder.percentEncode(key)).append("=").append(AcsURLEncoder.percentEncode((String) queries.get(key)));
            }

            StringBuilder stringToSign = new StringBuilder();
            stringToSign.append(method.toString());
            stringToSign.append("&");
            stringToSign.append(AcsURLEncoder.percentEncode("/"));
            stringToSign.append("&");
            stringToSign.append(AcsURLEncoder.percentEncode(canonicalizedQueryString.toString().substring(1)));
            return stringToSign.toString();
        } catch (UnsupportedEncodingException var13) {
            throw new RuntimeException("UTF-8 encoding is not supported.");
        }
    }

    public static String httpPostWithParam(String url, Map<String, String> map, HttpHost proxy) {
        long startTime = System.currentTimeMillis();
        String returnValue = "";
        CloseableHttpClient httpClient = HttpClients.createDefault();
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        try {
            //第一步:创建HttpClient对象
            httpClient = HttpClients.createDefault();

            //第二步:创建httpPost对象
            HttpPost httpPost = new HttpPost(url);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setProxy(proxy)
                    .build();
            httpPost.setConfig(requestConfig);

            //第三步:给httpPost设置form-data格式的参数
            List params = new ArrayList();
            for (String key : map.keySet()) {
                params.add(new BasicNameValuePair(key, map.get(key)));
            }
            HttpEntity httpEntity = new UrlEncodedFormEntity(params, "UTF-8");
            httpPost.setEntity(httpEntity);

            //第四步:发送HttpPost请求,获取返回值
            returnValue = httpClient.execute(httpPost, responseHandler); //调接口获取返回值时,必须用此方法

        } catch (Exception e) {
            log.warn("异常:", e);
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                log.warn("异常:", e);
            }
            long endTime = System.currentTimeMillis();
            log.debug("http post url: " + url + ",时间秒: " + (double) (endTime - startTime) / 1000 + ",请求参数: "
                    + map + ",返回参数: " + returnValue);
        }
        //第五步:处理返回值
        return returnValue;
    }

推送到ios

/**
*调用自己封装的方法 
*/
public PushResultDTO pushNoticeToSingleIOS(PushUser pushUser, UserDevice userDevice) {
        PushResultDTO pushResultDTO = new PushResultDTO();
        Map<String, String> queries = new LinkedHashMap<>();
        queries.put("AppKey", appKeyIOS);
        queries.put("ApnsEnv", apnsEnv);
        queries.put("Target", TARGET_DEVICE);
        queries.put("TargetValue", userDevice.getDeviceIdAli());
        String title = pushUser.getTitle();
        String body = pushUser.getContent();
        queries.put("Title", title);
        queries.put("Body", body);
        queries.put("Action", ActionEnum.IOS.getDeviceMpush());
	    logger.info("推送开始,ios调用阿里云接口");
        PushResultDTO pushResultDTO1 = pushNotice(queries);
        logger.info("推送结束,ios调用阿里云成功");
        return pushResultDTO1 ;
    }

java技术群: 931243010

你可能感兴趣的:(小波)