Im Prozess der Webentwicklung ist die Dateninteraktion unverzichtbar, wodurch das relevante Format interaktiver Daten angegeben werden muss, damit Daten zwischen dem Client und dem Server übergeben werden können. Es gibt normalerweise zwei Arten von Datenformaten: 1. XML; 2. JSON. Im Allgemeinen wird JSON verwendet, um Daten zu übergeben. In diesem Artikel werden mehrere Probleme eingeführt, die beim Konvertieren von JSON und Objekten in Java und verwandten Vorschlägen auftreten.
Erstens haben wir zwei Konzepte für JSON:
JSON -Objekt (JavaScript -Objektnotation, JavaScript -Objektnotation). Dies scheint ein benutzerdefiniertes JavaScript-Bit zu sein, aber es ist Sprach- und Plattformspezifische als Syntax. Dies bedeutet nur, dass wir normalerweise, wenn wir Daten an die Serverseite (Browser) übergeben, JSON -Format verwenden, und dieses Format wird verwendet, um JavaScript -Objekte darzustellen. Es besteht aus einer Reihe von "Schlüsselwerten", wie {"ID": 1, "Name": "Kevin"}, was der Art und Weise, wie Kartenschlüsselwertepaare gespeichert sind, etwas ähnlich ist. Das in Java beschriebene JSON-Objekt bezieht sich tatsächlich auf die JSONObject-Klasse, die normalerweise in jedem Jsonjar-Paket von Drittanbietern nach diesem Namen benannt ist. Verschiedene JAR -Pakete haben leicht unterschiedliche interne Implementierungen.
Json String. Die Umwandlung zwischen JSON -Objekten und JSON -Zeichenfolgen ist ein Prozess der Serialisierung und Deserialisierung, der wie die Serialisierung und Deserialisierung von Java -Objekten entspricht. Die Datenübertragung im Netzwerk wird über Zeichenfolgen oder binäre Streams usw. durchgeführt. Wenn der Client (Browser) Daten im JSON -Format übergeben muss, wird die Zeichenfolge zum Zeitpunkt des Netzwerks über das Netzwerk weitergegeben, und die Serverseite hat natürlich auch eine Zeichenfolge (String -Typ) nach Empfangen der Daten. Manchmal ist es notwendig, die JSON -String in ein JSON -Objekt umzuwandeln und dann den nächsten Vorgang auszuführen (der String -Typ wird in den JSONObject -Typ konvertiert).
Die beiden oben genannten Konzepte klären im Grunde das Datenformat von JSON oder auch als JSON -Syntax bezeichnet. Es gibt viele JAR -Pakete für JSON in Java. Das "am häufigsten verwendete" ist das von "net.sf.json" bereitgestellte JAR -Paket. Dieser Artikel konzentriert sich auf dieses Grubenpaket. Obwohl es sich um Grube handelt, hat es eine Vielzahl von Anwendungen. Tatsächlich gibt es andere hervorragende JSON -Pakete, die wir verwenden können, wie Fastjson, das Alibaba als das schnellste JSON -Paket, Google's GSON und Jackson, behauptet. Versuchen Sie, das Paket "net.sf.json" zu verwenden. Es gibt nicht nur Fallstricke, sondern auch sehr alt, so alt, dass er den Quellcode in der Idee nicht herunterladen kann. Das Maven -Repository zeigt, dass es 2010 in Version 2.4 gestoppt wurde. Lassen Sie uns über die beiden Fehler sprechen, die ich bereits über "net.sf.json" und darüber, wie diese beiden Fehler generiert wurden, bereits kenne.
JSON PIT -Paket in Java - net.sf.json
1. Wenn Java -Objekte JSON -Objekte konvertieren, werden alle Methoden mit GET konvertiert.
Was bedeutet dies, dass beispielsweise die folgenden Java -Objekte verfügbar sind.
Paket SFJSON; Import Java.util.List;/*** Erstellt von Kevin unter 2017/12/1. */public Class Student {private int id; Private List <Long> curistIds; public int getid () {return id; } public void setId (int id) {this.id = id; } public list <Long> getCourseIds () {return curtsIds; } public void setCourseIds (Liste <Long> curistIds) {this.CourseIds = curtsIds; } public String getQl () {// Die Methode, um SQL -Anweisungen in dieser Klasse zu erhalten, hat nicht die entsprechende Attributfeldrendite "Dies ist SQL."; }}Wenn wir ein Schülerobjekt in JSON -Objekt konvertieren, hoffen wir, dass das konvertierte JSON -Format sein sollte:
{"ID": 1, "CursIds": [1, 2, 3]}Das Ergebnis nach der Umwandlung des JSONObject json = jsonObject.fromObject (Student); API ist:
Mit anderen Worten, es kann vermutet werden, dass "net.sf.json" die Methode erhält, die mit dem öffentlichen Modifikator in Java -Objekt startet und sein Suffix als "Schlüssel" des JSON -Objekts definiert und den Rückgabewert der Methode definiert, die mit dem GET als "Wert" des entsprechenden Schlüssels beginnt. Beachten Sie, dass es die Methode ist, die mit dem öffentlichen Modifikator beginnt und einen Rückgabewert hat.
Ich denke, dies ist eine unangemessene Konversionsregel. Wenn ich eine Methode in einem Java -Objekt definiere und nur weil diese Methode mit "GET" beginnt und einen Rückgabewert hat, wird sie ausgesetzt? Oder ist es der Front-End-Konsole-Konsole ausgesetzt, wenn sie an den Client zurückgegeben wird (Browser)? Der Autor sieht diese Konversionsregel vor. Der grobe Grund ist der Grund: Da Sie es als öffentliche Methode definieren und sie erhalten, enthält dies absichtlich diese Methode, damit der Kunden das Recht hat, sie zu erhalten. Aber ich denke immer noch, dass dies unangemessen ist, und selbst ich definiere es als Fehler. Es ist für mich vielleicht nicht vernünftig, diese Weise zu definieren, da nach meinem tatsächlichen Test nicht nur das Paket "net.sf.json" nach dieser Regel konvertiert wird, sondern Fastjson und Jackson auch dieser Regel folgen, aber Googles GSON von Google konvertiert keine Objekte nach dieser Regel in JSON.
Konvertieren Sie das konstruierte Studentenobjekt in ein JSON -Objekt über JSONObject JSON = jsonObject.fromObject (Student); und der Schüler ist wie oben beschrieben. Nach der Eingabe dieser Methode wird die überlastete Methode FromObject (Object, JsonConfig) weiterhin aufgerufen. In dieser überladenen Methode wird Instanz von verwendet, um festzustellen, ob das zu konvertierte Objektobjekt Aufzählung, Annotation und andere Typen ist. Diese besonderen Typen haben spezielle Beurteilungsmethoden. Hier ist ein gewöhnliches Java -Pojo -Objekt, sodass es _fromObject (Object, JsonConfig) eingibt, und es wird einige Urteile in dieser Methode geben, und schließlich wird das JSON -Objekt durch Aufrufen von DefaultBeanprocessing erstellt. Diese Methode ist der Schlüssel und wird weiterhin die "Eigenschaft Descriptor" über Propertyutils.getPropertyDescriptors (Bean) -Methode erhalten. Tatsächlich soll die Methode mit GET erhalten werden, das hier als PropertyDescriptor eingekapselt ist. Diese Schülerklasse wird 4 erhalten, nämlich: GetClass, getid, getCourseids, getQl.
Tatsächlich ist PropertyDescriptor im Detail eingekapselt, und alle Lese- und Schreibmethoden wurden zugewiesen.
Beispielsweise wurde diese GETQL -Methode in der obigen Abbildung in den PropertyDescriptor analysiert. Das Folgende ist durch diese Klasse einige Methoden herausgefiltert. Beispielsweise ist die GetClass -Methode keine Methode in Pojo, daher muss sie nicht in ein JSON -Objekt konvertiert werden. Der PropertyDescriptor wird über BeanInfo#getPropertyDescriptors erhalten, und der BeanInfo wird über einen neuen Introspector (BeanClass, Null, Use_All_BeanInfo) .getBeanInfo () erhalten; Und dann werden Sie endlich die folgende Methode erreichen.
private beanInfo getBeanInfo () löst introspectiveException {… methodDescriptor mds [] = GetTargetMethodinfo (); // Diese Methode nennt GetPublicDeclaredMethods. Sie können sehen, dass es in der Tat nach öffentlichen Methoden und allen öffentlichen Methoden sucht, einschließlich Wait und anderen PropertyDescriptors PDS [] = GetTargetPropertyInfo (); // nach bestimmten Regeln filtern. Die Filterregeln befinden sich alle in dieser Methode, bei der die Methode ausgewählt wird, bei der der öffentliche Modifikator ein GET -Präfix und einen Rückgabewert hat ...Ich habe kurz den Quellcode von net.sf.json analysiert und festgestellt, dass der spezifische Quellcode im Raum relativ groß und begrenzt ist und von mir selbst betrachtet und verfolgt werden muss.
2. Beim Konvertieren eines Java -Objekts in ein JSON -Objekt tritt ein Konvertierungsfehler in der Liste <Long> auf
Der Titel kann in einem Satz nicht klar erklärt werden, und ich bin mir sehr sicher, dass dieses Problem ein Fehler ist.
Jetzt gibt es eine JSON -Zeichenfolge von {"id": 1, "curseIds": [1,2,3]}, und es muss in das oben erwähnte Schülerobjekt konvertiert werden. Es gibt zwei Attributfelder vom Typ Int und List <Long> im Student -Objekt, was bedeutet, dass diese JSON -Zeichenfolge in den entsprechenden Datentyp konvertiert werden sollte.
String json = "{/" id/": 1,/" coursIds/": [1,2,3]}"; Student Student = (Student) jsonObject.tobean (jsonObject.fromObject (json), student.class);Die obige Ausgabe sollte wahr sein, aber leider ist es falsch. Um genau zu sein, ist es in der Kompilierzeit lang, aber integer zur Laufzeit. Es muss gesagt werden, dass dies eine Gefahr sein muss, und keiner der anderen drei JSON -Pakete hat einen solchen Fehler. Ich bin mir also sicher, dass es ein Fehler ist. Mal sehen, wie dieser Fehler in net.sf.json vorkommt. Sie müssen auch den Quellcode selbst vergleichen, um ihn anzuzeigen. Während ich das Breakpoint -Debug ständig vertiefte, stellte ich fest, dass ich diese Methode nummerutils#CreateNumber entdeckte, als ich Net.sf.json verarbeitete. Diese Klasse beurteilt seinen Datentyp beim Extrahieren von Daten aus einer Zeichenfolge. Die ursprüngliche Absicht ist es, die Zahl so lange zu verarbeiten, wenn sie danach "l" oder "L" hat. Aus dieser Sicht sollte das Endergebnis korrekt sein.
case 'l': case 'l': if (dec == null && exp == null && (numeric.charat (0) == '-' && isDigits (numeric.substring (1)) || isDigits (numerisch)) {trink {return createlong (numerisch); } catch (numberFormatexception var11) {return createBigInteger (numerisch); }} else {town numnformatexception (str + "ist keine gültige Nummer."); }In der Tat hat Net.sf.json bisher den Datentyp nach der Nummer genau beurteilt. Das Problem liegt in der Tatsache, dass nach Erhalt dieses Wertes und dessen Datentyp es in JSONObject gespeichert werden muss. Die Methode JsonUtils#TransformNumber existiert während des Speichervorgangs. Die Existenz dieser Methode ist in der aktuellen Ansicht zumindest rein extravagant.
public static number transformNumber (number input) {if (inputinstanceof float) {return New Double (input.toString ()); } else if (inputinstance von kurz) {neu integer zurückgeben (input.intValue ()); } else if (inputinstanceof byte) {neu integer zurückgeben (input.intValue ()); } else {if (inputinstance von lang) {long max = new Long (2147483647L); if (input.longValue () <= max.longValue () && input.longValue ()> = -2147483648l) {// Auch wenn der ursprüngliche Typ lang ist, so lange er sich innerhalb der Ganzzahl -Reichweite befindet, wird er schließlich in Ganzzahl konvertiert. Neue Integer zurückgeben (input.intValue ()); }} return Input; }}Der obige Code zeigt deutlich den Täter, ob es sich um den langen Typ handelt (der lange Typ innerhalb des Ganzzahlbereichs), einschließlich Byte und Short, er wird in Ganzzahl umgewandelt. Ich verstehe nicht, was die Bedeutung dieses Code ist. Der genaue Datentyp muss basierend auf den Buchstaben nach der Nummer ermittelt werden, und der genaue Datentyp muss später erneut konvertiert werden, was zu dem zu Beginn erwähnten Fehler führt. Dieses Problem ist fast unvermeidlich, daher ist es der beste Weg, es nicht zu verwenden.
Diese beiden Fallstricke wurden zufällig entdeckt. Es wird empfohlen, das JSON -Paket von Net.sf.json nicht zu verwenden, das nicht aufrechterhalten wurde. Darüber hinaus ist das Paket net.sf.json bei der Überprüfung des JSON -Formats nicht so streng. Wenn ein solches Format "{" ID ": 1," CursIDs "ist:" [1,2,3] "}", wird in den anderen drei Paketen eine Ausnahme ausgelöst, aber net.sf.json wird es nicht.
In dem obigen Artikel werden die Fallstricke von JSON und Objekttransfer in Java im Detail erläutert. Dies ist der gesamte Inhalt, den ich mit Ihnen teile. Ich hoffe, es kann Ihnen eine Referenz geben und ich hoffe, Sie können Wulin.com mehr unterstützen.