JSONPATH-阿里和jayway的实现测试
业务业务的需要,所以想找一个从对象中获取属性的工具。
搜了搜发现由阿里和jayway的实现,又花费了一些时间了解和练习,总结了一些要点:
阿里的可能快一些,但考虑到完备性,也许选择jayway更好一些。
本文档参考了以下URL:
Jayway JsonPath介绍_com.jayway.jsonpath-CSDN博客
FASTJSON2 JSONPath支持介绍 | fastjson2
https://github.com/json-path/JsonPath
一、测试代码
1.1基本类TestJsonPath
用于生成测试数据:
package study.base.json; import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import study.base.classes.ChineseMan;
import study.base.classes.Human;
import study.base.classes.Parent; /**
* JsonPath练习
* @author lzfto
*/
public abstract class TestJsonPath { public String toJsonString(Object obj) {
ObjectMapper objectMapper = new ObjectMapper();
String json;
try {
json = objectMapper.writeValueAsString(obj);
return json;
} catch (JsonProcessingException e) {
return "";
} }
public ChineseMan getJObject() {
ChineseMan lzf = new ChineseMan();
lzf.setName("lzf");
lzf.setAge(12);
lzf.setHeight(90);
lzf.setHeight(170);
lzf.set力量("大力");
lzf.set斗志("昂扬");
lzf.setType("传承");
lzf.setSoldier(true);
lzf.setGender("男");
lzf.setBirthDay(new Date());
lzf.setLocation("中国");
Parent father = new Parent("鲁达", "男", 99, new BigDecimal("180"));
Parent mather = new Parent("黄试", "女", 103, new BigDecimal("160"));
lzf.setFather(father);
lzf.setMother(mather); Human girl =new Human("女");
girl.setName("lml");
girl.setHeight(160);
girl.setWeight(90);
girl.setLocation("中国");
girl.setType("创造");
girl.setBirthDay(new Date());
girl.setEatable(false); Human e =new Human("男");
e.setName("lmj");
e.setHeight(175);
e.setWeight(140);
e.setLocation("中国");
e.setType("前瞻");
e.setBirthDay(new Date());
e.setEatable(false);
lzf.getChildren().add(girl);
lzf.getChildren().add(e); return lzf;
} public List<ChineseMan> getObjectList() { final String[] names = { "楼上的", "非法手段", "口袋空空", "嗯嗯开始", "共和国和", "给v叫我", "说的话我", "很多我不怕", "皮肤和", "工期哈" };
Random random = new Random();
List<ChineseMan> list=new ArrayList<>(); for (int i = 1; i <= 10; i++) {
int namePos = random.nextInt(10); // 生成0到9之间的随机数
String name = names[namePos];
int age = random.nextInt(100);
int height = random.nextInt(200);
int weight = random.nextInt(100);
String sex = random.nextInt(0,2) == 1 ? "男" : "女";
ChineseMan jo = this.getRanddomObject(name, age, height, weight, sex);
list.add(jo);
} return list;
} public ChineseMan getRanddomObject(String name, Integer age, Integer height, Integer weight, String sex) {
Random random = new Random();
ChineseMan lzf = new ChineseMan();
lzf.setName(name);
lzf.setAge(age);
lzf.setHeight(height);
lzf.setHeight(weight);
lzf.set力量("大力");
lzf.set斗志("昂扬");
lzf.setType("传承");
lzf.setSoldier(true);
lzf.setGender(sex);
lzf.setBirthDay(new Date());
lzf.setLocation("中国");
Parent father = new Parent(name + "爸", "男", 99, new BigDecimal("180"));
Parent mather = new Parent(name + "妈", "女", 103, new BigDecimal("160"));
lzf.setFather(father);
lzf.setMother(mather); Human girl =new Human("女");
girl.setName(name+"女");
girl.setHeight(random.nextInt(155, 170));
girl.setWeight(random.nextInt(80, 90));
girl.setLocation("中国");
girl.setType("创造");
girl.setBirthDay(new Date());
girl.setEatable(false);
girl.setPower(random.nextInt(100, 400)); Human e =new Human("男");
e.setName(name+"男");
e.setHeight(random.nextInt(155, 170));
e.setWeight(random.nextInt(80, 99));
e.setLocation("中国");
e.setType("前瞻");
e.setBirthDay(new Date());
e.setEatable(false);
e.setPower(random.nextInt(100, 900));
lzf.getChildren().add(girl);
lzf.getChildren().add(e);
return lzf;
} /**
* 从JSON对象中一次获取多个key
*
* @param jo JSON对象
* @param pathList 路径
*/
public abstract void testReadMultiKeyOnce(Object jo, List<String> pathList); /**
* 测试在JSON数组中进行查找,汇总等等 </br>
* </br>
* 不考虑按照数组序号进行查找
*
* @param ja
* @param pathList
*/
public abstract void testReadJsonarray(Object ja, List<String> pathList) ; /**
* 从JSON数组中过读取特定的元素,包含简单的过滤
*
* @param ja
* @param pathList
*/
public abstract void testFilterJsonarray(Object ja, List<String> pathList); }
1.2 阿里实现
package study.base.json.fastjson; import java.util.Arrays;
import java.util.List; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONPath;
import com.alibaba.fastjson2.JSONWriter; import study.base.classes.ChineseMan;
import study.base.classes.Parent;
import study.base.json.TestJsonPath; /**
* JSONPATH练习
*
* @author lzfto
*/
public class TestFastJsonJSONPath extends TestJsonPath{ /**
* 从JSON对象中一次获取多个key
*
* @param jo JSON对象
* @param pathList 路径
*/
@Override
public void testReadMultiKeyOnce(Object jo, List<String> pathList) {
for (String path : pathList) { try {
Object item = JSONPath.eval(jo, path);
if (item != null) {
if (item instanceof Parent) {
System.out.println(
"key[" + path + "]=" + JSON.toJSONString(item, JSONWriter.Feature.PrettyFormat));
} else {
System.out.println("key[" + path + "]=" + item.toString());
} } else {
System.out.println("key[" + path + "]没有找到对应的值");
}
} catch (Exception e) {
System.out.println("key[" + path + "]没有找到对应的值,因为:"+e.getMessage());
}
} } /**
* 测试在JSON数组中进行查找,汇总等等 </br>
* </br>
* 不考虑按照数组序号进行查找
*
* @param ja
* @param pathList
*/
@Override
public void testReadJsonarray(Object ja, List<String> pathList) {
for (String path : pathList) {
try {
Object item = JSONPath.eval(ja, path);
if (item != null) {
if (item instanceof Parent) {
System.out.println(
"key[" + path + "]=" + JSON.toJSONString(item, JSONWriter.Feature.PrettyFormat));
} else {
System.out.println("key[" + path + "]=" + item.toString());
} } else {
System.out.println("key[" + path + "]没有找到对应的值");
}
} catch (Exception e) {
System.out.println("key[" + path + "]没有找到对应的值,因为:" + e.getMessage());
}
}
} /**
* 从JSON数组中过滤掉特定的元素(满足条件的留下)
*
* @param ja
* @param pathList
*/
@Override
public void testFilterJsonarray(Object ja, List<String> pathList) {
for (String path : pathList) {
try {
Object item = JSONPath.eval(ja, path);
if (item != null) {
System.out.println(
"key[" + path + "]=" + JSONArray.toJSONString(item, JSONWriter.Feature.PrettyFormat)); } else {
System.out.println("条件[" + path + "]没有找到对应的值");
}
} catch (Exception e) {
System.out.println("key[" + path + "]没有找到对应的值,因为:" + e.getMessage());
}
}
} /**
* @param args
*/
/**
* @param args
*/
public static void main(String[] args) {
TestFastJsonJSONPath test = new TestFastJsonJSONPath();
// 1.0 JSONObject中的查找
Object jo = test.getJObject();
List<String> list = Arrays.asList(
// 简单的key查找
"$.name", "$.age", "$.height", "$.力量", "$.father", "$.mother",
// 查找层级大于1的子节点
"$.father.name", "$.mother.name",
"$.children[*]", //所有的孩子
"$.children", //所有的孩子
"$.children[0]", //第一个孩子
"$.children[0].name", //第一个孩子的姓名
// 同时查找多个key/属性,返回的是一个数组,按照顺序的 ["lzf",12,"男"]
"$[\"name\",\"age\",\"gender\"]",
"$[name,age]" // 这个是错误的语法
);
test.testReadMultiKeyOnce(jo, list); // 2.0 JSONArray中的查找
// 2.1 JSON聚集函数 -- 经过测试 fastjson2的JSONPath并不支持max,min等函数
// 主要测试:min,max,avg,sum(),concat,keys(),length()
// 查找成员的成员存在一些问题
// a.无法同时获取多个数组中的多个key
// b.不支持基本的四则运算
// c.不支持特定的函数avg
// e.无法获取数组成员的指定成员,例如如果某个成员是数组,那么无法从这个数组获取指定序号的成员
// 例如不能用 [*].children[0] 来或者 每人的第一个孩子
List<ChineseMan> ja = test.getObjectList();
//System.out.println(JSONArray.toJSONString(ja, Feature.PrettyFormat));
list = Arrays.asList("$[0].name", // 第1个元素的name
"$[*]" // 返回所有的数组元素
, "$[*].age.sum()" // 汇总所有的年龄
, "$[*].age.min()" // 最大年龄
, "$[*].age.max()" // 最小的年龄
, "$[*].age.length()" // 数组个数
, "$[*].length()" // 数组个数
, "$[*]..power" // 所有能量
, "$..power" // 所有能量
//返回数组中数组成员的属性,以下几个居然是等价的,这到底是灵活还是阿里程序员的能力导致的?
, "$[*].children.weight" //返回所有孩子体重,结果是数组*2(因为每人都是2个孩)
, "$[*].children[0].weight" //返回所有第一个孩子体重,结果是数组*1(因为每人都是2个孩)
, "$[*].children[*].weight" //返回所有第一个孩子体重,结果是数组*1(因为每人都是2个孩)
, "$[*].children.weight[0]" //返回所有第一个孩子体重,结果是数组*1(因为每人都是2个孩)
//如何才能够返回所有人第一个孩子的体重信息? , "$[*][\"age\"]" // 所有年龄
, "$[*][\"father\"]" // 所有人员的父亲
, "$[*][\"father\"].name" // 所有人员的父亲的姓名
, "$[*].mother.name" // 所有人员的母亲的姓名
// 以下是错误的语法,或者是不支持的功能
, "$[*].father.length()+$[*].mather.length()" // 所有人员的父母个数,这个语法不合格。不支持四则运算
, "$[*][\"father\",\"mother\"]" // 所有人员的父亲母亲 这个语法非法
, "$[*].age.avg()" // 不支持avg,但可以通过sum/length来解决
);
test.testReadJsonarray(ja, list); // 3.0 JSONArray的过滤测试
// fastjson的过滤相当优先,不能使用组合条件
System.out.println("=========================================================================");
System.out.println("============== 过滤测试 ===================================");
System.out.println("=========================================================================");
list = Arrays.asList("$[*][?(age>90)]" // 返回所有年龄>90的
, "$[*].children[?(weight<100)]" //返回所有孩子体重小于100的孩子信息(非人员信息)
, "$[*].children.weight" //返回所有孩子体重
, "$[*][?(@.children.weight<100)]" //返回所有孩子体重小于100的人员信息(非人员信息)
, "$[*][?(@.children[*].weight<100)]" //返回所有孩子体重小于100的人员信息(非人员信息)
, "$[*][?(@.children.weight<100)]" //返回所有孩子体重小于100的人员信息(非人员信息)
, "$[*][?(age>60sex='女')]" // 返回所有年龄>60的女性个数
);
test.testFilterJsonarray(ja, list);
} }
1.3jayway实现
package study.base.json.jayway; import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.Filter;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.ReadContext;
import com.jayway.jsonpath.internal.filter.FilterCompiler;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider; import study.base.classes.ChineseMan;
import study.base.classes.Parent;
import study.base.json.TestJsonPath; /**
* JsonPath练习-基于jayway </br>
* 据说比fastjson的好用
*
* @author lzfto
*/
public class TestJAYWAYJsonPath extends TestJsonPath { /**
* 从JSON数组中过滤掉特定的元素(满足条件的留下)
*
* @param ja
* @param pathList
*/
@Override
public void testFilterJsonarray(Object ja, List<String> pathList) {
Predicate[] pa = new Predicate[0];
ReadContext ctx = JsonPath.parse(ja);
for (String path : pathList) {
try {
Object item = ctx.read(path, pa);
if (item != null) {
System.out.println("key【" + path + "】=" + this.toJsonString(item)); } else {
System.out.println("条件【" + path + "】没有找到对应的值");
}
} catch (Exception e) {
System.out.println("key【" + path + "】没有找到对应的值,因为:" + e.getMessage());
}
}
} public void testFilterJsonarray(DocumentContext doc, List<String> pathList,Predicate filter) {
for (String path : pathList) {
try {
Object item = doc.read(path, filter);
if (item != null) {
System.out.println(
"key【" + path + "】=" + this.toJsonString(item)); } else {
System.out.println("条件【" + path + "】没有找到对应的值");
}
} catch (Exception e) {
System.out.println("key【" + path + "】没有找到对应的值,因为:" + e.getMessage());
}
}
} /**
* 从JSON对象中一次获取多个key
*
* @param jo JSON对象
* @param pathList 路径
*/
@Override
public void testReadMultiKeyOnce(Object jo, List<String> pathList) {
Predicate[] pa = new Predicate[0];
ReadContext ctx = JsonPath.parse(jo);
for (String path : pathList) {
try {
Object item = ctx.read(path, pa);
if (item != null) {
if (item instanceof Parent) {
System.out.println("key[" + path + "]=" + this.toJsonString(item));
} else {
System.out.println("key[" + path + "]=" + item.toString());
} } else {
System.out.println("key[" + path + "]没有找到对应的值");
}
} catch (Exception e) {
System.out.println("key[" + path + "]没有找到对应的值,因为:" + e.getMessage());
}
} } /**
* 测试在JSON数组中进行查找,汇总等等 </br>
* </br>
* 不考虑按照数组序号进行查找
*
* @param ja
* @param pathList
*/
@Override
public void testReadJsonarray(Object ja, List<String> pathList) {
Predicate[] pa = new Predicate[0];
ReadContext ctx = JsonPath.parse(ja);
for (String path : pathList) {
try {
Object item = ctx.read(path, pa);
if (item != null) {
if (item instanceof Parent) {
System.out.println("key[" + path + "]=" + this.toJsonString(item));
} else {
System.out.println("key[" + path + "]=" + item.toString());
} } else {
System.out.println("key[" + path + "]没有找到对应的值");
}
} catch (Exception e) {
System.out.println("key[" + path + "]没有找到对应的值,因为:" + e.getMessage());
}
}
} /**
* @param args
*/
/**
* @param args
*/
@SuppressWarnings("unchecked")
public static void main(String[] args) { Configuration.setDefaults(new Configuration.Defaults() {
private final JsonProvider jsonProvider = new JacksonJsonProvider();
private final MappingProvider mappingProvider = new JacksonMappingProvider(); @Override
public JsonProvider jsonProvider() {
return jsonProvider;
} @Override
public MappingProvider mappingProvider() {
return mappingProvider;
} @Override
public Set<Option> options() {
return EnumSet.noneOf(Option.class);
}
});
TestJAYWAYJsonPath test = new TestJAYWAYJsonPath();
// 1.0 ObjectMapper中的查找
ChineseMan jo = test.getJObject();
System.out.println("=========================================================================");
System.out.println("============== 读取json对象===================================");
System.out.println("=========================================================================");
List<String> list = Arrays.asList(
// 简单的key查找 $ddd.vvvScVSs
"$", "$.name", "$[?(@.gender=='男')]", "$.*",
// 查找层级大于1的子节点
"$.father.name", "$.mother.name", "$.children[*]", // 所有的孩子
"$.children[0]", // 第一个孩子
// 同时查找多个key/属性,返回的是一个数组,按照顺序的 ["lzf",12,"男"]
"$[\"name\",\"age\",\"gender\"]", "$['name','age','gender']");
Map<String, Object> map = Configuration.defaultConfiguration().mappingProvider().map(jo, Map.class,
Configuration.defaultConfiguration());
test.testReadMultiKeyOnce(map, list); // 2.0 JSONArray中的查找
// 2.1 JSON聚集函数 -- 经过测试 fastjson2的JsonPath并不支持max,min等函数
// 主要测试:min,max,avg,sum(),concat,keys(),length()
// 查找成员的成员存在一些问题
// a.如果要访问数组成员的属性,那么不能直接使用.访问,必须使用 [n].prop或者[*].prop,或者使用递归获取..
// chidlren[*].weight和children..weight在某些情况下是等价的
System.out.println("=========================================================================");
System.out.println("============== 读取JSON数组===================================");
System.out.println("=========================================================================");
List<ChineseMan> ja = test.getObjectList();
ja.get(0).getChildren().get(0).setWeight(10);
ja.get(0).getChildren().get(1).setWeight(20);
List<Map<String, Object>> listmap = Configuration.defaultConfiguration().mappingProvider().map(ja, List.class,
Configuration.defaultConfiguration());
list = Arrays.asList("$[0].name", // 第1个元素的name
"$[*]" // 返回所有的数组元素
, "sum($[*].age)" // 汇总所有的年龄
, "min($[*].age)" // 最大年龄
, "max($[*].age)" // 最小的年龄
, "avg($[*].age)" // 平均年龄
, "$.length()" // 数组个数
// 返回数组中数组成员的属性,以下几个居然是等价的,这到底是灵活还是阿里程序员的能力导致的?
, "$[*]..power" // 所有能量
, "$..power" // 返回所有的power--即所谓的深度扫描deepScan
, "$[*].children[0].weight" // 返回所有第一个孩子体重,结果是数组*1(因为每人都是2个孩)
, "$[*].children[*].weight" // 返回所有孩子体重,结果是数组*2(因为每人都是2个孩)
, "$[*].children..weight" // 返回所有孩子体重,结果是数组*2(因为每人都是2个孩)
, "$[*][\"father\",\"mother\"]" // 所有人员的父亲母亲--示范:同时读取数组中的多个元素
, "$[*][\"age\"]" // 所有年龄
, "$[*][\"father\"]" // 所有人员的父亲
, "$[*][\"father\"].name" // 所有人员的父亲的姓名
, "$[*].mother.name" // 所有人员的母亲的姓名
// 以下是错误的语法,或者是不支持的功能
, "$[*].father.length()+$[*].mather.length()" // 可以返回 [4,4] 但不是期望的 ); test.testReadJsonarray(listmap, list); // 3.0 JSONArray的过滤测试
// a.过滤的语法访问属性通常要带上@.
// b.可以对过滤后的数据再次过滤(不过这个过滤是直接的属性访问,不是用?语法)
// c.如果成员也是list,那么无法对检测此类成员的每一个
// fastjson的过滤相当优先,不能使用组合条件
System.out.println("=========================================================================");
System.out.println("============== 过滤测试 ===================================");
System.out.println("=========================================================================");
list = Arrays.asList("$[*].age" // 返回所有年龄>90的
, "$[*][?(@.age>60)].name" // 返回所有年龄>90的姓名
, "$[*][?(@.age>60)]" // 返回所有年龄>90的
, "$[*].children" // 返回所有年龄>90的姓名
, "$[*].children[*].['weight']" // 所有孩子的体重
, "$[*].children[*].weight" // 所有孩子的体重
, "$[*].children[*].['name','weight']" // 所有孩子的名称和体重
, "$[*][?(@.children[*].weight subsetof [10,20])]" // 孩子体重只是10,20的
, "$[*].children[?(@.weight<100)]['name','weight']" // 返回所有孩子体重小于100的孩子信息(非人员信息)
, "$[*][?(@.children[0].weight<100)]['name','weight']" // 返回第一个孩子体重小于100的人员信息(非孩子)
// 以下是错误的语法,或者是不支持的功能
);
test.testFilterJsonarray(listmap, list); //过滤测试 list = Arrays.asList(
// ------------------------------------------------------------------------
"$[*][?]" // 返回所有年龄>60的女性个数
);
DocumentContext doc=JsonPath.parse(listmap);
Filter filter=FilterCompiler.compile("[?(@.age>60)]");
Filter filter2=FilterCompiler.compile("[?(@.gender=='男')]");
Filter filter3=filter2.and(filter); test.testFilterJsonarray(doc, list, filter3); } }
二、小结
a.代码完善性-jayway比阿里好。
ali的开源一贯的大毛病:代码质量不怎么样、文档不怎么样、功能也不怎么样。
jayway实现的功能更加完善一些,例如以下一些是阿里没有的:
, "$[*]..power" // 所有能量
, "$..power" // 所有能量
, "avg($[*].age)" // 平均年龄
"$['name','age','gender']"
总体来说就是jayway的实现会稍微完善一些,友好一些。
b.性能
没有测试过,如果是比较注重效率务必自行测试。如果对效率要求不高的,则推荐jayway
总之jsonpath是一个好东西,在不少的业务场景中具有不少的用处。
JSONPATH-阿里和jayway的实现测试的更多相关文章
- Java JsonPath grab InvalidPathException in code, you must be catching Java 7's java.nio.file.InvalidPathException instead of JsonPath's com.jayway.jsonpath.InvalidPathExceptio
I am using JsonPath and am able to parse my data and get the values when the path provided is correc ...
- (二)基于阿里云的MQTT远程控制(购买阿里云,在云端安装MQTT,测试MQTT远程通信)
QQ名称为Friday~的网友把他自己买MQTT的过程截图发给了我,今天就说一下如何购买阿里云,安装MQTT可以参考 http://www.cnblogs.com/yangfengwu/p/77646 ...
- 阿里毕玄:来测试下你的Java编程能力
上篇整理了下后面准备更系统化写的Java编程进阶的思路,如果仅看里面的词,很多同学会觉得都懂,但我真心觉得没有多少人是真懂的,所以简单的想了一些题目,感兴趣的同学们可以来做做看,看看自己的Java编程 ...
- 更强的 JsonPath 兼容性及性能测试之2022版(Snack3,Fastjson2,jayway.jsonpath)
2022年了,重新做了一份json path的兼容性与性能测试.三个市面上流行框架比较性测试. 免责声明:可能测试得方式不对而造成不科学的结果(另外,机器不同结果会有不同),可以留言指出来.以下测试数 ...
- 就是这么简单!使用Rest-assured 测试Restful Web Services
使用 Rest-assured 测试 Restful Web Services 转载注明出处: http://www.cnblogs.com/wade-xu/p/4298819.html 这里向大家介 ...
- 使用json-path解析json
在我们的日常开发中,有时候需要从一个json字符串中获取一个值,或者从一段json字符串中获取到某些值,如果先使用Gson或Jackson转换成java对象在获取值,有些时候是很麻烦的,那么有没有一种 ...
- 记一次Redis和NetMQ的测试
Redis是一个高速缓存K-V数据库,而NetMQ是ZeroMQ的C#实现版本,两者是完全不同的东西. 最近做游戏服务器的时候想到,如果选择一个组件来做服务器间通信的话,ZeroMQ绝对是一个不错的选 ...
- 使用jsonpath解析json内容
JsonPath提供的json解析非常强大,它提供了类似正则表达式的语法,基本上可以满足所有你想要获得的json内容.下面我把官网介绍的每个表达式用代码实现,可以更直观的知道该怎么用它. 一.首先需要 ...
- jsonpath读取json数据格式公用方法!!!
import java.util.LinkedHashMap; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.Pred ...
- JsonPath如何获取JSON数据中的值
场景: 发送接口请求后,得到请求结果值是Json数据, 需要从Json数据信息中提取字段值. 响应值字符与字符之间有空格,导致用正则表达式方法提取比较麻烦,于是用java的JsonPath方法提取快速 ...
随机推荐
- dotnet 修复在 Linux 上使用 SkiaSharp 提示找不到 libSkiaSharp 库
本文告诉大家如何简单修复在 Linux 上使用 SkiaSharp 提示找不到 libSkiaSharp 库 我的应用在 Windows 上跑的好好的,放在 Linux 上一运行就炸掉了,异常内容如下 ...
- Petalinux 基本工程的构建
Petalinux 基本工程的构建 在上一节,我们安装好linux了,这一节,我们搭建一个简单的工程测试一下,并通过TF卡启动 电脑环境 vivado版本:2019.2 petalinux版本:201 ...
- git checkout 命令图文详解
目录 git checkout branchname (切换本地分支) 切换远程分支 放弃修改 git checkout . git checkout – filename git checkout ...
- Deepin安装Python3
https://www.jianshu.com/p/0c61bdfb9589 也可以看这篇,本文是这篇的简捷版,均原创 首先,把系统更到最新,并复制下面的代码 sudo apt update 更新软件 ...
- 教你如何破解虚拟机root密码
一.开机时按e键,即可进入grub编辑界面,光标选择第一条,e表示进入编辑模式. 当机器开机出现如图1所示的kernel菜单后,按e键. 二.将光标移动到以linux开头的行,对图2中标注的位置进行修 ...
- flex布局方案
参考:https://blog.csdn.net/weixin_39717076/article/details/82586915
- smtplib详解,发送邮件
创建邮箱账号 1.官网登录邮箱. 2.在邮箱的主界面找到"设置",新版的主界面与旧版稍有不同,一般位于上方,齿轮状的即是. 3.点击齿轮状的设置标志,会弹出一个下拉菜单,在最后有我 ...
- 导入使用es
from django.shortcuts import render, HttpResponsefrom elasticsearch import Elasticsearchfrom elastic ...
- python命令行传参详解,optparse模块OptionParse类的学习
官网链接:https://docs.python.org/3/library/optparse.html https://docs.python.org/2/library/argparse.html ...
- 防火墙规则之iptables
防火墙规则之iptables 一 如何禁止外面应用对某个端口访问 iptables -I INPUT -p TCP ! --source 127.0.0.1 --dport 8080 -j DROP ...