腾讯云>>云通信>>TLS后台API在mac上JAVA DEMO搭建

来源:互联网 发布:java捕获被0除的异常 编辑:程序博客网 时间:2024/06/06 20:09

云通信相关资料下载地址


https://share.weiyun.com/2b3abe0e3f185c440cf455647455f661


Java demo


根据官方提供的demo做了调整,更符合spring-boot的风格

import java.util.Map;/** * Created by saleson on 2017/10/24. */public class IMActionResult {    private Map<String, Object> result;    public IMActionResult(Map<String, Object> result) {        this.result = result;    }    public boolean isSuccess() {        return "OK".equals(getActionStatus());    }    public String getActionStatus() {        return (String) result.get("ActionStatus");    }    public String getErrorInfo() {        return (String) result.get("ErrorInfo");    }    public int getErrorCode() {        return (int) result.get("ErrorCode");    }    public Map<String, Object> getResult() {        return result;    }    public Object getObject(String name) {        return result.get(name);    }    public <T> T get(String name) {        return (T) result.get(name);    }}
/** * Created by saleson on 2017/10/23. */public class TencentIMConfig {    private String sdkAppid;    private String jnisigcheckLibPath;    private String privateKeyPath;    private String privateKey;    private String defaultImAdminAccount;    public String getSdkAppid() {        return sdkAppid;    }    public void setSdkAppid(String sdkAppid) {        this.sdkAppid = sdkAppid;    }    public String getJnisigcheckLibPath() {        return jnisigcheckLibPath;    }    public void setJnisigcheckLibPath(String jnisigcheckLibPath) {        this.jnisigcheckLibPath = jnisigcheckLibPath;    }    public String getPrivateKeyPath() {        return privateKeyPath;    }    public void setPrivateKeyPath(String privateKeyPath) {        this.privateKeyPath = privateKeyPath;    }    public String getPrivateKey() {        return privateKey;    }    public void setPrivateKey(String privateKey) {        this.privateKey = privateKey;    }    public String getDefaultImAdminAccount() {        return defaultImAdminAccount;    }    public void setDefaultImAdminAccount(String defaultImAdminAccount) {        this.defaultImAdminAccount = defaultImAdminAccount;    }}
import com.fasterxml.jackson.annotation.JsonProperty;/** * Created by saleson on 2017/10/23. */public class IMActionResponse {    @JsonProperty("ActionStatus")    private String ActionStatus;    @JsonProperty("ErrorInfo")    private String ErrorInfo;    @JsonProperty("ErrorCode")    private int ErrorCode;    public boolean isSuccess() {        return "OK".equals(ActionStatus);    }    public String getActionStatus() {        return ActionStatus;    }    public void setActionStatus(String actionStatus) {        ActionStatus = actionStatus;    }    public String getErrorInfo() {        return ErrorInfo;    }    public void setErrorInfo(String errorInfo) {        ErrorInfo = errorInfo;    }    public int getErrorCode() {        return ErrorCode;    }    public void setErrorCode(int errorCode) {        ErrorCode = errorCode;    }}
import com.fasterxml.jackson.annotation.JsonProperty;import java.util.List;/** * Created by saleson on 2017/10/23. */public class IMMultiAccImportResponse extends IMActionResponse {    @JsonProperty("FailAccounts")    private List<String> FailAccounts;    public List<String> getFailAccounts() {        return FailAccounts;    }    public void setFailAccounts(List<String> failAccounts) {        FailAccounts = failAccounts;    }}
import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.core.type.TypeReference;import com.fasterxml.jackson.databind.ObjectMapper;import com.google.common.base.Joiner;import com.google.common.collect.ImmutableList;import com.google.common.collect.ImmutableMap;import com.google.common.collect.Maps;import com.tls.sigcheck.tls_sigcheck;import org.apache.commons.lang3.ObjectUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.client.RestTemplate;import java.io.IOException;import java.util.Arrays;import java.util.List;import java.util.Map;/** * Created by saleson on 2017/10/23. */public class TencentIMHelper {    private static final Logger log = LoggerFactory.getLogger(TencentIMHelper.class);    private TencentIMConfig config;    private RestTemplate rest;    private ObjectMapper objectMapper;    private Joiner.MapJoiner joiner = Joiner.on("&").withKeyValueSeparator("=");    public TencentIMHelper(TencentIMConfig config, RestTemplate rest, ObjectMapper objectMapper) {        this.config = config;        this.rest = rest;        this.objectMapper = objectMapper;    }    /**     * 生成usersig     *     * @param identifier     * @return     */    public String genUsersig(String identifier) {        tls_sigcheck demo = new tls_sigcheck();        // 使用前请修改动态库的加载路径        demo.loadJniLib(config.getJnisigcheckLibPath());        int ret = demo.tls_gen_signature_ex2(config.getSdkAppid(), identifier, config.getPrivateKey());        if (0 != ret) {            log.error("ret: {}, errMsg:{}", ret, demo.getErrMsg());            throw new ClientException(ResultCode.IM_ACCOUNT_LOGIN_FAILD);        } else {            String usersig = demo.getSig();            System.out.println("sig:\n" + demo.getSig());            log.debug("identifier '{}' take usersig is {}", identifier, usersig);            return usersig;        }    }    /**     * 获取默认设置的im admin 账号的usersig     *     * @return     */    public String getIMAdminUsersig() {        if (StringUtils.isEmpty(config.getDefaultImAdminAccount())) {            log.error("TencentIMConfig.defaultImAdminAccount不存在");            throw new ServerException(ResultCode.IM_ACCOUNT_LOGIN_FAILD.getResultCode(), "默认的IM admin账号不存在");        }        return getIMAdminUsersig(config.getDefaultImAdminAccount());    }    /**     * 获取im admin 账号的usersig     *     * @param identifier     * @return     */    public String getIMAdminUsersig(String identifier) {        String usersig = _getIMAdminUsersig(identifier);        if (StringUtils.isEmpty(usersig)) {            usersig = genUsersig(identifier);            cacheIMAdminUsersig(identifier, usersig);        }        return usersig;    }    /**     * 导入账号     *     * @param accountId     */    public void accountImport(String accountId) {        String url = "https://console.tim.qq.com/v4/im_open_login_svc/account_import?";        String queryString = joiner.join(getDefaultParams());        Map<String, String> requestBody = ImmutableMap.of("Identifier", accountId);        IMActionResponse res = request(url + queryString, requestBody, IMActionResponse.class);        if (!res.isSuccess()) {            log.error("导入'{}'到腾讯云IM失败, response message is: {}", toString(res));            throw new ClientException(ResultCode.IM_ACCOUNT_CREATE_FAILD);        }    }    /**     * 帐号批量导入     *     * @param accountIds 用户名,单个用户名长度不超过 32 字节,单次最多导入100个用户名     * @return 返回导入失败的帐号列表     */    public List<String> multiAccountImport(String... accountIds) {        String url = "https://console.tim.qq.com/v4/im_open_login_svc/multiaccount_import?";        String queryString = joiner.join(getDefaultParams());        Map<String, List<String>> requestBody = ImmutableMap.of("Accounts", Arrays.asList(accountIds));        IMMultiAccImportResponse res = request(url + queryString, requestBody, IMMultiAccImportResponse.class);        if (!res.isSuccess()) {            log.error("帐号批量导入失败:{}, response message is: {}",                    StringUtils.join(accountIds, ", "),                    toString(res));            throw new ClientException(ResultCode.IM_ACTION_FAILD);        }        return res.getFailAccounts();    }    /**     * 设置用户资料(IM)     *     * @param userDTO     */    public void setAccountProfile(UserDTO userDTO) {        String url = "https://console.tim.qq.com/v4/profile/portrait_set?";        String queryString = joiner.join(getDefaultParams());        String nikename = userDTO.getNickName()        int gder = ObjectUtils.defaultIfNull(userDTO.getGender(), 0);        String gender = gder == 1 ? "Gender_Type_Male" : gder == 2 ? "Gender_Type_Female" : "Gender_Type_Unknown";        Map<String, Object> requestBody = ImmutableMap.of("From_Account", userDTO.getLogin(),                "ProfileItem", ImmutableList.of(                        ofProPortItem("Tag_Profile_IM_Nick", nikename),                        ofProPortItem("Tag_Profile_IM_Gender", gender),                        ofProPortItem("Tag_Profile_IM_Image",                                ResourceUtils.getFullResourceUrl(userDTO.getAvatar()))//                        ofProPortItem("", ""),//                        ofProPortItem("", ""),//                        ofProPortItem("", ""),//                        ofProPortItem("", "")                ));        IMActionResult res = request(url + queryString, requestBody);        if (!res.isSuccess()) {            log.error("调用'{}'的账号信息到腾讯云IM失败, response message is: {}",                    userDTO.getLogin(), toString(res.getResult()));            throw new ClientException(ResultCode.IM_ACCOUNT_INFO_SET_FAILD);        }    }    /**     * @param tag     * @param value     * @return     */    private Map<String, Object> ofProPortItem(String tag, Object value) {        return ImmutableMap.of("tag", tag, "value", value);    }    /**     * 默认值     *     * @param obj     * @param def     * @return     */    private Object defNull(Object obj, Object def) {        return obj == null ? def : obj;    }    /**     * 返回默认的参数     *     * @return     */    private Map<String, String> getDefaultParams() {        Map<String, String> pathParams = Maps.newHashMap();        pathParams.put("usersig", getIMAdminUsersig());        pathParams.put("identifier", config.getDefaultImAdminAccount());        pathParams.put("sdkappid", config.getSdkAppid());        pathParams.put("random", StringUtils.uuid());        pathParams.put("contenttype", "json");        return pathParams;    }    private void initPrivateKey() {        if (StringUtils.isNotEmpty(config.getPrivateKey())) {            return;        }        if (StringUtils.isEmpty(config.getPrivateKeyPath())) {            throw new ServerException(ResultCode.OPERATION_FAILD.getResultCode(), "腾讯云通讯无法找到privateKey");        }        //todo    }    private <T> T request(String url, Object params, Class<T> cls) {        return toBean(requestInvoke(url, params), cls);    }    private IMActionResult request(String url, Object params) {        Map<String, Object> map = toBean(requestInvoke(url, params),                new TypeReference<Map<String, Object>>() {                });        return new IMActionResult(map);    }    private String requestInvoke(String url, Object params) {        String json = rest.postForObject(url, params, String.class);        try {            log.info("request url {}, the params is: {}, and response: {}", url, objectMapper.writeValueAsString(params), json);        } catch (IOException e) {        }        return json;    }    private <T> T toBean(String json, Class<T> cls) {        try {            return objectMapper.readValue(json, cls);        } catch (IOException e) {            log.error("json:{} 转换类型失败: {} ", json, cls);            log.error(e.getMessage(), e);            throw new ServerException(ResultCode.OPERATION_FAILD.getResultCode(), "转换json失败");        }    }    private <T> T toBean(String json, TypeReference<T> type) {        try {            return objectMapper.readValue(json, type);        } catch (IOException e) {            log.error("json:{} 转换类型失败: {} ", json, type.getType());            log.error(e.getMessage(), e);            throw new ServerException(ResultCode.OPERATION_FAILD.getResultCode(), "转换json失败");        }    }    private String _getIMAdminUsersig(String identifier) {        //todo        return null;    }    private void cacheIMAdminUsersig(String identifier, String usersig) {        //todo    }    private String toString(Object obj) {        if (obj == null) {            return null;        } else if ("".equals(obj)) {            return "";        }        try {            return objectMapper.writeValueAsString(obj);        } catch (JsonProcessingException e) {            return obj.toString();        }    }}

Test

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;import com.fasterxml.jackson.databind.ObjectMapper;import com.tls.sigcheck.tls_sigcheck;import org.junit.Test;import org.springframework.http.MediaType;import org.springframework.http.client.ClientHttpRequestFactory;import org.springframework.http.client.ClientHttpResponse;import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;import org.springframework.web.client.RestTemplate;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.List;/** * Created by saleson on 2017/10/23. */public class TencentIMTest {    @Test    public void testHelper() throws IOException {        TencentIMConfig config = new TencentIMConfig();        config.setDefaultImAdminAccount("testadmin");        config.setSdkAppid("1400046172");        //config.setJnisigcheckLibPath("tencent_im/tls_sig_api-src/src/jnisigcheck.so");        config.setJnisigcheckLibPath("tencent_im/jnisigcheck_mt_x64.so");        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("thirdparty/tencent/im/private_key");        BufferedReader br = new BufferedReader(new InputStreamReader(is));        StringBuilder strBuilder = new StringBuilder();        String s = "";        while ((s = br.readLine()) != null) {            strBuilder.append(s + '\n');        }        br.close();        String priKey = strBuilder.toString();        config.setPrivateKey(priKey);//        config.setPrivateKeyPath("");//        RestTemplate rest = new RestTemplate();//        rest.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter()));        RestTemplate rest = jsonRestTemplate();        TencentIMHelper helper = new TencentIMHelper(config, rest, new ObjectMapper());        String adminUsersig = helper.getIMAdminUsersig();        System.out.println("adminUsersig:\n" + adminUsersig);        helper.accountImport("test10");        List<String> list = helper.multiAccountImport("test2jalsdkfjaoisdufo32jkleoflkjasdkfjasdiufowerquwlkj0", "test21", "test22", "test23");        System.out.println(list);    }    public RestTemplate jsonRestTemplate() {        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());        restTemplate.getMessageConverters().add(0, new FastJsonHttpMessageConverter());        restTemplate.getInterceptors().add((request, body, execution) -> {            System.out.println(new String(body));            ClientHttpResponse response = execution.execute(request, body);            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);            return response;        });        return restTemplate;    }    private ClientHttpRequestFactory clientHttpRequestFactory() {        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();        factory.setReadTimeout(30000);        factory.setConnectTimeout(30000);        return factory;    }}

上面的代码在linux环境上是可能正常运行了。
但是要在mac上运行调试, 会报错:

java.lang.UnsatisfiedLinkError: /Users/saleson/Downloads/tencent_im/jnisigcheck_mt_x64.so: dlopen(/Users/saleson/Downloads/tencent_im/jnisigcheck_mt_x64.so, 1): no suitable image found.  Did find:    /Users/saleson/Downloads/tencent_im/jnisigcheck_mt_x64.so: unknown file type, first eight bytes: 0x7F 0x45 0x4C 0x46 0x02 0x01 0x01 0x00    /Users/saleson/Downloads/tencent_im/jnisigcheck_mt_x64.so: unknown file type, first eight bytes: 0x7F 0x45 0x4C 0x46 0x02 0x01 0x01 0x00    at java.lang.ClassLoader$NativeLibrary.load(Native Method)    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)    at java.lang.Runtime.load0(Runtime.java:809)    at java.lang.System.load(System.java:1086)    at com.tls.sigcheck.tls_sigcheck.loadJniLib(tls_sigcheck.java:9)    at com.thirdparty.tencent.im.TencentIMHelper.genUsersig(TencentIMHelper.java:48)    at com.thirdparty.tencent.im.TencentIMHelper.getIMAdminUsersig(TencentIMHelper.java:85)    at com.thirdparty.tencent.im.TencentIMHelper.getIMAdminUsersig(TencentIMHelper.java:72)    at com.thirdparty.TencentIMTest.testHelper(TencentIMTest.java:123)

因此在mac上,需要重新编译生成jnisigcheck.so文件。


编译jnisigcheck.so


下载并解压tls_sig_api-src.tar.gz
进入src目录,查看Makefile

$ tar -zxvf tls_sig_api_src.tar.gz$ cd tls_sig_api-src/src$ vim Makefile

Makefile

CPP = g++CC = gccARCH=$(shell getconf LONG_BIT)CFLAGS= -g -I../include -I../include/tls_sig_api -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -Wall -fPICLIBS= ../linux/$(ARCH)/lib/jsoncpp/libjsoncpp.a ../openssl-dynamic/lib/libcrypto.a -ldl -lzTARGETS = libtlsignature.a sigcheck.so signatureall: $(TARGETS)libtlsignature.a: tls_signature.o multi_thread.o base64.o base64_url.o    ar -rs $@ $^# jni 库编译前请安装 jdk,并且配置 JAVA_HOME 环境变量jni: com_tls_sigcheck_tls_sigcheck.o libtlsignature.a    g++ -shared -o jnisigcheck.so $^ ../linux/$(ARCH)/lib/jsoncpp/libjsoncpp.a ../openssl-dynamic/lib/libcrypto.a -lzsignature: signature.o libtlsignature.a    g++ -o $@ $^ ../linux/$(ARCH)/lib/jsoncpp/libjsoncpp.a ../openssl-dynamic/lib/libcrypto.a -ldl -lzsigcheck.so: sigcheck.o libtlsignature.a sigcheck.h    g++ -shared -fPIC -o $@ $^ ../linux/$(ARCH)/lib/jsoncpp/libjsoncpp.a ../openssl-dynamic/lib/libcrypto.a -ldl -lz.cpp.o:    $(CPP) $(CFLAGS) -c $*.cpp.c.o:    $(CC) $(CFLAGS) -c $*.cclean:      -rm -f *.o *.so *.a tls_licence_tools TAGS $(TARGETS)

可以看到使用make jni生成jnisigcheck.so。执行命令之后,并没有像我们想象那样生成了jnisigcheck.so,需要解决部分依赖库问题:jni_md.h,代码中的../linux/$(ARCH)/lib/jsoncpp/libjsoncpp.a ($(ARCH)=64)和../openssl-dynamic/lib/libcrypto.a文件缺失问题。


解决问题

解决jni_md.h的问题(复制jni_md.h)

$ cd $JAVA_HOME/include$ sudo cp darwin/jni_md.h .

编译jsoncpp

$ brew install scons$ cd tls_sig_api-src/jsoncpp-src-0.5.0$ python /usr/local/bin/scons platform=linux-gcc

执行的结果是在libs目录下生成了
linux-gcc-4.2.1/libjson_linux-gcc-4.2.1_libmt.a
linux-gcc-4.2.1/libjson_linux-gcc-4.2.1_libmt.dylib

编译openssl

// 进入tls_sig_api-src目录$ tar -zxvf openssl-1.0.2a.tar.gz$ mv openssl-1.0.2a openssl_x86_64$ cd openssl_x86_64$ ./Configure darwin64-x86_64-cc -shared$ make

这就在当前目录生成了libcrypto.a

创建软链
进入tls_sig_api-src/src

$ mkdir -p ../linux/64/lib/jsoncpp$ ln -s `cd ..;pwd`/jsoncpp-src-0.5.0/libs/linux-gcc-4.2.1/libjson_linux-gcc-4.2.1_libmt.a ../linux/64/lib/jsoncpp/libjsoncpp.a$ mkdir -p ../openssl-dynamic/lib/$ ln -s `cd ..;pwd`/openssl_x86_64/libcrypto.a ../openssl-dynamic/lib/libcrypto.a

创建link的时候,source需要填写绝对路径,所以才有上述cd ..;pwd。

编译jnisigcheck.so

//在src目录下,执行一下命令,则生成`jnisigcheck.so`$ make clean$ make jni

这时在src目录下就有jnisigcheck.so文件了,
将jnisigcheckLibPath改为”tls_sig_api-src/src/jnisigcheck.so”,
就可以在mac上运行了。

转载:http://www.cnblogs.com/javaDeveloper/p/6098145.html

阅读全文
0 0
原创粉丝点击