• java推送数据到指定的外部接口


    注意:文章中除工具类外,其他私钥,appid,pushUrl等xml里面的配置信息,不能直接使用的哦!

    先在坐标里面引入网络请求的坐标地址
    第一步:引入网络请求工具插件,我这里用的是:okhttp3

    <dependency>
                <groupId>com.squareup.okhttp3groupId>
                <artifactId>okhttpartifactId>
                <version>3.14.9version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    第二步:引入封装好的工具类:OkHttpUtil

    package com.yfh.sportcompetitioncoursesite.map.util;
    import com.alibaba.fastjson.JSON;
    import com.google.common.base.Joiner;
    import com.google.common.base.Preconditions;
    import lombok.Builder;
    import lombok.Builder.Default;
    import lombok.Data;
    import okhttp3.*;
    import org.apache.commons.collections.MapUtils;
    import org.apache.commons.lang3.StringUtils;
    import javax.net.ssl.*;
    import java.io.File;
    import java.io.IOException;
    import java.security.SecureRandom;
    import java.security.cert.X509Certificate;
    import java.util.Map;
    import java.util.Optional;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 基于OkHttp的网络请求封装
     * @author zdj
     * @date 2021年4月24日
     */
    public class OkHttpUtil {
    	public static final int EXCEPTION_CODE = -99;
    	public static final MediaType MediaType_Json = MediaType.parse("application/json; charset=utf-8");
    	public static final MediaType MediaType_Form = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
    	public static final MediaType MediaType_File = MediaType.parse("multipart/form-data; charset=utf-8");
    
    	private static RequestConfig defaultRequestConfig = RequestConfig.builder().build();
    
    	// 忽略https证书验证
    	private static X509TrustManager xtm;
    	private static SSLContext sslContext;
    	private static HostnameVerifier DO_NOT_VERIFY;
    	static {
    		createX509TrustManager();
    		createSSLContext();
    		createHostnameVerifier();
    	}
    
    	/******************** get from方法 start *********************/
    	public static OkRespone<String> get(String url) {
    		return get(url, String.class);
    	}
    
    	public static <T> OkRespone<T> get(String url, Class<T> tclass) {
    		return get(url, null, tclass, null);
    	}
    
    	public static <T> OkRespone<T> get(String url, Map<String, String> params, Class<T> tclass) {
    		return get(url, params, tclass, defaultRequestConfig);
    	}
    
    	public static OkRespone<String> getForm(String url, Map<String, String> params) {
    		return get(url, params, String.class);
    	}
    
    	public static <T> OkRespone<T> get(String url, Map<String, String> params, Class<T> tclass, RequestConfig config) {
    		Request request = buildGetRequest(url, params, config);
    		return doExecute(request, tclass, config);
    	}
    	/******************** get from方法 end ***********************/
    
    
    	/******************** post from方法 start ********************/
    	public static OkRespone<String> postForm(String url, Map<String, String> params) {
    		return postForm(url, params, String.class);
    	}
    
    	public static <T> OkRespone<T> postForm(String url, Map<String, String> params, Class<T> tclass) {
    		return postForm(url, params, tclass, defaultRequestConfig);
    	}
    
    	public static <T> OkRespone<T> postForm(String url, Map<String, String> params, Class<T> tclass,
    											RequestConfig config) {
    		Request request = buildPostFormRequest(url, params, config);
    		return doExecute(request, tclass, config);
    	}
    	/******************** post from方法 end ********************/
    
    
    	/******************** post body方法 start ******************/
    	public static OkRespone<String> post(String url) {
    		return post(url, null);
    	}
    
    	public static OkRespone<String> post(String url, String content) {
    		return post(url, content, String.class);
    	}
    
    	public static <T> OkRespone<T> post(String url, String content, Class<T> tclass) {
    		return post(url, content, tclass, defaultRequestConfig);
    	}
    
    	public static <T> OkRespone<T> post(String url, String content, Class<T> tclass, RequestConfig config) {
    		Request request = buildPostBodyRequest(url, content, config);
    		return doExecute(request, tclass, config);
    	}
    	/******************** post body方法 end ******************/
    
    
    
    	/******************** post file方法 start ******************/
    	public static OkRespone<String> postFile(String url, FileUploadParam param) {
    		return postFile(url, param, String.class);
    	}
    
    	public static <T> OkRespone<T> postFile(String url, FileUploadParam param, Class<T> tclass) {
    		return postFile(url, param, tclass, defaultRequestConfig);
    	}
    
    	public static <T> OkRespone<T> postFile(String url, FileUploadParam param, Class<T> tclass, RequestConfig config) {
    		Request request = buildPostFileRequest(url, param, config);
    		return doExecute(request, tclass, config);
    	}
    	/******************** post file方法 end ******************/
    
    
    	private static <T> OkRespone<T> doExecute(Request request, Class<T> tclass, RequestConfig config) {
    		OkHttpClient ok = buildOkHttpClient(request.isHttps(), config);
    		try (Response response = ok.newCall(request).execute()) {
    			return buildOkRespone(tclass, response);
    		} catch (Exception e) {
    			return OkRespone.<T>builder().code(EXCEPTION_CODE).message(e.getMessage()).build();
    		}
    	}
    
    	@SuppressWarnings("unchecked")
    	private static <T> OkRespone<T> buildOkRespone(final Class<T> tclass, final Response response) throws IOException {
    		String s = response.body().string();
    		return OkRespone.<T>builder().code(response.code()).message(response.message())
    				.data(tclass == String.class ? (T) s : JSON.parseObject(s, tclass)).build();
    	}
    
    	/**
    	 * 创建get请求
    	 */
    	private static Request buildGetRequest(String url, Map<String, String> params, RequestConfig config) {
    		Preconditions.checkNotNull(url, "url is null");
    		if (MapUtils.isNotEmpty(params)) {
    			StringBuilder sb = new StringBuilder(url);
    			sb.append(url.indexOf("?") > 0 ? "&" : "?");
    			sb.append(Joiner.on('&').useForNull(StringUtils.EMPTY).withKeyValueSeparator('=').join(params));
    			url = sb.toString();
    		}
    
    		Request.Builder b = new Request.Builder().get().url(url);
    		Optional.ofNullable(config.headers).ifPresent(h -> b.headers(h));
    		return b.build();
    	}
    
    	/**
    	 * 创建post body请求
    	 */
    	private static Request buildPostBodyRequest(String url, String content, RequestConfig config) {
    		RequestBody body = RequestBody.create(config.mediaType, StringUtils.trimToEmpty(content));
    		return buildPostRequest(url, config, body);
    	}
    
    	/**
    	 * 创建post form请求
    	 */
    	private static Request buildPostFormRequest(String url, Map<String, String> params, RequestConfig config) {
    		FormBody.Builder fomBuilder = new FormBody.Builder();
    		Optional.ofNullable(params)
    				.ifPresent(p -> p.entrySet().stream().filter(e -> StringUtils.isNotEmpty(e.getValue()))
    						.forEach(e -> fomBuilder.add(e.getKey(), e.getValue())));
    		return buildPostRequest(url, config, fomBuilder.build());
    	}
    
    	/**
    	 * 创建post file请求
    	 */
    	private static Request buildPostFileRequest(String url, FileUploadParam param, RequestConfig config) {
    		RequestBody body = RequestBody.create(MediaType_File, new File(param.filePath));
    		MultipartBody.Builder b = new MultipartBody.Builder().setType(MediaType_File);
    		b.addFormDataPart(param.formName, param.fileName, body);
    		Optional.ofNullable(param.params).ifPresent(p -> p.forEach((k, v) -> b.addFormDataPart(k, v)));
    		return buildPostRequest(url, config, b.build());
    	}
    
    	private static Request buildPostRequest(String url, RequestConfig config, RequestBody body) {
    		Preconditions.checkNotNull(url, "url is null");
    		Preconditions.checkNotNull(config, "config is null");
    		Request.Builder b = new Request.Builder().url(url).post(body);
    		Optional.ofNullable(config.headers).ifPresent(h -> b.headers(h));
    		return b.build();
    	}
    
    	/**
    	 * 创建ok连接
    	 */
    	private static OkHttpClient buildOkHttpClient(boolean isHttps, RequestConfig config) {
    		OkHttpClient.Builder builder = new OkHttpClient.Builder()
    				.connectTimeout(config.connectTimeout, TimeUnit.SECONDS)
    				.readTimeout(config.readTimeout, TimeUnit.SECONDS);
    		if (isHttps) {
    			builder.sslSocketFactory(sslContext.getSocketFactory(), xtm).hostnameVerifier(DO_NOT_VERIFY);
    		}
    		OkHttpClient ok = builder.build();
    		return ok;
    	}
    
    	// ========忽略https证书验证 start========
    	private static void createHostnameVerifier() {
    		if (DO_NOT_VERIFY != null) {
    			return;
    		}
    		DO_NOT_VERIFY = new HostnameVerifier() {
    			@Override
    			public boolean verify(String hostname, SSLSession session) {
    				return true;
    			}
    		};
    	}
    
    	private static void createX509TrustManager() {
    		if (xtm != null) {
    			return;
    		}
    		xtm = new X509TrustManager() {
    			@Override
    			public void checkClientTrusted(X509Certificate[] chain, String authType) {
    			}
    
    			@Override
    			public void checkServerTrusted(X509Certificate[] chain, String authType) {
    			}
    
    			@Override
    			public X509Certificate[] getAcceptedIssuers() {
    				X509Certificate[] x509Certificates = new X509Certificate[0];
    				return x509Certificates;
    			}
    		};
    	}
    
    	private static void createSSLContext() {
    		if (sslContext != null) {
    			return;
    		}
    		try {
    			sslContext = SSLContext.getInstance("SSL");
    			sslContext.init(null, new TrustManager[] { xtm }, new SecureRandom());
    		} catch (Exception e) {
    			// log.error("createSSLContext error", e);
    		}
    	}
    
    	// ========忽略https证书验证 end========
    
    	@Builder
    	@Data
    	public static class RequestConfig {
    		@Default
    		private int connectTimeout = 5;// 连接超时时间,单位秒
    		@Default
    		private int readTimeout = 30;
    		@Default
    		private MediaType mediaType = MediaType_Form;
    		private Headers headers;
    	}
    
    	@Builder
    	@Data
    	public static class FileUploadParam {
    		private String filePath;// 文件路径
    		private String fileName;// 文件名称
    		@Default
    		private String formName = "file";// 表单名字
    		private Map<String, String> params;
    	}
    
    	@Builder
    	@Data
    	public static class OkRespone<T> {
    		private int code;
    		private String message;
    		private T data;
    
    		public boolean isSuccessful() {
    			return code >= 200 && code < 300;
    		}
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288

    第三步:封装具体的请求工具类对象:RequestUtil

    package com.yfh.sportcompetitioncoursesite.map.util;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Component;
    import org.springframework.util.ObjectUtils;
    
    import java.io.UnsupportedEncodingException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.TreeMap;
    
    /**
     * @Description: 调用外部接口处理
     * @Author: zdj
     * @Date: 2021/07/16
     * @version: 1.0.0
     */
    @Slf4j
    @Component
    @Configuration
    public class RequestUtil {
    
        @Value("${sanwan.cd.appId}")
        @ApiModelProperty("appId")
        public String appId;
    
        @Value("${sanwan.cd.pushUrl}")
        @ApiModelProperty("推送地址url")
        public String pushUrl;
    
        @Value("${sanwan.cd.privateKey}")
        @ApiModelProperty("推送私钥")
        public String privateKey;
    
        /**
         * post 请求
         * @param method 请求方法
         * @param dto 参数
         * @return
         * @throws Exception
         */
        public JSONObject post(String method, JSONObject dto) throws Exception {
            log.info("接口调用入参::appId" + appId);
            log.info("接口调用入参::privateKey::" + privateKey);
            log.info("接口调用入参::pushUrl::" + pushUrl);
            
            // 封装公共参数
            Map<String, String> params = new HashMap<String, String>();
            params.put("app_id", appId);
            params.put("method", method);
            params.put("format", "json");
            params.put("charset", "utf-8");
            params.put("sign_type", "RSA2");
            params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            params.put("version", "1.0");
            params.put("biz_content", dto.toJSONString());
    
            // 对参数签名
            String sign = sign(params, privateKey);
            params.put("sign", sign);
    
            log.info("接口调用入参:方法名:{}, 请求参数:{}", method, JSON.toJSONString(params));
            JSONObject res = new JSONObject();
            res.put("code", 500);
            res.put("data", null);
            try {
                OkHttpUtil.OkRespone<String> okRespone = OkHttpUtil.postForm(pushUrl, params);
                if (ObjectUtils.isEmpty(okRespone)) {
                    res.put("msg", "接口返回空对象!");
                    return res;
                }
                log.info("接口出参:方法名:{}, 响应参数:{}", method, JSONObject.toJSONString(okRespone));
                res.put("code", okRespone.getCode());
                res.put("data", okRespone.getData());
                res.put("msg", okRespone.getMessage());
                return res;
            } catch (Exception e){
                e.printStackTrace();
                res.put("msg", e.getMessage());
                log.info("调用接口出错:" + e.getMessage());
            }
            return res;
        }
    
        /**
         * get 请求
         * @param method 请求方法
         * @param dto 参数
         * @return
         * @throws Exception
         */
        public JSONObject get(String method, JSONObject dto) throws Exception {
            log.info("接口调用入参::appId" + appId);
            log.info("接口调用入参::privateKey::" + privateKey);
            log.info("接口调用入参::pushUrl::" + pushUrl);
    
            // 封装公共参数
            Map<String, String> params = new HashMap<String, String>();
            params.put("app_id", appId);
            params.put("method", method);
            params.put("format", "json");
            params.put("charset", "utf-8");
            params.put("sign_type", "RSA2");
            params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            params.put("version", "1.0");
            params.put("biz_content", dto.toJSONString());
    
            // 对参数签名
            String sign = sign(params, privateKey);
            params.put("sign", sign);
    
            log.info("接口调用入参:方法名:{}, 请求参数:{}", method, JSON.toJSONString(params));
            JSONObject res = new JSONObject();
            res.put("code", 500);
            res.put("data", null);
            try {
                OkHttpUtil.OkRespone<String> okRespone = OkHttpUtil.getForm(pushUrl, params);
                if (ObjectUtils.isEmpty(okRespone)) {
                    res.put("msg", "接口返回空对象!");
                    return res;
                }
                log.info("接口出参:方法名:{}, 响应参数:{}", method, JSONObject.toJSONString(okRespone));
                res.put("code", okRespone.getCode());
                res.put("data", okRespone.getData());
                res.put("msg", okRespone.getMessage());
                return res;
            } catch (Exception e){
                e.printStackTrace();
                res.put("msg", e.getMessage());
                log.info("调用接口出错:" + e.getMessage());
            }
            return res;
        }
    
        /**
         * 签名生成sign值
         *
         * @param params
         * @param key
         * @return
         */
        private String sign(Map<String, String> params, String key)
                throws Exception{
            String body = buildBody(params);
            String sign = RSAUtils.sign(body, key);
            return sign;
        }
    
        /**
         * 组装待签名参数
         *
         * @param params
         * @return
         */
        private  String buildBody(Map<String, String> params)
                throws UnsupportedEncodingException {
            StringBuilder body = new StringBuilder();
            for (Map.Entry<String, String> p : new TreeMap<String, String>(params)
                    .entrySet()) {
                if (p.getValue() != null && !StringUtils.isEmpty(String.valueOf(p.getValue()))) {
                    body.append("&").append(p.getKey()).append("=").append(String.valueOf(p.getValue()));
                }
            }
            return body.toString().substring(1);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175

    第四步:封装RSA加密工具类:RSAUtils

    package com.yfh.sportcompetitioncoursesite.map.util;
    
    import javax.crypto.Cipher;
    import java.io.ByteArrayOutputStream;
    import java.security.*;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Base64;
    import java.util.HashMap;
    import java.util.Map;
    
    
    public class RSAUtils {
    
    	/** */
    	/**
    	 * 加密算法RSA
    	 */
    	public static final String KEY_ALGORITHM = "RSA";
    
    	/** */
    	/**
    	 * 签名算法
    	 */
    	public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
    
    	/** */
    	/**
    	 * 获取公钥的key
    	 */
    	private static final String PUBLIC_KEY = "RSAPublicKey";
    
    	/** */
    	/**
    	 * 获取私钥的key
    	 */
    	private static final String PRIVATE_KEY = "RSAPrivateKey";
    
    	/** */
    	/**
    	 * RSA最大加密明文大小
    	 */
    	private static final int MAX_ENCRYPT_BLOCK = 117;
    
    	/** */
    	/**
    	 * RSA最大解密密文大小
    	 */
    	private static final int MAX_DECRYPT_BLOCK = 128;
    
    	/** */
    	/**
    	 * 

    * 生成密钥对(公钥和私钥) *

    * * @return * @throws Exception */
    public static Map<String, Object> genKeyPair() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** */ /** *

    * 用私钥对信息生成数字签名 *

    * * @param content * 已加密数据 * @param privateKey * 私钥(BASE64编码) * * @return * @throws Exception */
    public static String sign(String content, String privateKey) throws Exception { byte[] keyBytes = Base64.getDecoder().decode(privateKey); byte[] data = content.getBytes("UTF-8"); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return encryptBASE64(signature.sign()); } /** */ /** *

    * 校验数字签名 *

    * * @param content * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @param sign * 数字签名 * * @return * @throws Exception * */
    public static boolean verify(String content, String publicKey, String sign) throws Exception { byte[] keyBytes = Base64.getDecoder().decode(publicKey); byte[] data = content.getBytes("UTF-8"); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(Base64.getDecoder().decode(sign)); } /** */ /** *

    * 私钥解密 *

    * * @param content * 已加密数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */
    public static String decryptByPrivateKey(String content, String privateKey) throws Exception { byte[] keyBytes = Base64.getDecoder().decode(privateKey); byte[] encryptedData = decryptBASE64(content); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return new String(decryptedData, "UTF-8"); } /** */ /** *

    * 公钥解密 *

    * * @param content * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */
    public static String decryptByPublicKey(String content, String publicKey) throws Exception { byte[] keyBytes = Base64.getDecoder().decode(publicKey); byte[] encryptedData = decryptBASE64(content); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return new String(decryptedData, "UTF-8"); } /** */ /** *

    * 公钥加密 *

    * * @param content * 源数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */
    public static String encryptByPublicKey(String content, String publicKey) throws Exception { byte[] keyBytes = Base64.getDecoder().decode(publicKey); byte[] data = content.getBytes("UTF-8"); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); // Base64加密 return encryptBASE64(encryptedData); } /** */ /** *

    * 私钥加密 *

    * * @param content * 源数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */
    public static String encryptByPrivateKey(String content, String privateKey) throws Exception { byte[] keyBytes = Base64.getDecoder().decode(privateKey); byte[] data = content.getBytes("UTF-8"); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); // Base64加密 return encryptBASE64(encryptedData); } /** */ /** *

    * 获取私钥 *

    * * @param keyMap * 密钥对 * @return * @throws Exception */
    public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return Base64.getEncoder().encodeToString(key.getEncoded()); } /** */ /** *

    * 获取公钥 *

    * * @param keyMap * 密钥对 * @return * @throws Exception */
    public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64.getEncoder().encodeToString(key.getEncoded()); } /** * BASE64解密 * * @param key * @return * @throws Exception */ public static byte[] decryptBASE64(String key) throws Exception { return Base64.getDecoder().decode(key); } /** * BASE64加密 * * @param key * @return * @throws Exception */ public static String encryptBASE64(byte[] key) throws Exception { return Base64.getEncoder().encodeToString(key); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356

    第五步:响应给前端的实体对象:Result

    package com.yfh.sportcompetitioncoursesite.system.vo;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    import java.io.Serializable;
    
    /**
     * @author zdj
     * @version 1.0
     * @date 2022/2/14 14:39
     */
    @Data
    @ApiModel(value = "接口返回对象", description = "接口返回对象")
    public class Result<T> implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        /**
         * 成功标志
         */
        @ApiModelProperty(value = "成功标志")
        private boolean success = true;
    
        /**
         * 返回处理消息
         */
        @ApiModelProperty(value = "返回处理消息")
        private String message = "";
    
        /**
         * 返回代码
         */
        @ApiModelProperty(value = "返回代码")
        private Integer code = 0;
    
        /**
         * 返回数据对象 data
         */
        @ApiModelProperty(value = "返回数据对象")
        private T result;
    
        /**
         * 时间戳
         */
        @ApiModelProperty(value = "时间戳")
        private long timestamp = System.currentTimeMillis();
    
        public Result() {
        }
    
        /**
         * 兼容VUE3版token失效不跳转登录页面
         *
         * @param code
         * @param message
         */
        public Result(Integer code, String message) {
            this.code = code;
            this.message = message;
        }
    
        public Result<T> success(String message) {
            this.message = message;
            this.code = 200;
            this.success = true;
            return this;
        }
    
        @Deprecated
        public static Result<Object> ok() {
            Result<Object> r = new Result<Object>();
            r.setSuccess(true);
            r.setCode(200);
            return r;
        }
    
        @Deprecated
        public static Result<Object> ok(String msg) {
            Result<Object> r = new Result<Object>();
            r.setSuccess(true);
            r.setCode(200);
            r.setMessage(msg);
            return r;
        }
    
        @Deprecated
        public static Result<Object> ok(Object data) {
            Result<Object> r = new Result<Object>();
            r.setSuccess(true);
            r.setCode(200);
            r.setResult(data);
            return r;
        }
    
        public static <T> Result<T> OK() {
            Result<T> r = new Result<T>();
            r.setSuccess(true);
            r.setCode(200);
            return r;
        }
    
        public static <T> Result<T> OK(String msg) {
            Result<T> r = new Result<T>();
            r.setSuccess(true);
            r.setCode(200);
            r.setMessage(msg);
            return r;
        }
    
        public static <T> Result<T> OK(T data) {
            Result<T> r = new Result<T>();
            r.setSuccess(true);
            r.setCode(200);
            r.setResult(data);
            return r;
        }
    
        public static <T> Result<T> OK(String msg, T data) {
            Result<T> r = new Result<T>();
            r.setSuccess(true);
            r.setCode(200);
            r.setMessage(msg);
            r.setResult(data);
            return r;
        }
    
        public static <T> Result<T> error(String msg, T data) {
            Result<T> r = new Result<T>();
            r.setSuccess(false);
            r.setCode(500);
            r.setMessage(msg);
            r.setResult(data);
            return r;
        }
    
        public static Result<Object> error(String msg) {
            return error(500, msg);
        }
    
        public static Result<Object> error(int code, String msg) {
            Result<Object> r = new Result<Object>();
            r.setCode(code);
            r.setMessage(msg);
            r.setSuccess(false);
            return r;
        }
    
        public Result<T> error500(String message) {
            this.message = message;
            this.code = 500;
            this.success = false;
            return this;
        }
    
        /**
         * 无权限访问返回结果
         */
        public static Result<Object> noauth(String msg) {
            return error(510, msg);
        }
    
        @JsonIgnore
        private String onlTable;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168

    第六步:封装具体的业务对应的请求实现进行推送,比如,我这里推送体育馆的场地业务数据为例:SportServiceImpl

    package com.yfh.sportcompetitioncoursesite.map.service.impl;
    
    import cn.hutool.core.convert.Convert;
    import com.alibaba.fastjson.JSONObject;
    import com.yfh.sportcompetitioncoursesite.map.mapper.SiteMessageMapper;
    import com.yfh.sportcompetitioncoursesite.map.po.SiteMessage;
    import com.yfh.sportcompetitioncoursesite.map.util.RequestUtil;
    import com.yfh.sportcompetitioncoursesite.system.constants.CacheContant;
    import com.yfh.sportcompetitioncoursesite.system.vo.Result;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * @author zdj
     * @version 1.0
     * @date 2022/2/24 15:47
     */
    @Slf4j
    @Service
    public class SportServiceImpl {
    
        /**
         * 场地 mapper
         */
        @Autowired
        private SiteMessageMapper siteMessageMapper;
    
        /**
         * 新增场地
         * @return
         */
        public Result saveSite(SiteMessage siteMessage) {
            try {
                siteMessage.setIsDel(CacheContant.TWO);
    
                // 先推送数据到体育局
                Result result = this.pushSiteToTiYuJu(siteMessage);
                if(result.getCode().intValue() != 200){
                    throw new RuntimeException(result.getMessage());
                }
                String sportId = result.getMessage();
                siteMessage.setSportId(Convert.toInt(sportId));
    
                // 新增本地场地数据
                int addResult = siteMessageMapper.insert(siteMessage);
                if (addResult == CacheContant.ZERO) {
                    throw new RuntimeException("新增场地失败");
                }
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            }
            return Result.OK();
        }
    
        /**
         * 推送场地数据到体育局
         * @param siteMessage 场地对象
         * @return
         */
        public Result pushSiteToTiYuJu(SiteMessage siteMessage) {
            log.info("场地信息推送到体育局平台...开始");
            // 申请最终请求的对象
            JSONObject jsob = new JSONObject();
    
            /**************************封装请求参数对象**************************************/
            // 基础信息
            jsob.put("address", siteMessage.getSiteDetailPlace());	 	// 场馆场地地址信息
            jsob.put("name", siteMessage.getSiteName());    	        // 场馆场地名称
            jsob.put("openTime", siteMessage.getOpenTime());    	    // 开放时间信息
            jsob.put("photos", siteMessage.getSitePhoto());    	        // 场地图片(可多张),逗号隔开
            jsob.put("provinceCode", "330000");    	                    // 所在省级编码
    
            /**************************调用接口,进行推送**************************************/
            try {
                JSONObject result = new RequestUtil().post("mise.gym.updateGymData", jsob);
                if (result.getInteger("code").intValue() != 1000) {
                    return Result.error(result.getString("msg"));
                }
                log.info("场地信息推送到体育局平台...结束");
                return Result.ok(result.getString("data"));
            } catch (Exception e){
                e.printStackTrace();
                log.error("场地信息推送到体育局平台出错:" + e);
            }
            return Result.error("服务繁忙,请重试!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    最后注意:推送的地址,appid,私钥等,需要在xml里面进行配好哈,用测试环境和正式环境区分一下,列:
    在这里插入图片描述

    下面是dev.properties里面的推送配置信息,pro.properties里面根据自己实际情况填写

    #推送场地数据到体育馆需要的配置信息
    sanwan.cd.appId = 1222061594657525695803392
    sanwan.cd.pushUrl = http://ww.span.ceshi.com
    sanwan.cd.privateKey = IIEvQIBADANBgkhXtMHWHncbtv/8Y+376d+Ep21riQnirsORaZYOdb7CW2xjCTkfZzXX8QGncoXw2vFJKi29wi2tVJknC6/UUL3dkb+bxc8ZhL3TufzGelOPWmuE7Zi1H9AExJVv0im4jH3U7R8oNniVLl4v2AWJu9OVGSjZURhhz44UpoK5VZH6s=
    
    • 1
    • 2
    • 3
    • 4

    注意:文章中除工具类外,其他私钥,appid,pushUrl等xml里面的配置信息,不能直接使用的哦!

  • 相关阅读:
    PL/SQL+cpolar公网访问内网Oracle数据库
    电子学会C/C++编程等级考试2022年09月(一级)真题解析
    这个困扰程序员50年的问题,终于要被解决了?
    基于ubuntu 22, jdk 8x64搭建图数据库环境 hugegraph--google镜像chatgpt
    IP-guard助力能源企业完善终端防泄密措施,保护机密资料安全
    Flutter关于StatefulWidget中State刷新时机的一点实用理解
    乾元通聚合路由器实现多5G转WIFI6信号覆盖
    【鸿蒙开发】第十七章 Web组件(一)
    HTML5期末考核大作业:基于Html+Css+javascript的网页制作(化妆品公司网站制作)
    soildwork2022怎么恢复软件界面的默认设置?
  • 原文地址:https://blog.csdn.net/gelinwangzi_juge/article/details/127447759