昨天感悟了一下人生,今天回归正轨,想记录一下自己进入实验室做项目时写的第一个接口。
当我接手这个项目的时候这个项目已经接近尾声,但还是有一些小功能需要完善一下,原定由师兄完成项目的区块链模块因某些原因无法继续,于是我们只能使用别人的区块链接口,这其中就需要用到一种类似“请求转发”的接口,而我当时仅仅是一个只会crud的菜鸟,所以这个功能对当时的我来说是个不小的挑战。
话不多说,让我回到当时的记忆.....
具体的实现功能大致如下:①数据上传至区块链:首先自己划分好不同权限所展示的数据(管理者数据和普通用户数据),我将其称为“pubdata”和“pridata”。区分好之后,调用提供的区块链接口信息,通过获取区块链信息来判断信息是否上链成功。②数据校验:将“pubdata”以及“pridata”分别存储到系统数据库中,调用此接口,我们可以查询区块链上相应的信息,再将其与数据库上的数据进行比对,如有差异,则证明数据被篡改,反之数据安全。
@ApiOperation(value = "上传至区块链")
@PostMapping("/uploadToChain")
@RequiresRoles(logical = Logical.OR, value = {"admin"})
public Result uploadToChain(@ApiParam("id") @RequestParam("id") Long id) throws IOException {
FishSourceAttribution fishSourceAttribution = fishSourceAttributionService.getById(id);
fishSourceAttribution.setStatus(0);
String pubData = "节点名称:peer0.org1.example.com|上链时间:" + fishSourceAttribution.getGmtCreate() + "|鱼名称:" + fishSourceAttribution.getFishName();
String priData = "鱼名称:" + fishSourceAttribution.getFishName() + "|种质所属名称:" + fishSourceAttribution.getSubjectName() + "|鱼类型:" + fishSourceAttribution.getFishSourceClass() + "|亲鱼来源:" + fishSourceAttribution.getParentSource() +
"|归属人:" + fishSourceAttribution.getBelongManName() + "|归属主题:" + fishSourceAttribution.getUserClass() + "|种质所属主体类别:" + fishSourceAttribution.getSubject()+"|归属地:"+fishSourceAttribution.getProvince()+fishSourceAttribution.getCity()+fishSourceAttribution.getCounty()+fishSourceAttribution.getAddress();
boolean success = false;
boolean save=false;
Integer height=0;
String token = "token";
String charset = HTTP.UTF_8;
HashMap<String,Object> p = new HashMap<>();
LinkedList linkedList1 = new LinkedList();
linkedList1.add("peer0.org1.example.com");
LinkedList linkedList2 = new LinkedList();
linkedList2.add(Long.toString(fishSourceAttribution.getSourceId()));
linkedList2.add(pubData);
linkedList2.add(priData);
linkedList2.add("qhgjisekoritdkcm");
p.put("fcn", "traceTrans");
p.put("peers", linkedList1);
p.put("args", linkedList2);
现在回头看一下当时的代码,可谓是一言难尽,pubdata以及pridata使用了经典操作,无限拼接,然后为获取调用接口所得到的结果,new了很多变量,再之后就是一堆的集合的添加操作。代码格外辣鸡,但是,能用就刑 :smile:
变量值都赋好了,然后就是调接口的流程了,具体的示例如下所示
其实乍一看,感觉没什么难度(不就是把相关的接口地址和一些必要参数弄进请求头一起发送嘛),上手之后,我就不再嘴硬了呵呵
try {
String params = JSONObject.toJSONString(p);
String url = "http://xxxx:4000/channels/channelproduce/chaincodes/syTrace";
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);// 创建httpPost
httpPost.setHeader("Accept", "text/plain");
httpPost.setHeader("Content-Type", "application/json");
httpPost.setHeader("Authorization", "Bearer " + token);
String charSet = "UTF-8";
StringEntity entity = new StringEntity(params, charSet);
httpPost.setEntity(entity);
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpPost);
StatusLine status = response.getStatusLine();
int state = status.getStatusCode();
if (state == HttpStatus.SC_OK) {
HttpEntity responseEntity = response.getEntity();
String jsonString = EntityUtils.toString(responseEntity,charset);
JSONObject jsonObject1 = JSON.parseObject(jsonString);
success = (boolean) jsonObject1.get("success");
} else {
}
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
接上一页代码,将所有必要信息添加到请求头中去,and then发送请求,发送之后用一个HttpEntity对象获取到相关信息,之后将对象转为json字符串格式来获取success的值,只有success为true,才能继续下一步
fishSourceAttribution.setStatus(1);
BufferedReader in = null;
CloseableHttpResponse response = null;
String url = "http://xxxx:4000/channels/channelproduce";
HashMap params1 = new HashMap();
params1.put("peer", "peer0.org1.example.com");
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
httpClient = HttpClients.createDefault();
URIBuilder uriBuilder = new URIBuilder(url);
//设置参数
if (params1 != null && params1.size() > 0) {
for (Object param : params1.keySet()) {
uriBuilder.setParameter(param + "", params1.get(param) + "");
}
}
//2.创建HttpGet对象,设置URL地址
HttpGet httpGet = new HttpGet(uriBuilder.build());
if (!StringUtils.isBlank(token)) { //设置请求token
httpGet.setHeader("Authorization", "Bearer " + token);
}
System.out.println("发送请求的信息:" + httpGet);
//使用httpClient发起响应获取repsonse
response = httpClient.execute(httpGet);
//4.解析响应,获取数据 判断状态码是否是200
if (response.getStatusLine().getStatusCode() == 200) {
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String s = StringUtils.toStringTrim(sb);
JSONObject jsonObject = JSON.parseObject(s);
height = jsonObject.getJSONObject("height").getInteger("low") - 1;
fishSourceAttribution.setBlockHeight(height);
}
} catch (Exception e) {
e.printStackTrace();
}
又一次调用接口,和上面的方法大差不差,就不再赘述了。
之后,我将上面的接口cv了一份,去调另外一个接口(别问为啥不写在一起,问就是当时代码水平能力太拉,写在一起就因为各种问题报错,索性就直接cv一份再自己去改)
String url1="http://xxxx:4000/channels/channelproduce/blocks/"+height.toString();
BufferedReader in1 = null;
CloseableHttpClient httpClient1 = HttpClients.createDefault();
try {
httpClient1 = HttpClients.createDefault();
URIBuilder uriBuilder = new URIBuilder(url1);
//设置参数
if (params1 != null && params1.size() > 0) {
for (Object param : params1.keySet()) {
uriBuilder.setParameter(param + "", params1.get(param) + "");
}
}
//2.创建HttpGet对象,设置URL地址
HttpGet httpGet = new HttpGet(uriBuilder.build());
if (!StringUtils.isBlank(token)) { //设置请求token
httpGet.setHeader("Authorization", "Bearer " + token);
}
System.out.println("发送请求的信息:" + httpGet);
//使用httpClient发起响应获取repsonse
response = httpClient1.execute(httpGet);
//4.解析响应,获取数据 判断状态码是否是200
if (response.getStatusLine().getStatusCode() == 200) {
in1 = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in1.readLine()) != null) {
sb.append(line + NL);
}
in1.close();
String s = StringUtils.toStringTrim(sb);
JSONObject jsonObject = JSON.parseObject(s);
String previousHash = jsonObject.getJSONObject("header").getString("previous_hash");
fishSourceAttribution.setLastBlockHash(previousHash);
String dataHash = jsonObject.getJSONObject("header").getString("data_hash");
fishSourceAttribution.setDataHash(dataHash);
fishSourceAttribution.setChainName("fishproduce");
fishSourceAttribution.setSmartContracts("agrifishTrace");
fishSourceAttribution.setSource("渔业种质平台");
fishSourceAttribution.setCreateTime(fishSourceAttribution.getGmtCreate());
fishSourceAttribution.setPubdata(pubData);
fishSourceAttribution.setPridata(priData);
save = fishSourceAttributionService.updateById(fishSourceAttribution);
}
System.out.println("请求状态码----" + response.getStatusLine().getStatusCode());
} catch (Exception e) {
e.printStackTrace();
}
获取到数据后就是经典的添加操作了。以上,上传至区块链接口完成,数据成功入库,为下面一个数据校验的接口做了铺垫
@ApiOperation(value = "数据校验")
@GetMapping("/dataalidation")
@RequiresRoles(logical = Logical.OR, value = {"admin"})
public int dataAlidation(@RequestParam String id){
long l = Long.parseLong(id);
FishSourceAttribution fishSourceAttribution = fishSourceAttributionService.getById(l);
BufferedReader in = null;
CloseableHttpResponse response = null;
String url = "http://xxxx:4000/channels/channelproduce/chaincodes/syTrace";
String s=null;
HashMap params = new HashMap();
LinkedList linkedList=new LinkedList();
HashMap map=new HashMap();
HashMap map1=new HashMap();
HashMap map2=new HashMap();
params.put("peer", "peer0.org1.example.com");
params.put("fcn", "getPridata");
params.put("args", "[""+fishSourceAttribution.getSourceId()+""]");
String token = "该token不可见";
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
httpClient = HttpClients.createDefault();
URIBuilder uriBuilder = new URIBuilder(url);
//设置参数
if (params != null && params.size() > 0) {
for (Object param : params.keySet()) {
uriBuilder.setParameter(param + "", params.get(param) + "");
}
}
//2.创建HttpGet对象,设置URL地址
HttpGet httpGet = new HttpGet(uriBuilder.build());
if (!StringUtils.isBlank(token)) { //设置请求token
httpGet.setHeader("Authorization", "Bearer " + token);
}
System.out.println("发送请求的信息:" + httpGet);
//使用httpClient发起响应获取repsonse
response = httpClient.execute(httpGet);
//4.解析响应,获取数据 判断状态码是否是200
if (response.getStatusLine().getStatusCode() == 200) {
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
s = StringUtils.toStringTrim(sb);
}
System.out.println("请求状态码----" + response.getStatusLine().getStatusCode());
} catch (Exception e) {
e.printStackTrace();
}
BufferedReader in1 = null;
CloseableHttpResponse response1 = null;
HashMap params1 = new HashMap();
params1.put("peer", "peer0.org1.example.com");
params1.put("fcn", "getPubdata");
params1.put("args", "[""+fishSourceAttribution.getSourceId()+""]");
CloseableHttpClient httpClient1 = HttpClients.createDefault();
try {
httpClient1 = HttpClients.createDefault();
URIBuilder uriBuilder = new URIBuilder(url);
//设置参数
if (params1 != null && params1.size() > 0) {
for (Object param : params1.keySet()) {
uriBuilder.setParameter(param + "", params1.get(param) + "");
}
}
//2.创建HttpGet对象,设置URL地址
HttpGet httpGet = new HttpGet(uriBuilder.build());
if (!StringUtils.isBlank(token)) { //设置请求token
httpGet.setHeader("Authorization", "Bearer " + token);
}
System.out.println("发送请求的信息:" + httpGet);
//使用httpClient发起响应获取repsonse
response = httpClient.execute(httpGet);
//4.解析响应,获取数据 判断状态码是否是200
if (response.getStatusLine().getStatusCode() == 200) {
in1 = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in1.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String s2 = StringUtils.toStringTrim(sb);
String s3=fishSourceAttribution.getPridata();
String s4=fishSourceAttribution.getPubdata().toLowerCase(Locale.ROOT);
System.out.println(s);
System.out.println(s2);
String pubData = "节点名称:peer0.org1.example.com|上链时间:" + fishSourceAttribution.getGmtCreate().toString().toLowerCase(Locale.ROOT) + "|鱼名称:" + fishSourceAttribution.getFishName();
String priData = "鱼名称:" + fishSourceAttribution.getFishName() + "|种质所属名称:" + fishSourceAttribution.getSubjectName() + "|鱼类型:" + fishSourceAttribution.getFishSourceClass() + "|亲鱼来源:" + fishSourceAttribution.getParentSource() +
"|归属人:" + fishSourceAttribution.getBelongManName() + "|归属主题:" + fishSourceAttribution.getUserClass() + "|种质所属主体类别:" + fishSourceAttribution.getSubject()+"|归属地:"+fishSourceAttribution.getProvince()+fishSourceAttribution.getCity()+fishSourceAttribution.getCounty()+fishSourceAttribution.getAddress();
if (s.equals(priData) ||s2.equals(pubData)){
return 0;
}
}
System.out.println("请求状态码----" + response.getStatusLine().getStatusCode());
} catch (Exception e) {
e.printStackTrace();
}
return 1;
}
这样一看数据校验和上传至区块链的接口大同小异,只是多了查数据以及比对的操作,最后返回成功代码,至此,接口顺利完成。
这一块代码是我加入实验室后不久写出来的代码,看似如此简单的接口,我当时写了快一个星期,而且那时候还阳了,有趣的是,当时发烧时起床给数据表添加新字段的时候直接写中文,给当时和我沟通的奎哥(区块链接口提供者)弄笑了
那时的我刚进实验室没多久,代码水平很拉,springboot也是速成,不过历经一个星期写出的接口能跑了,当时真的格外开心,很有成就感,最后,该项目也是通过流量测试并成功结题。
以上就是关于我第一次写的接口的所有内容,希望大家每天都能够进步,包括我嘻嘻