Разбор JSON

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
Коллеги, подскажите пожалуйста, есть ли в стандартных либах в ext что-то по теме? А то неохота тянуть зависимости.
 

oshmianski

Достойный программист
Lotus Team
25.04.2012
711
59
BIT
8
 
Последнее редактирование модератором:

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
The import com.ibm.commons cannot be resolved

Нет такого в ext.
 

oshmianski

Достойный программист
Lotus Team
25.04.2012
711
59
BIT
8
Java:
import com.ibm.commons.util.io.json.JsonException;
import com.ibm.commons.util.io.json.JsonJavaObject;
import com.ibm.commons.util.io.json.util.JsonWriter;

У меня много где это нормально импортится. Может оно не в ext, но есть точно. 9.0.Х.
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
528
я бы внешний взял, с учетом передачи ibm -> hcl.
сами gson используем
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
У меня много где это нормально импортится. Может оно не в ext, но есть точно. 9.0.Х.
Возможно из экспэйджэвской джавы вызовы. Иначе не подтягивает.

сами gson используем
Буду Jackson использовать, у нас все на нём.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
я поэтому gson и взял, у нас файлы маленькие.
А у нас в одном сервисе надо разобрать один большой, а в остальных по одному маленькому. А т.к. на одном маленьком файле разницы особой нет (разница есть на множестве маленьких), то остановился на Jackson.
 
  • Нравится
Реакции: savl

rinsk

Lotus Team
12.11.2009
1 156
126
BIT
43
Юзаю ralfstx/minimal-json
все устраивает.
для LS2J наваял враппер типа:
Java:
//https://github.com/ralfstx/minimal-json
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;

//import com.eclipsesource.json.JsonObject.Member;

public class RinsJson {
    public JsonObject jObject;

    private RinsJson() { //
        parse("{}");
    }

    public void parse(String jstr) {
        jObject = Json.parse(jstr).asObject();
    }

    // @Override
    public String toString() {
        return jObject.toString();
    }

    public void setArrayString(String key, String values[]) {
        JsonArray jArray = Json.array(values);
        JsonValue jValue = new JsonArray(jArray);
        jObject.set(key, jValue);
    }

    public void addArrayString(String key, String values[]) {
        JsonArray jArray = Json.array(values);
        JsonValue jValue = new JsonArray(jArray);
        jObject.add(key, jValue);
    }

    public String[] getArrayString(String key) {
        String[] retnull = new String[1];
        retnull[0] = "";
        if (jObject.get(key) != null) {
            JsonArray jArray = jObject.get(key).asArray();
            int size = jArray.size();
            if (size == 0) {
                return retnull;
            }
            ;
            String[] ret = new String[size];
            for (int k = 0; k < size; k++) {
                if (jArray.get(k).isString()) {
                    ret[k] = jArray.get(k).asString();
                } else {
                    ret[k] = jArray.get(k).toString();
                }
            }
            return ret;
        } else {
            return retnull;
        }
    }

    public void addObject(String key, String value) {
        JsonObject jObj = Json.parse(value).asObject();
        jObject.add(key, jObj);

    }
    
    public void addArray(String key, String value) {
        JsonArray jObj = Json.parse(value).asArray();
        jObject.add(key, jObj);
    }

    public void setNumber(String key, double value) {
        jObject.set(key, value);
    }

    public void addNumber(String key, double value) {
        jObject.add(key, value);
    }
    
    public JsonValue get(String key) {
        return jObject.get(key);
    }

    public JsonObject getObject() {
        return jObject;
    }
    public boolean isKeyExist(String key) {
        return (jObject.get(key) != null);
    }

    public int getValueType(String key) {
        JsonValue value = jObject.get(key);
        if (value.isArray()) {
            return 1;
        }
        ; // isArray
        if (value.isBoolean()) {
            return 2;
        }
        ; // isBoolean
        if (value.isNumber()) {
            return 3;
        }
        ; // isNumber
        if (value.isString()) {
            return 4;
        }
        ; // isString
        if (value.isObject()) {
            return 5;
        }
        ; // isObject
        return -1;
    }

    public String[] getKeyNames() {
//        if (jObject.names().size() == 0) {
//            String[] ret = { "" };
//            return (ret);
//        }
//        ;
//        return jObject.names().toArray(new String[0]);
        int size=jObject.names().size();
        if (size == 0) {
            String[] retnull = new String[1];
            retnull[0] = "";           
            return (retnull);
            };
        String[] ret = new String[size];
        for (int k = 0; k < size; k++) {
            ret[k]=jObject.names().get(k).toString();
        }
        return ret;
    }

    // @Override
    protected void finalize() throws Throwable {
        // super.finalize();
        jObject = null;
    }
}
 
  • Нравится
Реакции: VladSh

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
Jackson
Java class -> JSON.

Сначала попробовал сгенерить Java-классы по swagger'у но там такая ахинея получилась (налеплено куча ненужных методов и аннотаций для универсальной совместимости до всеми Json-движками), что пришлось удалить и самому разобраться в аннотациях для Jackson.

Итак...
JSON:
{
  "amount": 3552,
  "code_nbu": "45454545454",
  "credit_account": "257486579679.EUR",
  "currency": "EUR",
  "debit_account": "56756856.EUR",
  "narrative": "NARRATIVE",
  "order_num": "1",
  "receiver": {
    "account": "0101010101/01",
    "bank": {
      "code": "RBANKCODE",
      "name": "RBANKNAME"
    },
    "code": "RCODE",
    "name": "RNAME"
  },
  "sender": {
    "bank": {
      "code": "SBANKCODE",
      "name": "SBANKNAME"
    },
    "name": "SNAME"
  },
  "value": "2019-12-03"
}

Java:
import com.fasterxml.jackson.annotation.JsonProperty;

public class Bank {
    @JsonProperty("code")
    protected String code;
    @JsonProperty("name")
    protected String name;
    
    Bank (String code, String name) {
        this.code = code;
        this.name = name;
    }
}
Java:
import com.fasterxml.jackson.annotation.JsonProperty;

public class Sender {
    @JsonProperty("bank")
    protected Bank bank;
    @JsonProperty("name")
    protected String name;
    
    Sender(Bank bank, String name) {
        this.bank = bank;
        this.name = name;
    }
}
Java:
import com.fasterxml.jackson.annotation.JsonProperty;

public class Receiver extends Sender {
    @JsonProperty("account")
    protected String account;
    @JsonProperty("code")
    protected String code;
    
    Receiver(Bank bank, String name) {
        super(bank, name);
    }
    
    public void setAccount(String account) {
        this.account = account;
    }
    
    public void setCode(String code) {
        this.code = code;
    }
}
Java:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Date;

public class NbuDocument {
    @JsonProperty("amount")
    protected double amount;
    @JsonProperty("code_nbu")
    protected String code_nbu;
    @JsonProperty("credit_account")
    protected String credit_account;
    @JsonProperty("currency")
    protected String currency;
    @JsonProperty("debit_account")
    protected String debit_account;
    @JsonProperty("narrative")
    protected String narrative;
    @JsonProperty("order_num")
    protected String order_num;
    @JsonProperty("receiver")
    protected Receiver reseiver;
    @JsonProperty("sender")
    protected Sender sender;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    protected Date value;
    
    public NbuDocument(Receiver reseiver, Sender sender) {
        this.reseiver = reseiver;
        this.sender = sender;
    }
    
    public void setAmount(double amount) {
        this.amount = amount;
    }
    
    public void setCodeNbu(String code_nbu) {
        this.code_nbu = code_nbu;
    }
    
    public void setCreditAccount(String credit_account) {
        this.credit_account = credit_account;
    }
    
    public void setCurrency(String currency) {
        this.currency = currency;
    }
    
    public void setDebitAccount(String debit_account) {
        this.debit_account = debit_account;
    }
    
    public void setNarrative(String narrative) {
        this.narrative = narrative;
    }
    
    public void setOrderNum(String order_num) {
        this.order_num = order_num;
    }
    
    public void setDate(Date date) {
        this.value = date;
    }
}
Тест:
Java:
import java.util.Date;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestClassToJson {
    public void run() throws JsonProcessingException {
        Receiver receiver = new Receiver(new Bank("RBANKCODE", "RBANKNAME"), "RNAME");
        receiver.setAccount("0101010101/01");
        receiver.setCode("RCODE");
        Sender sender = new Sender(new Bank("SBANKCODE", "SBANKNAME"), "SNAME");
        NbuDoc doc = new NbuDoc(receiver, sender);
        doc.setAmount(3552);
        doc.setCodeNbu("45454545454");
        doc.setCreditAccount("257486579679.EUR");
        doc.setCurrency("EUR");
        doc.setDebitAccount("56756856.EUR");
        doc.setNarrative("NARRATIVE");
        doc.setOrderNum("1");
        doc.setDate(new Date());
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(doc));
    }
}
На серваке FP8 бились ошибки, добавил в java.policy:
Java:
grant {
// ...

// for Jackson
      permission java.lang.RuntimePermission "accessDeclaredMembers";
      permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};
Всё завелось. На сервере.
А на клиенте при добавлении этих же строк всё равно та же ошибка:
03.12.2019 12:33:13 Agent error: java.security.AccessControlException: Access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")
03.12.2019 12:33:13 Agent error: at java.security.AccessController.throwACE(AccessController.java:157)
03.12.2019 12:33:13 Agent error: at java.security.AccessController.checkPermissionHelper(AccessController.java:217)
03.12.2019 12:33:13 Agent error: at java.security.AccessController.checkPermission(AccessController.java:349)
03.12.2019 12:33:13 Agent error: at java.lang.SecurityManager.checkPermission(SecurityManager.java:562)
03.12.2019 12:33:13 Agent error: at lotus.notes.AgentSecurityManager.checkPermission(Unknown Source)
03.12.2019 12:33:13 Agent error: at java.lang.Class.checkMemberAccess(Class.java:200)
03.12.2019 12:33:13 Agent error: at java.lang.Class.getDeclaredFields(Class.java:823)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.util.ClassUtil.getDeclaredFields(ClassUtil.java:1113)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector._findFields(AnnotatedFieldCollector.java:66)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector.collect(AnnotatedFieldCollector.java:41)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.introspect.AnnotatedFieldCollector.collectFields(AnnotatedFieldCollector.java:36)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.introspect.AnnotatedClass._fields(AnnotatedClass.java:349)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.introspect.AnnotatedClass.fields(AnnotatedClass.java:321)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addFields(POJOPropertiesCollector.java:379)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:308)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getJsonValueAccessor(POJOPropertiesCollector.java:196)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findJsonValueAccessor(BasicBeanDescription.java:252)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.findSerializerByAnnotations(BasicSerializerFactory.java:346)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:216)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:165)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1388)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1336)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:510)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:713)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:308)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:4094)
03.12.2019 12:33:13 Agent error: at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3404)
03.12.2019 12:33:13 Agent error: at TestClassToJson.run(Unknown Source)
03.12.2019 12:33:13 Agent error: at JavaAgent.main(JavaAgent.java:31)
Подскажите, коллеги, можно ли как-то поправить?
 

oshmianski

Достойный программист
Lotus Team
25.04.2012
711
59
BIT
8
А если указать "read"?

permission java.lang.RuntimePermission "accessDeclaredMembers", "read";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks", "read";
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
Не помогает. "write" тоже пробовал. Похоже ему всё равно, хоть добавляй, хоть нет.

У меня файл здесь лежит: ...\IBM\Notes\java.policy
правильно? /других файлов таких нет/
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
Jackson, ч.2
JSON -> Java-объект
JSON:
{
   "access_token": "абракадабра-1",
   "expires_in": 300,
   "refresh_expires_in": 1800,
   "refresh_token": "абракадабра-2",
   "token_type": "bearer",
   "not-before-policy": 0,
   "session_state": "913ec75e-3a62-47d9-8a34-78a661fe14e0",
   "scope": ""
}
Java:
import java.io.Serializable;

public class OAuthToken implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private String tokenType;
    private String accessToken;
    private long expiresIn;
    private String refreshToken;
    private long refreshExpiresIn;
    
    public String getTokenType() {
        return tokenType;
    }
    
    public String getAccessToken() {
        return accessToken;
    }
    
    public long getExpiresIn() {
        return expiresIn;
    }
    
    public String getRefreshToken() {
        return refreshToken;
    }
    
    public long getRefreshExpiresIn() {
        return refreshExpiresIn;
    }
}
Java:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.annotation.JsonInclude;

public class TestJsonToClass {
    public void run(String json) throws JsonMappingException, JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        OAuthToken token = mapper.readValue(json, OAuthToken.class);

        System.out.println("token_type = " + token.getTokenType());
        System.out.println("access_token = " + token.getAccessToken());
        System.out.println("expires_in = " + token.getExpiresIn());
        System.out.println("refresh_token = " + token.getRefreshToken());
        System.out.println("refresh_expires_in = " + token.getRefreshExpiresIn());
    }
}
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
Юзаю ralfstx/minimal-json
все устраивает.
для LS2J наваял враппер типа...
Мои предшественники для простых случаев использовали LS-класс JSONReader и его спутники от Troy Reimer (когда-то выкладывался на OpenNTF), а для сложных случаев писали весь код на Java.
Сейчас столкнулся с тем, что упомянутый LS-класс не работает с вложенными объектами... Оказалось, Дима выложил свою LS-библиотеку, которая гораздо меньше по размеру и прекрасно работает с вложенными объектами и массивами! Реально круто!

Добавлено: сейчас допиливаю. Выложу, как будет готово.
 
Последнее редактирование:

rinsk

Lotus Team
12.11.2009
1 156
126
BIT
43
Мои предшественники для простых случаев использовали LS-класс JSONReader и его спутники от Troy Reimer (когда-то выкладывался на OpenNTF), а для сложных случаев писали весь код на Java.
Сейчас столкнулся с тем, что упомянутый LS-класс не работает с вложенными объектами... Оказалось, Дима выложил свою LS-библиотеку, которая гораздо меньше по размеру и прекрасно работает с вложенными объектами и массивами! Реально круто!

Добавлено: сейчас допиливаю. Выложу, как будет готово.
Интересно посмотреть...
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
Интересно посмотреть...
LSJsonParser. Пользоваться тоже можно)

Добавлено: Хотел ещё JSONObject переименовать в JSONList, а в JSONObject перенести общие методы и сделать его базовым классом, но пока оставил так, для обратной совместимости.
 
Последнее редактирование:

rinsk

Lotus Team
12.11.2009
1 156
126
BIT
43
Пара вопросов:
- на скорость парсинга не проверялось, по сравнению с реализацией на java\Ls2J ?
- есть планы по реализации метода .toJsonString ?
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!