ts = new ArrayList<>();
66 | RequestBody body = RequestBody.create(JSON_HEADER, sql);
67 | final Request request = new Request.Builder()
68 | .url(url + "_find").post(body)
69 | .build();
70 | final Call call = okHttpClient.newCall(request);
71 | Response response = null;
72 | try {
73 | response = call.execute();
74 | assert response != null;
75 | JSONObject res = null;
76 | res = JSON.parseObject(response.body().string());
77 | JSONArray t = (JSONArray) res.get("docs");
78 | assert t.size() > 0;
79 | t.forEach(idObject -> {
80 | String id = ((JSONObject) idObject).getString("_id");
81 | // baseDao.delete(id);
82 | if (!StringUtils.isEmpty(id)) {
83 | T t1 = getValueBytes(id);
84 | if (t1 != null) ts.add(t1);
85 | }
86 | });
87 | } catch (Exception e) {
88 | return null;
89 | }
90 | return ts;
91 | }
92 |
93 | public boolean update(T t) throws DaoException {
94 | QueryResult a = baseDao.update(t.getId(), JSON.toJSONString(t));
95 | if (!a.isSuccess()) throw new DaoException(a.getData());
96 | return true;
97 | }
98 |
99 | public void deleteAll() {
100 | query("{\n" +
101 | " \"selector\": {\n" +
102 | " \"_id\": {\n" +
103 | " \"$gt\": \"\"\n" +
104 | " }\n" +
105 | " }\n" +
106 | "}");
107 | }
108 |
109 | public T getValueBytes(String id) {
110 | T t = null;
111 | if (cacheHelper.isKeyAble(CacheHelper.VALUEBYTE + id)) {
112 | t = (T) redisDao.get(CacheHelper.VALUEBYTE + id);
113 | }
114 | if (t == null) {
115 | final Request request = new Request.Builder()
116 | .url(url + id + "/valueBytes").get()
117 | .build();
118 | final Call call = okHttpClient.newCall(request);
119 | Response response = null;
120 | try {
121 | response = call.execute();
122 | String res = response.body().string();
123 | assert res != null;
124 | ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
125 | Type clazz = type.getActualTypeArguments()[0];
126 | t = JSON.parseObject(StringUtil.formatJsonString(res), clazz);
127 | if (t != null) {
128 | redisDao.set(CacheHelper.VALUEBYTE + id, t);
129 | cacheHelper.setKeyAble(CacheHelper.VALUEBYTE + id, true);
130 | }
131 | } catch (Exception e) {
132 | e.printStackTrace();
133 | return null;
134 | }
135 | }
136 | return t;
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/sdk/src/main/java/cn/huse/trace/sdk/trace/FabricManager.java:
--------------------------------------------------------------------------------
1 | package cn.huse.trace.sdk.trace;
2 |
3 | /**
4 | * @author: huanxi
5 | * @date: 2019/3/7 15:37
6 | */
7 |
8 | import cn.huse.trace.sdk.trace.bean.Chaincode;
9 | import cn.huse.trace.sdk.trace.bean.Orderers;
10 | import cn.huse.trace.sdk.trace.bean.Peers;
11 | import org.hyperledger.fabric.sdk.exception.CryptoException;
12 | import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
13 | import org.hyperledger.fabric.sdk.exception.TransactionException;
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 |
17 | import java.io.IOException;
18 | import java.security.NoSuchAlgorithmException;
19 | import java.security.NoSuchProviderException;
20 | import java.security.spec.InvalidKeySpecException;
21 |
22 | public class FabricManager {
23 |
24 | private static final String CHAINCODE_NAME = "funding";
25 | private static final String CHANNEL_NAME = "mychannel";
26 | private final FabricConfig config;
27 | private ChaincodeManager manager;
28 |
29 | private static FabricManager instance = null;
30 | private static Logger log = LoggerFactory.getLogger(FabricManager.class);
31 | private String directory;
32 |
33 | public static FabricManager obtain(FabricConfig config)
34 | throws CryptoException, InvalidArgumentException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, TransactionException, IOException {
35 | if (null == instance) {
36 | synchronized (FabricManager.class) {
37 | if (null == instance) {
38 | instance = new FabricManager(config);
39 | }
40 | }
41 | }
42 | return instance;
43 | }
44 |
45 | public static FabricManager getInstance() {
46 | return instance;
47 | }
48 |
49 | private FabricManager(FabricConfig config)
50 | throws CryptoException, InvalidArgumentException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, TransactionException, IOException {
51 | this.config=config;
52 | manager = new ChaincodeManager("Admin", getConfig());
53 | }
54 |
55 | /**
56 | * 获取节点服务器管理器
57 | *
58 | * @return 节点服务器管理器
59 | */
60 | public ChaincodeManager getManager() {
61 | return manager;
62 | }
63 |
64 | /**
65 | * 根据节点作用类型获取节点服务器配置
66 | *
67 | * 服务器作用类型(1、执行;2、查询)
68 | *
69 | * @return 节点服务器配置
70 | */
71 | private FabricConfig getConfig() {
72 | FabricConfig config = new FabricConfig();
73 | config.setOrderers(getOrderers());
74 | config.setPeers(getPeers());
75 | config.setChaincode(getChaincode(CHANNEL_NAME,CHAINCODE_NAME , "github.com/chaincode/chaincode_example02/go/", "1.0"));
76 | config.setChannelArtifactsPath(getChannleArtifactsPath());
77 | config.setCryptoConfigPath(getCryptoConfigPath());
78 | return config;
79 | }
80 |
81 | private Orderers getOrderers() {
82 | Orderers orderer = new Orderers();
83 | orderer.setOrdererDomainName("example.com");
84 | orderer.addOrderer("orderer.example.com", Location.getOrdererLocation());
85 | return orderer;
86 | }
87 |
88 | /**
89 | * 获取节点服务器集
90 | *
91 | * @return 节点服务器集
92 | */
93 | private Peers getPeers() {
94 | Peers peers = new Peers();
95 | peers.setOrgName("org1");
96 | peers.setOrgMSPID("Org1MSP");
97 | peers.setOrgDomainName("org1.example.com");
98 | peers.addPeer("peer0.org1.example.com", "peer0.org1.example.com", Location.getPeer0Location(), Location.getPeerEventHubLocation(), Location.getCaLocation());
99 | return peers;
100 | }
101 |
102 | /**
103 | * 获取智能合约
104 | *
105 | * @param channelName 频道名称
106 | * @param chaincodeName 智能合约名称
107 | * @param chaincodePath 智能合约路径
108 | * @param chaincodeVersion 智能合约版本
109 | * @return 智能合约
110 | */
111 | private Chaincode getChaincode(String channelName, String chaincodeName, String chaincodePath, String chaincodeVersion) {
112 | Chaincode chaincode = new Chaincode();
113 | chaincode.setChannelName(channelName);
114 | chaincode.setChaincodeName(chaincodeName);
115 | chaincode.setChaincodePath(chaincodePath);
116 | chaincode.setChaincodeVersion(chaincodeVersion);
117 | chaincode.setDeployWaitTime(100000);
118 | chaincode.setTransactionWaitTime(100000);
119 | return chaincode;
120 | }
121 |
122 | /**
123 | * 获取channel-artifacts配置路径
124 | *
125 | * @return /WEB-INF/classes/fabric/channel-artifacts/
126 | */
127 | private String getChannleArtifactsPath() {
128 | return getDirectory() + "/channel-artifacts/";
129 | }
130 |
131 | private String getDirectory() {
132 | return config.getDirectory();
133 | }
134 |
135 | /**
136 | * 获取crypto-config配置路径
137 | *
138 | * @return /WEB-INF/classes/fabric/crypto-config/
139 | */
140 | private String getCryptoConfigPath() {
141 | return getDirectory() + "/crypto-config/";
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/sdk/src/main/java/cn/huse/trace/web/response/model/EnvelopeModel.java:
--------------------------------------------------------------------------------
1 | package cn.huse.trace.web.response.model;
2 |
3 | import cn.huse.trace.sdk.trace.ChaincodeManager;
4 | import com.google.protobuf.InvalidProtocolBufferException;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import org.hyperledger.fabric.protos.ledger.rwset.kvrwset.KvRwset;
7 | import org.hyperledger.fabric.sdk.BlockInfo;
8 | import org.hyperledger.fabric.sdk.TxReadWriteSetInfo;
9 |
10 | import java.io.UnsupportedEncodingException;
11 | import java.util.Date;
12 | import java.util.HashMap;
13 | import java.util.Map;
14 |
15 | /**
16 | * @author: huanxi
17 | * @date: 2019/3/16 0:07
18 | */
19 | public class EnvelopeModel {
20 | @ApiModelProperty("信封类型")
21 | private BlockInfo.EnvelopeType type;
22 | @ApiModelProperty("操作通道")
23 | private String channelId;
24 | @ApiModelProperty("交易ID")
25 | private String TransactionID;
26 | @ApiModelProperty("验证状态码")
27 | private byte ValidationCode;
28 | @ApiModelProperty("时间戳")
29 | private Comparable Timestamp;
30 | @ApiModelProperty("创建者")
31 | private BlockInfo.EnvelopeInfo.IdentitiesInfo Creator;
32 | @ApiModelProperty("随机值")
33 | private byte[] Nonce;
34 | @ApiModelProperty("写操作")
35 | private Map ws = new HashMap<>();
36 |
37 | public EnvelopeModel(BlockInfo.EnvelopeInfo envelopeInfo) {
38 | this.type = envelopeInfo.getType();
39 | this.channelId = envelopeInfo.getChannelId();
40 | this.TransactionID = envelopeInfo.getTransactionID();
41 | this.ValidationCode = envelopeInfo.getValidationCode();
42 | this.Creator = envelopeInfo.getCreator();
43 | this.Timestamp = envelopeInfo.getTimestamp();
44 | this.Nonce = envelopeInfo.getNonce();
45 | if (envelopeInfo.getType() == BlockInfo.EnvelopeType.TRANSACTION_ENVELOPE) { //交易信封
46 | BlockInfo.TransactionEnvelopeInfo txeInfo = (BlockInfo.TransactionEnvelopeInfo) envelopeInfo;
47 | int txCount = txeInfo.getTransactionActionInfoCount();
48 | //遍历所有交易
49 | for (int i = 0; i < txCount; i++) {
50 | BlockInfo.TransactionEnvelopeInfo.TransactionActionInfo txInfo = txeInfo.getTransactionActionInfo(i);
51 | //读写操作
52 | TxReadWriteSetInfo rwsetInfo = txInfo.getTxReadWriteSet();
53 | if (null != rwsetInfo) {
54 | for (TxReadWriteSetInfo.NsRwsetInfo nsRwsetInfo : rwsetInfo.getNsRwsetInfos()) {
55 | final String namespace = nsRwsetInfo.getNamespace();
56 | KvRwset.KVRWSet rws = null;
57 | try {
58 | rws = nsRwsetInfo.getRwset();
59 | } catch (InvalidProtocolBufferException e) {
60 | e.printStackTrace();
61 | }
62 | int rs = -1;
63 | assert rws != null;
64 | for (KvRwset.KVRead readList : rws.getReadsList()) {
65 | rs++;
66 | }
67 | for (KvRwset.KVWrite writeList : rws.getWritesList()) {
68 | try {
69 | ws.put(writeList.getKey(), ChaincodeManager.printableString(new String(writeList.getValue().toByteArray(), "UTF-8")));
70 | } catch (UnsupportedEncodingException e) {
71 | e.printStackTrace();
72 | }
73 | }
74 | }
75 | }
76 |
77 | }
78 | }
79 | }
80 |
81 | public BlockInfo.EnvelopeType getType() {
82 | return type;
83 | }
84 |
85 | public String getChannelId() {
86 | return channelId;
87 | }
88 |
89 | public String getTransactionID() {
90 | return TransactionID;
91 | }
92 |
93 | public byte getValidationCode() {
94 | return ValidationCode;
95 | }
96 |
97 | public Comparable getTimestamp() {
98 | return Timestamp;
99 | }
100 |
101 | public Map getWs() {
102 | return ws;
103 | }
104 |
105 | public void setWs(Map ws) {
106 | this.ws = ws;
107 | }
108 |
109 | public BlockInfo.EnvelopeInfo.IdentitiesInfo getCreator() {
110 | return Creator;
111 | }
112 |
113 | public byte[] getNonce() {
114 | return Nonce;
115 | }
116 |
117 | public EnvelopeModel() {
118 | }
119 |
120 | public void setType(BlockInfo.EnvelopeType type) {
121 | this.type = type;
122 | }
123 |
124 | public void setChannelId(String channelId) {
125 | this.channelId = channelId;
126 | }
127 |
128 | public void setTransactionID(String transactionID) {
129 | TransactionID = transactionID;
130 | }
131 |
132 | public void setValidationCode(byte validationCode) {
133 | ValidationCode = validationCode;
134 | }
135 |
136 | public void setTimestamp(Comparable timestamp) {
137 | Timestamp = timestamp;
138 | }
139 |
140 | public void setCreator(BlockInfo.EnvelopeInfo.IdentitiesInfo creator) {
141 | Creator = creator;
142 | }
143 |
144 | public void setNonce(byte[] nonce) {
145 | Nonce = nonce;
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/sdk/src/main/java/cn/huse/trace/sdk/trace/FabricUser.java:
--------------------------------------------------------------------------------
1 | package cn.huse.trace.sdk.trace;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.IOException;
6 | import java.io.ObjectInputStream;
7 | import java.io.ObjectOutputStream;
8 | import java.io.Serializable;
9 | import java.util.Set;
10 |
11 | import org.bouncycastle.util.encoders.Hex;
12 | import org.hyperledger.fabric.sdk.Enrollment;
13 | import org.hyperledger.fabric.sdk.User;
14 |
15 | import io.netty.util.internal.StringUtil;
16 |
17 | /**
18 | * 联盟用户对象
19 | *
20 | * @author 杨毅
21 | *
22 | * @date 2017年9月7日 - 下午4:36:53
23 | * @email abericyang@gmail.com
24 | */
25 | public class FabricUser implements User, Serializable {
26 |
27 | private static final long serialVersionUID = 5695080465408336815L;
28 |
29 | /** 名称 */
30 | private String name;
31 | /** 规则 */
32 | private Set roles;
33 | /** 账户 */
34 | private String account;
35 | /** 从属联盟 */
36 | private String affiliation;
37 | /** 组织 */
38 | private String organization;
39 | /** 注册操作的密�? */
40 | private String enrollmentSecret;
41 | /** 会员id */
42 | private String mspId;
43 | /** 注册登记操作 */
44 | Enrollment enrollment = null;
45 |
46 | /** 存储配置对象 */
47 | private transient FabricStore keyValStore;
48 | private String keyValStoreName;
49 |
50 | public FabricUser(String name, String org, FabricStore store) {
51 | this.name = name;
52 | this.keyValStore = store;
53 | this.organization = org;
54 | this.keyValStoreName = toKeyValStoreName(this.name, org);
55 |
56 | String memberStr = keyValStore.getValue(keyValStoreName);
57 | if (null != memberStr) {
58 | saveState();
59 | } else {
60 | restoreState();
61 | }
62 | }
63 |
64 | /**
65 | * 设置账户信息并将用户状�?�更新至存储配置对象
66 | *
67 | * @param account
68 | * 账户
69 | */
70 | public void setAccount(String account) {
71 | this.account = account;
72 | saveState();
73 | }
74 |
75 | @Override
76 | public String getAccount() {
77 | return this.account;
78 | }
79 |
80 | /**
81 | * 设置从属联盟信息并将用户状�?�更新至存储配置对象
82 | *
83 | * @param affiliation
84 | * 从属联盟
85 | */
86 | public void setAffiliation(String affiliation) {
87 | this.affiliation = affiliation;
88 | saveState();
89 | }
90 |
91 | @Override
92 | public String getAffiliation() {
93 | return this.affiliation;
94 | }
95 |
96 | @Override
97 | public Enrollment getEnrollment() {
98 | return this.enrollment;
99 | }
100 |
101 | /**
102 | * 设置会员id信息并将用户状�?�更新至存储配置对象
103 | *
104 | * @param mspID
105 | * 会员id
106 | */
107 | public void setMspId(String mspID) {
108 | this.mspId = mspID;
109 | saveState();
110 | }
111 |
112 | @Override
113 | public String getMspId() {
114 | return this.mspId;
115 | }
116 |
117 | @Override
118 | public String getName() {
119 | return this.name;
120 | }
121 |
122 | /**
123 | * 设置规则信息并将用户状�?�更新至存储配置对象
124 | *
125 | * @param roles
126 | * 规则
127 | */
128 | public void setRoles(Set roles) {
129 | this.roles = roles;
130 | saveState();
131 | }
132 |
133 | @Override
134 | public Set getRoles() {
135 | return this.roles;
136 | }
137 |
138 | public String getEnrollmentSecret() {
139 | return enrollmentSecret;
140 | }
141 |
142 | /**
143 | * 设置注册操作的密钥信息并将用户状态更新至存储配置对象
144 | *
145 | * @param enrollmentSecret
146 | * 注册操作的密�?
147 | */
148 | public void setEnrollmentSecret(String enrollmentSecret) {
149 | this.enrollmentSecret = enrollmentSecret;
150 | saveState();
151 | }
152 |
153 | /**
154 | * 设置注册登记操作信息并将用户状�?�更新至存储配置对象
155 | *
156 | * @param enrollment
157 | * 注册登记操作
158 | */
159 | public void setEnrollment(Enrollment enrollment) {
160 | this.enrollment = enrollment;
161 | saveState();
162 | }
163 |
164 | /**
165 | * 确定这个名称是否已注�?
166 | *
167 | * @return 与否
168 | */
169 | public boolean isRegistered() {
170 | return !StringUtil.isNullOrEmpty(enrollmentSecret);
171 | }
172 |
173 | /**
174 | * 确定这个名字是否已经注册
175 | *
176 | * @return 与否
177 | */
178 | public boolean isEnrolled() {
179 | return this.enrollment != null;
180 | }
181 |
182 | /** 将用户状态保存至存储配置对象 */
183 | public void saveState() {
184 | ByteArrayOutputStream bos = new ByteArrayOutputStream();
185 | try {
186 | ObjectOutputStream oos = new ObjectOutputStream(bos);
187 | oos.writeObject(this);
188 | oos.flush();
189 | keyValStore.setValue(keyValStoreName, Hex.toHexString(bos.toByteArray()));
190 | bos.close();
191 | } catch (IOException e) {
192 | e.printStackTrace();
193 | }
194 | }
195 |
196 | /**
197 | * 从键值存储中恢复该用户的状�??(如果找到的话)。如果找不到,什么也不要做�??
198 | *
199 | * @return 返回用户
200 | */
201 | private FabricUser restoreState() {
202 | String memberStr = keyValStore.getValue(keyValStoreName);
203 | if (null != memberStr) {
204 | // 用户在键值存储中被找到,因此恢复状�?��??
205 | byte[] serialized = Hex.decode(memberStr);
206 | ByteArrayInputStream bis = new ByteArrayInputStream(serialized);
207 | try {
208 | ObjectInputStream ois = new ObjectInputStream(bis);
209 | FabricUser state = (FabricUser) ois.readObject();
210 | if (state != null) {
211 | this.name = state.name;
212 | this.roles = state.roles;
213 | this.account = state.account;
214 | this.affiliation = state.affiliation;
215 | this.organization = state.organization;
216 | this.enrollmentSecret = state.enrollmentSecret;
217 | this.enrollment = state.enrollment;
218 | this.mspId = state.mspId;
219 | return this;
220 | }
221 | } catch (Exception e) {
222 | throw new RuntimeException(String.format("Could not restore state of member %s", this.name), e);
223 | }
224 | }
225 | return null;
226 | }
227 |
228 | public static String toKeyValStoreName(String name, String org) {
229 | System.out.println("toKeyValStoreName = " + "user." + name + org);
230 | return "user." + name + org;
231 | }
232 |
233 | }
234 |
--------------------------------------------------------------------------------
/sdk/src/main/java/cn/huse/trace/sdk/util/DateUtil.java:
--------------------------------------------------------------------------------
1 | package cn.huse.trace.sdk.util;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 | import java.util.Locale;
8 |
9 | /**
10 | * 一般日期(时间)处理通用公共方法类
11 | *
12 | * @author 杨毅
13 | *
14 | * @date 2017年10月19日 - 下午5:33:00
15 | * @email abericyang@gmail.com
16 | */
17 | public class DateUtil {
18 |
19 | private static DateUtil instance;
20 |
21 | public static DateUtil obtain() {
22 | if (null == instance) {
23 | synchronized (DateUtil.class) {
24 | if (null == instance) {
25 | instance = new DateUtil();
26 | }
27 | }
28 | }
29 | return instance;
30 | }
31 |
32 | private DateUtil() {
33 | }
34 |
35 | // 使用DateFormat
36 |
37 | /**
38 | * 获取当前时间
39 | *
40 | * @param format
41 | * (yyyy年MM月dd日 HH时mm分ss秒|yyyy年MM月dd日
42 | * HH时mm分ss秒|yyyyMMddHHmmss|HH:mm:ss|yyyy年MM月dd日 等)
43 | *
44 | * @return 当前时间格式
45 | */
46 | public String getCurrentDate(String format) {
47 | SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA);
48 | return sdf.format(new Date());
49 | }
50 |
51 | /**
52 | * 将字符串转换为日期
53 | *
54 | * @param dateStr
55 | * 实际日期字符串
56 | * @param format
57 | * 指定日期字符串格式
58 | *
59 | * @return date
60 | */
61 | public Date parseStringToDate(String dateStr, String format) throws Exception {
62 | SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA);
63 | return sdf.parse(dateStr);
64 | }
65 |
66 | /**
67 | * 将日期转换为字符串
68 | *
69 | * @param date
70 | * date日期
71 | * @param format
72 | * 日期格式
73 | *
74 | * @return 日期字符串
75 | */
76 | public String parseDateFormat(Date date, String format) {
77 | try {
78 | SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA);
79 | return sdf.format(date);
80 | } catch (Exception ex) {
81 | return "";
82 | }
83 | }
84 |
85 | /**
86 | * 获得指定日期的前一天
87 | *
88 | * @param specifiedDay
89 | * 指定日期
90 | *
91 | * @return 指定日期的前一天
92 | */
93 | public String getSpecifiedDayBefore(String specifiedDay) {
94 | Calendar c = Calendar.getInstance();
95 | Date date = null;
96 | try {
97 | date = new SimpleDateFormat("yy-MM-dd", Locale.CHINA).parse(specifiedDay);
98 | } catch (ParseException e) {
99 | e.printStackTrace();
100 | }
101 | c.setTime(date);
102 | int day = c.get(Calendar.DATE);
103 | c.set(Calendar.DATE, day - 1);
104 |
105 | return new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA).format(c.getTime());
106 | }
107 |
108 | /**
109 | * 返回日期中的指定部分--YYYY 年份,MM 月份,DD 天,HH 小时 MI 分 SS 秒
110 | *
111 | * @param date
112 | * date日期
113 | * @param type
114 | * 日期中的指定部分
115 | *
116 | * @return 日期中的指定部分值
117 | */
118 | public int getDatePart(Date date, DatePartType type) {
119 | Calendar cal = Calendar.getInstance();
120 | cal.setTime(date);
121 | switch (type) {
122 | case Year:
123 | return cal.get(Calendar.YEAR);
124 | case Month:
125 | return cal.get(Calendar.MONTH);
126 | case Day:
127 | return cal.get(Calendar.DAY_OF_MONTH);
128 | case Hour:
129 | return cal.get(Calendar.HOUR_OF_DAY);
130 | case Minute:
131 | return cal.get(Calendar.MINUTE);
132 | case Second:
133 | return cal.get(Calendar.SECOND);
134 | default:
135 | return 0;
136 | }
137 | }
138 |
139 | public enum DatePartType {
140 | Year, Month, Day, Hour, Minute, Second
141 | }
142 |
143 | /**
144 | * 计算两个日期之间的时间差 传入的对象为两个日期,字符串和时间对象即可
145 | *
146 | * @param dateFrom
147 | * 起始日期/字符串/时间对象
148 | * @param dateTo
149 | * 截止日期/字符串/时间对象
150 | *
151 | * @return 时间差
152 | *
153 | * @throws Exception
154 | */
155 | public String dateDiff(Object dateFrom, Object dateTo) throws Exception {
156 | Date date1 = getDateByObject(dateFrom);
157 | Date date2 = getDateByObject(dateTo);
158 | Calendar cal1 = Calendar.getInstance();
159 | Calendar cal2 = Calendar.getInstance();
160 | cal1.setTime(date2);
161 | cal2.setTime(date1);
162 | float a = ((float) (cal1.getTimeInMillis() - cal2.getTimeInMillis()) / 86400) / 1000;
163 | int b = (int) a;
164 | return "" + Math.abs(((b == a) ? b : b + 1));
165 | }
166 |
167 | /**
168 | * 根据传入参数产生日期对象
169 | *
170 | * @param obj
171 | * 传入参数
172 | *
173 | * @return Date
174 | *
175 | * @throws Exception
176 | */
177 | public Date getDateByObject(Object obj) throws Exception {
178 | if (null == obj) {
179 | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).parse(getCurrentDate(null));
180 | }
181 |
182 | if (obj instanceof Date) {
183 | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).parse(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(obj));
184 | }
185 | if (obj instanceof String) {
186 | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).parse((String) obj);
187 | }
188 | return null;
189 | }
190 |
191 | /**
192 | * 获取当前年/月/日
193 | *
194 | * @return yyyy/MM/dd
195 | */
196 | public String getNowDateFor(String dateFro) {
197 | SimpleDateFormat sdf = new SimpleDateFormat(dateFro, Locale.CHINA);
198 | return sdf.format(new Date());
199 | }
200 |
201 | /**
202 | * 功能描述:返回小时
203 | *
204 | * @param date
205 | * 日期
206 | *
207 | * @return 返回小时
208 | */
209 | public int getHour(Date date) {
210 | Calendar calendar = Calendar.getInstance();
211 | calendar.setTime(date);
212 | return calendar.get(Calendar.HOUR_OF_DAY);
213 | }
214 |
215 | /**
216 | * 功能描述:将字符串转换为long型
217 | *
218 | * @param string
219 | * 日期
220 | * @param pattern
221 | * 日期格式
222 | *
223 | * @return 返回long型时间
224 | */
225 | public long parseDate(String string, String pattern) {
226 | SimpleDateFormat timeLine = new SimpleDateFormat(pattern, Locale.CHINA);
227 | long l = 0;
228 | try {
229 | l = timeLine.parse(string).getTime();
230 | return l;
231 | } catch (ParseException e) {
232 | System.out.print("parseDate 时间解析错误");
233 | }
234 | return l;
235 | }
236 | }
237 |
--------------------------------------------------------------------------------
/sdk/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM set title of command window
39 | title %0
40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42 |
43 | @REM set %HOME% to equivalent of $HOME
44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45 |
46 | @REM Execute a user defined script before this one
47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
51 | :skipRcPre
52 |
53 | @setlocal
54 |
55 | set ERROR_CODE=0
56 |
57 | @REM To isolate internal variables from possible post scripts, we use another setlocal
58 | @setlocal
59 |
60 | @REM ==== START VALIDATION ====
61 | if not "%JAVA_HOME%" == "" goto OkJHome
62 |
63 | echo.
64 | echo Error: JAVA_HOME not found in your environment. >&2
65 | echo Please set the JAVA_HOME variable in your environment to match the >&2
66 | echo location of your Java installation. >&2
67 | echo.
68 | goto error
69 |
70 | :OkJHome
71 | if exist "%JAVA_HOME%\bin\java.exe" goto init
72 |
73 | echo.
74 | echo Error: JAVA_HOME is set to an invalid directory. >&2
75 | echo JAVA_HOME = "%JAVA_HOME%" >&2
76 | echo Please set the JAVA_HOME variable in your environment to match the >&2
77 | echo location of your Java installation. >&2
78 | echo.
79 | goto error
80 |
81 | @REM ==== END VALIDATION ====
82 |
83 | :init
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122 |
123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
126 | )
127 |
128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
130 | if exist %WRAPPER_JAR% (
131 | echo Found %WRAPPER_JAR%
132 | ) else (
133 | echo Couldn't find %WRAPPER_JAR%, downloading it ...
134 | echo Downloading from: %DOWNLOAD_URL%
135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
136 | echo Finished downloading %WRAPPER_JAR%
137 | )
138 | @REM End of extension
139 |
140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
141 | if ERRORLEVEL 1 goto error
142 | goto end
143 |
144 | :error
145 | set ERROR_CODE=1
146 |
147 | :end
148 | @endlocal & set ERROR_CODE=%ERROR_CODE%
149 |
150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
154 | :skipRcPost
155 |
156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
158 |
159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
160 |
161 | exit /B %ERROR_CODE%
162 |
--------------------------------------------------------------------------------
/sdk/src/main/java/cn/huse/trace/web/controller/home/UserController.java:
--------------------------------------------------------------------------------
1 | package cn.huse.trace.web.controller.home;
2 |
3 | import cn.huse.trace.web.common.ReturnMessageMap;
4 | import cn.huse.trace.web.common.Utils;
5 | import cn.huse.trace.web.common.auth.jwt.JwtUserTokenUtil;
6 | import cn.huse.trace.web.config.parsetoken.ParseToken;
7 | import cn.huse.trace.web.dao.DaoException;
8 | import cn.huse.trace.web.entity.Transaction;
9 | import cn.huse.trace.web.entity.User;
10 | import cn.huse.trace.web.service.ProjectService;
11 | import cn.huse.trace.web.service.TransactionService;
12 | import cn.huse.trace.web.service.UserService;
13 | import io.swagger.annotations.Api;
14 | import io.swagger.annotations.ApiOperation;
15 | import io.swagger.annotations.ApiParam;
16 | import org.springframework.beans.factory.annotation.Value;
17 | import org.springframework.validation.annotation.Validated;
18 | import org.springframework.web.bind.annotation.*;
19 | import org.springframework.web.multipart.MultipartFile;
20 |
21 | import javax.annotation.Resource;
22 | import java.io.File;
23 |
24 | /**
25 | * @author: huanxi
26 | * @date: 2019/4/27 22:25
27 | */
28 | @RestController
29 | @RequestMapping("/user")
30 | @Api(value = "用户接口", description = "用户接口")
31 | public class UserController {
32 | @Resource
33 | UserService userService;
34 | @Resource
35 | ProjectService projectService;
36 | @Resource
37 | TransactionService transactionService;
38 | @Value("${upload.path}")
39 | String uploadPath;
40 |
41 | @PostMapping("")
42 | @ApiOperation("用户注册")
43 | public ReturnMessageMap addUser(@Validated User user) {
44 | try {
45 | userService.addUser(user);
46 | } catch (DaoException e) {
47 | return new ReturnMessageMap(e.getMessage());
48 | }
49 | return new ReturnMessageMap("register successfully");
50 | }
51 |
52 | @PostMapping("/token")
53 | @ApiOperation("用户登入获取token")
54 | public ReturnMessageMap addToken(@Validated User user) {
55 | User user1 = userService.getUser(user.getAccount());
56 | if (user1 == null) return new ReturnMessageMap(4010, "not exist this user");
57 | if (user1.getPassword().equals(Utils.passwd(user.getPassword()))) {
58 | String token = JwtUserTokenUtil.generateToken(user1);
59 | return new ReturnMessageMap(token);
60 | }
61 | return new ReturnMessageMap(4011, "username or password error");
62 | }
63 |
64 | @GetMapping("/info")
65 | @ApiOperation("获取用户信息")
66 | public ReturnMessageMap getUserInfo(@ParseToken String userId) {
67 | return new ReturnMessageMap(userService.getUser(userId));
68 | }
69 |
70 | @PutMapping("/info")
71 | @ApiOperation("修改用户信息")
72 | public ReturnMessageMap updateUserInfo(User user, @ParseToken String userId) throws DaoException {
73 | user.setAccount(userId);
74 | userService.update(user);
75 | return new ReturnMessageMap("update successfully!");
76 | }
77 |
78 |
79 | @PostMapping("/header")
80 | @ApiOperation("修改用户头像")
81 | public ReturnMessageMap updateUserHeader(@ParseToken String userId, MultipartFile image) throws DaoException {
82 | File file;
83 | try {
84 | file = Utils.saveFile(image, uploadPath);
85 | } catch (Exception e) {
86 | return new ReturnMessageMap(5013, e.getMessage());
87 | }
88 | if (file == null) return new ReturnMessageMap("upload file failed!");
89 | User user = userService.getUser(userId);
90 | if (user != null) {
91 | user.setHeaderUrl(file.getName());
92 | userService.update(user);
93 | }
94 | return new ReturnMessageMap(user);
95 | }
96 |
97 | @GetMapping("projects")
98 | @ApiOperation("查看我发布的项目")
99 | public ReturnMessageMap getMyProjects(@ParseToken String userId) {
100 | return new ReturnMessageMap(projectService.queryByUserId(userId));
101 | }
102 |
103 | @PostMapping("charge")
104 | @ApiOperation("模拟充值")
105 | public ReturnMessageMap charge(@ParseToken String userId, @ApiParam("充值金额") float amount) {
106 | if (amount <= 0) return new ReturnMessageMap(4011, "amount must be gt 0");
107 | Transaction transaction = new Transaction();
108 | transaction.setAmount(amount);
109 | transaction.setInId("bank");
110 | transaction.setOutId(userId);
111 | try {
112 | transactionService.addTransaction(transaction);
113 | } catch (DaoException e) {
114 | return new ReturnMessageMap(5021, e.getMessage());
115 | }
116 | return new ReturnMessageMap("ok");
117 | }
118 |
119 | @PostMapping("withdraw")
120 | @ApiOperation("模拟提现")
121 | public ReturnMessageMap withdraw(@ParseToken String userId, @ApiParam("充值金额") float amount) {
122 | Transaction transaction = new Transaction();
123 | transaction.setAmount(amount);
124 | transaction.setInId(userId);
125 | transaction.setOutId("bank");
126 | try {
127 | transactionService.addTransaction(transaction);
128 | } catch (DaoException e) {
129 | return new ReturnMessageMap(5021, e.getMessage());
130 | }
131 | return new ReturnMessageMap("ok");
132 | }
133 |
134 | @PostMapping("transfer")
135 | @ApiOperation("模拟投资众筹")
136 | public ReturnMessageMap transfer(@ParseToken String userId, @ApiParam("转账金额") float amount, @ApiParam("众筹项目") String project) {
137 | return new ReturnMessageMap(projectService.queryByUserId(userId));
138 | }
139 |
140 | @GetMapping("balance")
141 | @ApiOperation("查询余额")
142 | public ReturnMessageMap getBalance(@ParseToken String userId) {
143 | return new ReturnMessageMap(transactionService.getBalance(userId));
144 | }
145 |
146 | @GetMapping("transaction")
147 | @ApiOperation("获取我的所有交易")
148 | public ReturnMessageMap getTransaction(@ParseToken String userId) {
149 | return new ReturnMessageMap(transactionService.getTransactionByUserId(userId));
150 | }
151 |
152 | @GetMapping("transaction/in")
153 | @ApiOperation("获取转给我的所有交易")
154 | public ReturnMessageMap getTransactionIn(@ParseToken String userId) {
155 | return new ReturnMessageMap(transactionService.getTransactionInByUserId(userId));
156 | }
157 |
158 | @GetMapping("transaction/out")
159 | @ApiOperation("获取我转出的所有交易")
160 | public ReturnMessageMap getTransactionOut(@ParseToken String userId) {
161 | return new ReturnMessageMap(transactionService.getTransactionOutByUserId(userId));
162 | }
163 |
164 | }
165 |
--------------------------------------------------------------------------------
/sdk/src/main/java/cn/huse/trace/sdk/trace/FabricStore.java:
--------------------------------------------------------------------------------
1 | package cn.huse.trace.sdk.trace;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileOutputStream;
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 | import java.io.OutputStream;
10 | import java.io.Reader;
11 | import java.io.Serializable;
12 | import java.io.StringReader;
13 | import java.security.NoSuchAlgorithmException;
14 | import java.security.NoSuchProviderException;
15 | import java.security.PrivateKey;
16 | import java.security.Security;
17 | import java.security.spec.InvalidKeySpecException;
18 | import java.util.HashMap;
19 | import java.util.Map;
20 | import java.util.Properties;
21 |
22 | import org.apache.commons.io.IOUtils;
23 | import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
24 | import org.bouncycastle.jce.provider.BouncyCastleProvider;
25 | import org.bouncycastle.openssl.PEMParser;
26 | import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
27 | import org.hyperledger.fabric.sdk.Enrollment;
28 |
29 | /**
30 | * 联盟存储配置对象
31 | *
32 | * @author 杨毅
33 | *
34 | * @date 2017年9月7日 - 下午4:36:19
35 | * @email abericyang@gmail.com
36 | */
37 | public class FabricStore {
38 |
39 | private String file;
40 | /** 用户信息集合 */
41 | private final Map members = new HashMap<>();
42 |
43 | public FabricStore(File file) {
44 | this.file = file.getAbsolutePath();
45 | }
46 |
47 | /**
48 | * 设置与名称相关的值
49 | *
50 | * @param name
51 | * 名称
52 | * @param value
53 | * 相关值
54 | */
55 | public void setValue(String name, String value) {
56 | Properties properties = loadProperties();
57 | try (OutputStream output = new FileOutputStream(file)) {
58 | properties.setProperty(name, value);
59 | properties.store(output, "");
60 | output.close();
61 | } catch (IOException e) {
62 | System.out.println(String.format("Could not save the keyvalue store, reason:%s", e.getMessage()));
63 | }
64 | }
65 |
66 | /**
67 | * 获取与名称相关的值
68 | *
69 | * @param 名称
70 | * @return 相关值
71 | */
72 | public String getValue(String name) {
73 | Properties properties = loadProperties();
74 | return properties.getProperty(name);
75 | }
76 |
77 | /**
78 | * 加载配置文件
79 | *
80 | * @return 配置文件对象
81 | */
82 | private Properties loadProperties() {
83 | Properties properties = new Properties();
84 | try (InputStream input = new FileInputStream(file)) {
85 | properties.load(input);
86 | input.close();
87 | } catch (FileNotFoundException e) {
88 | System.out.println(String.format("Could not find the file \"%s\"", file));
89 | } catch (IOException e) {
90 | System.out.println(String.format("Could not load keyvalue store from file \"%s\", reason:%s", file, e.getMessage()));
91 | }
92 | return properties;
93 | }
94 |
95 | /**
96 | * 用给定的名称获取用户
97 | *
98 | * @param 名称
99 | * @param 组织
100 | *
101 | * @return 用户
102 | */
103 | public FabricUser getMember(String name, String org) {
104 | // 尝试从缓存中获取User状�??
105 | FabricUser fabricUser = members.get(FabricUser.toKeyValStoreName(name, org));
106 | if (null != fabricUser) {
107 | return fabricUser;
108 | }
109 | // 创建User,并尝试从键值存储中恢复它的状�??(如果找到的话)�?
110 | fabricUser = new FabricUser(name, org, this);
111 | return fabricUser;
112 | }
113 |
114 | /**
115 | * 用给定的名称获取用户
116 | *
117 | * @param name
118 | * 名称
119 | * @param org
120 | * 组织
121 | * @param mspId
122 | * 会员id
123 | * @param privateKeyFile
124 | * @param certificateFile
125 | *
126 | * @return user 用户
127 | *
128 | * @throws IOException
129 | * @throws NoSuchAlgorithmException
130 | * @throws NoSuchProviderException
131 | * @throws InvalidKeySpecException
132 | */
133 | public FabricUser getMember(String name, String org, String mspId, File privateKeyFile, File certificateFile)
134 | throws IOException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {
135 | try {
136 | // 尝试从缓存中获取User状�??
137 | FabricUser fabricUser = members.get(FabricUser.toKeyValStoreName(name, org));
138 | if (null != fabricUser) {
139 | System.out.println("尝试从缓存中获取User状�?? User = " + fabricUser);
140 | return fabricUser;
141 | }
142 | // 创建User,并尝试从键值存储中恢复它的状�??(如果找到的话)�?
143 | fabricUser = new FabricUser(name, org, this);
144 | fabricUser.setMspId(mspId);
145 | String certificate = new String(IOUtils.toByteArray(new FileInputStream(certificateFile)), "UTF-8");
146 | PrivateKey privateKey = getPrivateKeyFromBytes(IOUtils.toByteArray(new FileInputStream(privateKeyFile)));
147 | fabricUser.setEnrollment(new StoreEnrollement(privateKey, certificate));
148 | fabricUser.saveState();
149 | return fabricUser;
150 | } catch (IOException e) {
151 | e.printStackTrace();
152 | throw e;
153 | } catch (NoSuchAlgorithmException e) {
154 | e.printStackTrace();
155 | throw e;
156 | } catch (NoSuchProviderException e) {
157 | e.printStackTrace();
158 | throw e;
159 | } catch (InvalidKeySpecException e) {
160 | e.printStackTrace();
161 | throw e;
162 | } catch (ClassCastException e) {
163 | e.printStackTrace();
164 | throw e;
165 | }
166 | }
167 |
168 | /**
169 | * 通过字节数组信息获取私钥
170 | *
171 | * @param data
172 | * 字节数组
173 | *
174 | * @return 私钥
175 | *
176 | * @throws IOException
177 | * @throws NoSuchProviderException
178 | * @throws NoSuchAlgorithmException
179 | * @throws InvalidKeySpecException
180 | */
181 | private PrivateKey getPrivateKeyFromBytes(byte[] data) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {
182 | final Reader pemReader = new StringReader(new String(data));
183 | final PrivateKeyInfo pemPair;
184 | try (PEMParser pemParser = new PEMParser(pemReader)) {
185 | pemPair = (PrivateKeyInfo) pemParser.readObject();
186 | }
187 | PrivateKey privateKey = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getPrivateKey(pemPair);
188 | return privateKey;
189 | }
190 |
191 | static {
192 | try {
193 | Security.addProvider(new BouncyCastleProvider());
194 | } catch (Exception e) {
195 | e.printStackTrace();
196 | }
197 | }
198 |
199 | /**
200 | * 自定义注册登记操作类
201 | *
202 | * @author yangyi47
203 | *
204 | */
205 | static final class StoreEnrollement implements Enrollment, Serializable {
206 |
207 | private static final long serialVersionUID = 6965341351799577442L;
208 |
209 | /** 私钥 */
210 | private final PrivateKey privateKey;
211 | /** 授权证书 */
212 | private final String certificate;
213 |
214 | StoreEnrollement(PrivateKey privateKey, String certificate) {
215 | this.certificate = certificate;
216 | this.privateKey = privateKey;
217 | }
218 |
219 | @Override
220 | public PrivateKey getKey() {
221 | return privateKey;
222 | }
223 |
224 | @Override
225 | public String getCert() {
226 | return certificate;
227 | }
228 | }
229 |
230 | }
231 |
--------------------------------------------------------------------------------
/sdk/src/main/java/cn/huse/trace/web/cache/RedisDao.java:
--------------------------------------------------------------------------------
1 | package cn.huse.trace.web.cache;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.data.redis.core.RedisTemplate;
5 | import org.springframework.stereotype.Component;
6 |
7 | import javax.annotation.Resource;
8 | import java.util.List;
9 | import java.util.Map;
10 | import java.util.concurrent.TimeUnit;
11 |
12 | /**
13 | * @author: huanxi
14 | * @date: 2019-04-19 21:25
15 | */
16 | @Component
17 | @Slf4j
18 | public final class RedisDao {
19 | @Resource
20 | private RedisTemplate redisTemplate;
21 |
22 | /**
23 | * 获取普通缓存
24 | *
25 | * @param key
26 | * @return
27 | */
28 | public Object get(String key) {
29 | return key == null ? null : redisTemplate.opsForValue().get(key);
30 | }
31 |
32 |
33 | /**
34 | * 设置普通缓存
35 | *
36 | * @param key
37 | * @return
38 | */
39 | public boolean set(String key, Object value) {
40 | try {
41 | redisTemplate.opsForValue().set(key, value);
42 | return true;
43 | } catch (Exception e) {
44 | e.printStackTrace();
45 | return false;
46 | }
47 | }
48 |
49 | /**
50 | * 指定缓存失效时间
51 | *
52 | * @param key 键
53 | * @param time 时间(秒)
54 | */
55 | public boolean expire(String key, long time) {
56 | try {
57 | if (time > 0) {
58 | redisTemplate.expire(key, time, TimeUnit.SECONDS);
59 | }
60 | return true;
61 | } catch (Exception e) {
62 | e.printStackTrace();
63 | return false;
64 | }
65 | }
66 |
67 | /**
68 | * 根据key 获取过期时间
69 | *
70 | * @param key 键 不能为null
71 | * @return 时间(秒) 返回0代表为永久有效
72 | */
73 | public long getExpire(String key) {
74 | return redisTemplate.getExpire(key, TimeUnit.SECONDS);
75 | }
76 |
77 | /**
78 | * 向一张hash表中放入数据,如果不存在将创建
79 | *
80 | * @param key 键
81 | * @param item 项
82 | * @param value 值
83 | * @return true 成功 false失败
84 | */
85 | public boolean hset(String key, String item, Object value) {
86 | try {
87 | redisTemplate.opsForHash().put(key, item, value);
88 | return true;
89 | } catch (Exception e) {
90 | log.error("写redis缓存失败" + e.getMessage());
91 | return false;
92 | }
93 | }
94 |
95 | /**
96 | * 向一张hash表中放入数据,如果不存在将创建
97 | *
98 | * @param key 键
99 | * @param item 项
100 | * @param value 值
101 | * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
102 | * @return true 成功 false失败
103 | */
104 | public boolean hset(String key, String item, Object value, long time) {
105 | try {
106 | redisTemplate.opsForHash().put(key, item, value);
107 | if (time > 0) {
108 | expire(key, time);
109 | }
110 | return true;
111 | } catch (Exception e) {
112 | e.printStackTrace();
113 | return false;
114 | }
115 | }
116 |
117 | /**
118 | * 删除hash表中的值
119 | *
120 | * @param key 键 不能为null
121 | * @param item 项 可以使多个 不能为null
122 | */
123 | public void hdel(String key, Object... item) {
124 | redisTemplate.opsForHash().delete(key, item);
125 | }
126 |
127 | /**
128 | * HashGet
129 | *
130 | * @param key 键 不能为null
131 | * @param item 项 不能为null
132 | * @return 值
133 | */
134 | public Object hget(String key, String item) {
135 | return redisTemplate.opsForHash().get(key, item);
136 | }
137 |
138 | /**
139 | * 获取hashKey对应的所有键值
140 | *
141 | * @param key 键
142 | * @return 对应的多个键值
143 | */
144 | public Map