使用Jackson从请求JSON中提取某些字段和值
我正在寻找一种方法,只包含从接收到我的服务的JSON请求中的某些字段,然后相应地记录它们,以避免记录太多数据 要包含的字段和日志将在属性文件中配置 由于我使用Spring Boot提供服务,Jackson JARs应该已经可以使用了 由于请求JSON非常复杂,包含嵌套数组和对象作为字段,我不确定我是否可以使用Jackson实现我的要求 有没有办法使用Jackson API从输入请求JSON中仅提取某些字段及其值 基本上,我在看两个用例 1.从Json字符串中选择一个或多个元素(我打算通过配置传递),然后呈现它们 2.选择并更新一个或多个内联元素。我想在渲染元素之前屏蔽它们的值 我提供了选择元素和Json的代码,我使用了这些元素和Json,下面是我所期望的使用Jackson从请求JSON中提取某些字段和值,json,spring-boot,jackson,Json,Spring Boot,Jackson,我正在寻找一种方法,只包含从接收到我的服务的JSON请求中的某些字段,然后相应地记录它们,以避免记录太多数据 要包含的字段和日志将在属性文件中配置 由于我使用Spring Boot提供服务,Jackson JARs应该已经可以使用了 由于请求JSON非常复杂,包含嵌套数组和对象作为字段,我不确定我是否可以使用Jackson实现我的要求 有没有办法使用Jackson API从输入请求JSON中仅提取某些字段及其值 基本上,我在看两个用例 1.从Json字符串中选择一个或多个元素(我打算通过配置传递
public String getValues(String key,String jsonString){
String fieldNodeStr =null;
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonString);
JsonNode fieldNode = node.at(key);
fieldNodeStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(fieldNode);
System.out.println(fieldNodeStr);
} catch (IOException e) {
System.out.println("IOException:",e);
}catch (Exception e) {
System.out.println("Exception:",e);
}
}
我的Json如下所示
{
"employeeId" : "5353",
"salesId" : "sales005",
"manager" : {
"userId" : "managerUser",
"isSuperUser" : false,
"firstName":"manager first name",
"lastName":"manager last name"
},
"administrator" : {
"userId" : "administratorUser",
"isSuperUser" : false,
"firstName":"admin first name",
"lastName":"admin last name"
},
"requester" : [
{
"id":"1234",
"demographic" : {
"firstName" : "hello",
"lastName" : "hai"
}
},
{
"id":"1235",
"demographic" : {
"firstName" : "welcome",
"lastName" : "user"
}
}
]
}
我有两个问题如下
public String getValues(String key,String jsonString){
String fieldNodeStr =null;
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonString);
JsonNode fieldNode = node.at(key);
fieldNodeStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(fieldNode);
System.out.println(fieldNodeStr);
} catch (IOException e) {
System.out.println("IOException:",e);
}catch (Exception e) {
System.out.println("Exception:",e);
}
}
如果我通过“/manager/userId”、“/administrator/issupurer”(或“/salesId”,我就能够获得预期的值
但是,如果要获取/requester/id(或)/requester/demographic(或)/requester/demographic/lastName,我无法获取。
我得到了空值
当我分别通过“/requester/id”(或“/requester/demographic”时,我希望出现以下情况
"requester" : [
{
"id":"1234"
},
{
"id":"1235"
}
]
"requester" : [
{
"demographic" : {
"firstName" : "hello",
"lastName" : "hai"
}
},
{
"demographic" : {
"firstName" : "welcome",
"lastName" : "user"
}
}
]
除了fetch之外,我还希望在使用JsonPointer定位这些值之后,对它们进行内联更新
我的更新代码如下所示
public String findAndUpdate(String key,String jsonString,String repValue){
String fieldNodeStr =null;
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonString);
JsonNode fieldNode = node.at(key);
//Update the value of located node to a different one
((ObjectNode) fieldNode).put(key,repValue);
fieldNodeStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(fieldNode);
System.out.println(fieldNodeStr);
} catch (IOException e) {
System.out.println("IOException:",e);
}catch (Exception e) {
System.out.println("Exception:",e);
}
return fieldNodeStr;
}
当我传递“/manager/userId”作为key的值时,我得到以下错误
17:21:24.829 [main] ERROR com.demo.jsondemo.TestClass - Exception:
java.lang.ClassCastException: com.fasterxml.jackson.databind.node.TextNode cannot be cast to com.fasterxml.jackson.databind.node.ObjectNode
at com.demo.jsondemo.TestClass.findAndUpdate(TestClass.java:95) [classes/:na]
at com.demo.jsondemo.TestClass.main(TestClass.java:221) [classes/:na]
Jackson的JsonView注释应该允许您使用特定视图标记某些字段/getter。像下面这样的方法应该可以奏效
public class Item {
public static class LoggingView {}
@JsonView(LoggingView.class)
public int id;
@JsonView(LoggingView.class)
public String name;
public byte[] data;
}
这应该允许您通过执行以下操作来写入id
和name
,而无需写入data
:
public class Something {
private static final Logger logger = LoggerFactory.getLogger();
private static final ObjectWriter loggingItemWriter = new ObjectMapper().writerWithView(Item.LoggingView.class);
public void doSomething(Item item) {
...
logger.info(loggingItemWriter.writeValueAsString(item));
...
}
}
Jackson的JsonView注释应该允许您使用特定视图标记某些字段/getter。像下面这样的方法应该可以奏效
public class Item {
public static class LoggingView {}
@JsonView(LoggingView.class)
public int id;
@JsonView(LoggingView.class)
public String name;
public byte[] data;
}
这应该允许您通过执行以下操作来写入id
和name
,而无需写入data
:
public class Something {
private static final Logger logger = LoggerFactory.getLogger();
private static final ObjectWriter loggingItemWriter = new ObjectMapper().writerWithView(Item.LoggingView.class);
public void doSomething(Item item) {
...
logger.info(loggingItemWriter.writeValueAsString(item));
...
}
}
JSON指针
您可以使用由定义的JSON指针(用于标识JSON文档中特定值的字符串语法)
例如,考虑下面的JSON:
{
“名字”:“约翰”,
“姓氏”:“能源部”,
“地址”:{
“街道”:“第二街21号”,
“城市”:“纽约”,
“postalCode”:“10021-3100”,
“坐标”:{
“纬度”:40.7250387,
“经度”:-73.9932568
}
}
}
要查询坐标
节点,可以使用以下JSON指针表达式:
<代码>/地址/坐标
JSON指针和Jackson
Jackson 2.3.0引入了对JSON指针的支持,可以如下使用:
public class Something {
private static final Logger logger = LoggerFactory.getLogger();
private static final ObjectWriter loggingItemWriter = new ObjectMapper().writerWithView(Item.LoggingView.class);
public void doSomething(Item item) {
...
logger.info(loggingItemWriter.writeValueAsString(item));
...
}
}
String json=“{\“firstName\”:“John\”,“lastName\”:“Doe\”,“address\”:{“street\”:“
+“第二街21号”“纽约市”“邮政编码”“10021-3100”“,”
+“\”坐标\“:{\”纬度\“:40.7250387,\”经度\“:-73.9932568}}”;
ObjectMapper mapper=新的ObjectMapper();
JsonNode=mapper.readTree(json);
JsonNode coordinatesNode=node.at(“/address/coordinates”);
坐标
节点可以解析为bean:
Coordinates坐标=mapper.treeToValue(Coordinates节点,Coordinates.class);
或者可以写为字符串
:
String coordinates nodeasstring=mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(协调节点);
乱穿马路
JSON指针的一个很好的替代方法是JSONPath。在Java中,有一个名为的实现,它与Jackson集成
要使用JsonPath查询坐标
节点,可以使用以下表达式:
$.address.coordinates
查询节点的代码如下所示:
JsonNode coordinatesNode=JsonPath.parse(json)
.read(“$.address.coordinates”,JsonNode.class);
JsonPath需要以下依赖项:
com.jayway.jsonpath
阅读并理解如何正确使用它。JSON指针
您可以使用由定义的JSON指针(用于标识JSON文档中特定值的字符串语法)
例如,考虑下面的JSON:
{
“名字”:“约翰”,
“姓氏”:“能源部”,
“地址”:{
“街道”:“第二街21号”,
“城市”:“纽约”,
“postalCode”:“10021-3100”,
“坐标”:{
“纬度”:40.7250387,
“经度”:-73.9932568
}
}
}
要查询坐标
节点,可以使用以下JSON指针表达式:
/地址/坐标
JSON指针和Jackson
Jackson 2.3.0引入了对JSON指针的支持,可以如下使用:
public class Something {
private static final Logger logger = LoggerFactory.getLogger();
private static final ObjectWriter loggingItemWriter = new ObjectMapper().writerWithView(Item.LoggingView.class);
public void doSomething(Item item) {
...
logger.info(loggingItemWriter.writeValueAsString(item));
...
}
}
String json=“{\“firstName\”:“John\”,“lastName\”:“Doe\”,“address\”:{“street\”:“
+“第二街21号”“纽约市”“邮政编码”“10021-3100”“,”
+“\”坐标\“:{\”纬度\“:40.7250387,\”经度\“:-73.9932568}}”;
ObjectMapper mapper=新的ObjectMapper();
JsonNode=mapper.readTree(json);
JsonNode coordinatesNode=node.at(“/address/coordinates”);
坐标
节点可以解析为bean:
Coordinates坐标=mapper.treeToValue(Coordinates节点,Coordinates.class);
或者可以写为字符串
:
String coordinates nodeasstring=mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(协调节点);
乱穿马路
JSON p的一个很好的替代方案