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

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

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

<dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.14.9</version>
        </dependency>

第二步:引入封装好的工具类: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;
		}
	}
}

第三步:封装具体的请求工具类对象: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);
    }
}

第四步:封装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;

	/** */
	/**
	 * <p>
	 * 生成密钥对(公钥和私钥)
	 * </p>
	 *
	 * @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;
	}

	/** */
	/**
	 * <p>
	 * 用私钥对信息生成数字签名
	 * </p>
	 *
	 * @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());
	}

	/** */
	/**
	 * <p>
	 * 校验数字签名
	 * </p>
	 *
	 * @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));
	}

	/** */
	/**
	 * <P>
	 * 私钥解密
	 * </p>
	 *
	 * @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");
	}

	/** */
	/**
	 * <p>
	 * 公钥解密
	 * </p>
	 *
	 * @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");
	}

	/** */
	/**
	 * <p>
	 * 公钥加密
	 * </p>
	 *
	 * @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);
	}

	/** */
	/**
	 * <p>
	 * 私钥加密
	 * </p>
	 *
	 * @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);
	}

	/** */
	/**
	 * <p>
	 * 获取私钥
	 * </p>
	 *
	 * @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());
	}

	/** */
	/**
	 * <p>
	 * 获取公钥
	 * </p>
	 *
	 * @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);
	}

}

第五步:响应给前端的实体对象: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;

}

第六步:封装具体的业务对应的请求实现进行推送,比如,我这里推送体育馆的场地业务数据为例: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("服务繁忙,请重试!");
    }
}

最后注意:推送的地址,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=

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

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要在Unity WebGL中获取Java推送过来的接口数据,可以使用WebSocket实现双向通信。以下是具体步骤: 1. 在Java中创建WebSocket服务器,例如: ``` public class JavaWebSocketServer extends WebSocketServer { public JavaWebSocketServer(int port) { super(new InetSocketAddress(port)); } @Override public void onOpen(WebSocket conn, ClientHandshake handshake) { System.out.println("WebSocket opened: " + conn.getRemoteSocketAddress()); } @Override public void onClose(WebSocket conn, int code, String reason, boolean remote) { System.out.println("WebSocket closed: " + conn.getRemoteSocketAddress() + " with exit code " + code + " additional info: " + reason); } @Override public void onMessage(WebSocket conn, String message) { System.out.println("WebSocket message received: " + message); // 在这里处理接收到的数据 } @Override public void onError(WebSocket conn, Exception ex) { System.out.println("WebSocket error: " + ex.getMessage()); } } ``` 2. 在Unity WebGL中,使用WebSocket连接到Java服务器,例如: ``` WebSocket ws = new WebSocket("ws://localhost:8080"); ws.OnOpen += (sender, e) => { Debug.Log("WebSocket opened: " + ws.Url); }; ws.OnMessage += (sender, e) => { Debug.Log("WebSocket message received: " + e.Data); // 在这里处理接收到的数据 }; ws.OnError += (sender, e) => { Debug.LogError("WebSocket error: " + e.Message); }; ws.OnClose += (sender, e) => { Debug.Log("WebSocket closed: " + ws.Url); }; ws.Connect(); ``` 3. 当Java服务器向WebSocket发送数据时,Unity WebGL就会触发OnMessage事件。可以在OnMessage事件中处理接收到的数据,例如: ``` ws.OnMessage += (sender, e) => { Debug.Log("WebSocket message received: " + e.Data); // 在这里处理接收到的数据 }; ``` 以上就是在Unity WebGL中获取Java推送过来的接口数据的具体步骤。需要注意的是,在使用WebSocket时,需要在Unity WebGL中启用WebSocket支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枯枫叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值