关于我在实验室做项目写的第一个接口...

844 阅读6分钟

昨天感悟了一下人生,今天回归正轨,想记录一下自己进入实验室做项目时写的第一个接口。

当我接手这个项目的时候这个项目已经接近尾声,但还是有一些小功能需要完善一下,原定由师兄完成项目的区块链模块因某些原因无法继续,于是我们只能使用别人的区块链接口,这其中就需要用到一种类似“请求转发”的接口,而我当时仅仅是一个只会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:
变量值都赋好了,然后就是调接口的流程了,具体的示例如下所示

image.png 其实乍一看,感觉没什么难度(不就是把相关的接口地址和一些必要参数弄进请求头一起发送嘛),上手之后,我就不再嘴硬了呵呵

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也是速成,不过历经一个星期写出的接口能跑了,当时真的格外开心,很有成就感,最后,该项目也是通过流量测试并成功结题。

以上就是关于我第一次写的接口的所有内容,希望大家每天都能够进步,包括我嘻嘻