JsonAPI——Hledger入门笔记教程(四)

除了 Web UI,hledger-web 还提供一个 JSON API,可用于获取数据或添加新事务。如果您只需要 JSON API,则可以使用该–serve-api标志。

Json Api启动

hledger-web.exe -f D:\Program\hledger\test.hledger.journal --serve-api

路由

我们可以从以下路由获取Json数据
  
/favicon.ico     FaviconR        GET
/robots.txt      RobotsR         GET
/static          StaticR         Static getStatic

/                RootR           GET
/journal         JournalR        GET
/register        RegisterR       GET
/add             AddR            GET POST PUT

/manage             ManageR         GET
/edit/#FilePath     EditR           GET POST
/upload/#FilePath   UploadR         GET POST
/download/#FilePath DownloadR       GET

/version                           VersionR              GET
/accountnames                      AccountnamesR         GET             帐户名称
/transactions                      TransactionsR         GET             交易
/prices                            PricesR               GET             价格
/commodities                       CommoditiesR          GET
/accounts                          AccountsR             GET
/accounttransactions/#AccountName  AccounttransactionsR  GET
这时候再通过浏览器访问会直接报错,因为没有开启web ui
只能通过Json进行访问,linux系统可以通过curl命令访问,然后通过python命令进行格式化
 curl -s http://127.0.0.1:5000/accountnames | python -m json.tool
这里我是windows系统,同时为了和我们项目保持一致,我们将使用Java模拟访问一下。
官方的json数据:
{
    "tcomment": "",
    "tpostings": [
        {
            "pbalanceassertion": null,
            "pstatus": "Unmarked",
            "pamount": [
                {
                    "aprice": null,
                    "acommodity": "$",
                    "aquantity": {
                        "floatingPoint": 1,
                        "decimalPlaces": 10,
                        "decimalMantissa": 10000000000
                    },
                    "aismultiplier": false,
                    "astyle": {
                        "ascommodityside": "L",
                        "asdigitgroups": null,
                        "ascommodityspaced": false,
                        "asprecision": 2,
                        "asdecimalpoint": "."
                    }
                }
            ],
            "ptransaction_": "1",
            "paccount": "assets:bank:checking",
            "pdate": null,
            "ptype": "RegularPosting",
            "pcomment": "",
            "pdate2": null,
            "ptags": [],
            "poriginal": null
        },
        {
            "pbalanceassertion": null,
            "pstatus": "Unmarked",
            "pamount": [
                {
                    "aprice": null,
                    "acommodity": "$",
                    "aquantity": {
                        "floatingPoint": -1,
                        "decimalPlaces": 10,
                        "decimalMantissa": -10000000000
                    },
                    "aismultiplier": false,
                    "astyle": {
                        "ascommodityside": "L",
                        "asdigitgroups": null,
                        "ascommodityspaced": false,
                        "asprecision": 2,
                        "asdecimalpoint": "."
                    }
                }
            ],
            "ptransaction_": "1",
            "paccount": "income:salary",
            "pdate": null,
            "ptype": "RegularPosting",
            "pcomment": "",
            "pdate2": null,
            "ptags": [],
            "poriginal": null
        }
    ],
    "ttags": [],
    "tsourcepos": {
        "tag": "JournalSourcePos",
        "contents": [
            "",
            [
                1,
                1
            ]
        ]
    },
    "tdate": "2008-01-01",
    "tcode": "",
    "tindex": 1,
    "tprecedingcomment": "",
    "tdate2": null,
    "tdescription": "income",
    "tstatus": "Unmarked"
}

debug模式启动Hledger web

官方描述:General flags: -h –help show general help or (after command) command help –debug=N show debug output if N is 1-9 (default: 0) –version show version information
调试方式启动web ui 
hledger-web.exe --debug=9 -f D:\Program\hledger\test.hledger.journal
经过测试发现是可以获取到debug信息但是并没有得到想要的debug信息。请求错误依旧是简单的返回400错误,没有显示具体信息。

java模拟访问Json

通过json api获取hledger数据

 @Test
   public void test5(){
       String urlPath =  "http://127.0.0.1:5000/transactions";
       try {
            URL url = new URL(urlPath);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            connection.connect();
            InputStream inputStream = connection.getInputStream();
            //对应的字符编码转换
            Reader reader = new InputStreamReader(inputStream, "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(reader);
            String str = null;
            StringBuffer sb = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
            sb.append(str);
            }
            reader.close();
            connection.disconnect();
           System.out.println(sb);

       } catch (IOException e) {
           e.printStackTrace();
       }
   }
账户里只有一条交易的json数据,可以认为是基本组成单位。
未格式化:
[{"tcomment":"","tstatus":"Unmarked","ttags":[],"tprecedingcomment":"","tpostings":[{"pdate":null,"poriginal":null,"ptags":[],"paccount":"资产:银行卡","pdate2":null,"ptype":"RegularPosting","pbalanceassertion":null,"pstatus":"Unmarked","pamount":[{"aprice":null,"acommodity":"","astyle":{"asprecision":0,"asdecimalpoint":".","ascommodityspaced":false,"asdigitgroups":null,"ascommodityside":"L"},"aquantity":{"floatingPoint":1200,"decimalPlaces":0,"decimalMantissa":1200}}],"ptransaction_":"1","pcomment":""},{"pdate":null,"poriginal":null,"ptags":[],"paccount":"资产:现金","pdate2":null,"ptype":"RegularPosting","pbalanceassertion":null,"pstatus":"Unmarked","pamount":[{"aprice":null,"acommodity":"","astyle":{"asprecision":0,"asdecimalpoint":".","ascommodityspaced":false,"asdigitgroups":null,"ascommodityside":"L"},"aquantity":{"floatingPoint":-1200,"decimalPlaces":0,"decimalMantissa":-1200}}],"ptransaction_":"1","pcomment":""}],"tcode":"","tdate":"2021-10-08","tsourcepos":[{"sourceLine":1,"sourceName":"D:\\Program\\hledger\\test.hledger.journal","sourceColumn":1},{"sourceLine":3,"sourceName":"D:\\Program\\hledger\\test.hledger.journal","sourceColumn":28}],"tindex":1,"tdescription":"测试银行卡现金","tdate2":null}]
格式化:
{
	"tcomment": "",
	"tstatus": "Unmarked",
	"ttags": [],
	"tprecedingcomment": "",
	"tpostings": [{
		"pdate": null,
		"poriginal": null,
		"ptags": [],
		"paccount": "资产:电脑库存",
		"pdate2": null,
		"ptype": "RegularPosting",
		"pbalanceassertion": null,
		"pstatus": "Unmarked",
		"pamount": [{
			"aprice": null,
			"acommodity": "",
			"astyle": {
				"asprecision": 2,
				"asdecimalpoint": ".",
				"ascommodityspaced": false,
				"asdigitgroups": null,
				"ascommodityside": "L"
			},
			"aquantity": {
				"floatingPoint": 13293.12,
				"decimalPlaces": 2,
				"decimalMantissa": 1329312
			}
		}],
		"ptransaction_": "1",
		"pcomment": ""
	}, {
		"pdate": null,
		"poriginal": null,
		"ptags": [],
		"paccount": "资产:银行存款",
		"pdate2": null,
		"ptype": "RegularPosting",
		"pbalanceassertion": null,
		"pstatus": "Unmarked",
		"pamount": [{
			"aprice": null,
			"acommodity": "",
			"astyle": {
				"asprecision": 2,
				"asdecimalpoint": ".",
				"ascommodityspaced": false,
				"asdigitgroups": null,
				"ascommodityside": "L"
			},
			"aquantity": {
				"floatingPoint": -13293.12,
				"decimalPlaces": 2,
				"decimalMantissa": -1329312
			}
		}],
		"ptransaction_": "1",
		"pcomment": ""
	}],
	"tcode": "",
	"tdate": "2021-10-08",
	"tsourcepos": [{
		"sourceLine": 2,
		"sourceName": "D:\\Program\\hledger\\test.hledger.journal",
		"sourceColumn": 1
	}, {
		"sourceLine": 5,
		"sourceName": "D:\\Program\\hledger\\test.hledger.journal",
		"sourceColumn": 1
	}],
	"tindex": 1,
	"tdescription": "采购-电脑",
	"tdate2": null
}
多条记录重复上述json组。

经测试发现报文类型要求的非常严格如下:模版里的null就是null,不是””,javaBean to json也要是null
"tdate2": null
"aprice": null,
"asdigitgroups": null,
如果java生成的报文为””,则发送不成功。

通过json api向hledger发送数据

用Http PUT添加一条交易信息,目前测试同样的报文Http Post报错,Http Put可以正确添加。
@Test
   public void test6(){
        try {

            CloseableHttpClient httpclient = HttpClients.createDefault();


            //HttpPost httpPost = new HttpPost("http://127.0.0.1:5000/add");
            HttpPut httpPost = new HttpPut("http://127.0.0.1:5000/add");
            httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");


            String tempJson = "{\"tcomment\":\"\",\"tstatus\":\"Unmarked\",\"ttags\":[],\"tprecedingcomment\":\"\",\"tpostings\":[{\"pdate\":null,\"poriginal\":null,\"ptags\":[],\"paccount\":\"资产:银行卡\",\"pdate2\":null,\"ptype\":\"RegularPosting\",\"pbalanceassertion\":null,\"pstatus\":\"Unmarked\",\"pamount\":[{\"aprice\":null,\"acommodity\":\"\",\"astyle\":{\"asprecision\":0,\"asdecimalpoint\":\".\",\"ascommodityspaced\":false,\"asdigitgroups\":null,\"ascommodityside\":\"L\"},\"aquantity\":{\"floatingPoint\":3200,\"decimalPlaces\":0,\"decimalMantissa\":3200}}],\"ptransaction_\":\"1\",\"pcomment\":\"\"},{\"pdate\":null,\"poriginal\":null,\"ptags\":[],\"paccount\":\"资产:现金\",\"pdate2\":null,\"ptype\":\"RegularPosting\",\"pbalanceassertion\":null,\"pstatus\":\"Unmarked\",\"pamount\":[{\"aprice\":null,\"acommodity\":\"\",\"astyle\":{\"asprecision\":0,\"asdecimalpoint\":\".\",\"ascommodityspaced\":false,\"asdigitgroups\":null,\"ascommodityside\":\"L\"},\"aquantity\":{\"floatingPoint\":-3200,\"decimalPlaces\":0,\"decimalMantissa\":-3200}}],\"ptransaction_\":\"1\",\"pcomment\":\"\"}],\"tcode\":\"\",\"tdate\":\"2021-10-08\",\"tsourcepos\":[{\"sourceLine\":1,\"sourceName\":\"D:\\\\Program\\\\hledger\\\\test.hledger.journal\",\"sourceColumn\":1},{\"sourceLine\":3,\"sourceName\":\"D:\\\\Program\\\\hledger\\\\test.hledger.journal\",\"sourceColumn\":28}],\"tindex\":1,\"tdescription\":\"测试银行卡现金3\",\"tdate2\":null}";


            // 解决中文乱码问题
            // StringEntity stringEntity = new StringEntity(obj.toString(), "UTF-8");
            StringEntity stringEntity = new StringEntity(tempJson, "UTF-8");
            stringEntity.setContentEncoding("UTF-8");

            httpPost.setEntity(stringEntity);

            // CloseableHttpResponse response =
            // httpclient.execute(httpPost);

            System.out.println("Executing request " + httpPost.getRequestLine());

            // Create a custom response handler
            ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
                @Override
                public String handleResponse(final HttpResponse response)
                        throws ClientProtocolException, IOException {//
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {

                        HttpEntity entity = response.getEntity();

                        return entity != null ? EntityUtils.toString(entity) : null;
                    } else {
                        throw new ClientProtocolException(
                                "Unexpected response status: " + status);
                    }
                }
            };
            String responseBody = httpclient.execute(httpPost, responseHandler);
            System.out.println("----------------------------------------");
            System.out.println(responseBody);

        } catch (Exception e) {
            System.out.println(e);
        }
   }
apache http client的maven坐标:
    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.10</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.12</version>
        </dependency>
大T笔记所有文章均为本人原创,转载请您注明来源,并留下原文链接地址,是对我的尊重,也是对知识的尊重,谢谢!
大T笔记 » JsonAPI——Hledger入门笔记教程(四)

大T笔记-我的个人互联网创业和自由职业之路

关于我 我的百宝箱
大T笔记-专注个人互联网创业和自由职业