JSON: InvalidFormatException: Kann nicht bauen Instanz von int von String-Wert
Ich habe dieses seltsame problem, dass wenn der server erhält eine JSON über REST, Jackson versucht zu konvertieren eine Zeichenfolge in eine Ganzzahl:
BlockquoSchwerwiegend: Die Ausnahme enthaltenen MappableContainerException zugeordnet werden konnte, um eine Antwort, re-werfen, um die HTTP-container
com.fasterxml.jackson.databind-Methode.exc.InvalidFormatException: Kann nicht bauen Instanz von int von String-Wert 'vor': not a valid Integer value
[Quelle: org.apache.catalina.connector.CoyoteInputStream@3916f0; Zeile: 1, Spalte: 182] (über die Referenz-Kette: com.entities.SectionRelation["listLinkLabel"]->java.util.HashSet[0]->com.entities.LinkLabel["linkLabel"])
bei com.fasterxml.jackson.databind-Methode.exc.InvalidFormatException.aus(InvalidFormatException.java:55)
bei com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:883)
bei com.fasterxml.jackson.databind-Methode.deser.std.StdDeserializer._parseInteger(StdDeserializer.java:411)
bei com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:289)
bei com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:271)
bei com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty.deserializeSetAndReturn(ObjectIdValueProperty.java:85)
bei com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty.deserializeAndSet(ObjectIdValueProperty.java:77)
bei com.fasterxml.jackson.databind.deser.impl.BeanPropertyMap.findDeserializeAndSet(BeanPropertyMap.java:285)
bei com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:335)
bei com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithObjectId(BeanDeserializerBase.java:1045)
bei com.fasterxml.jackson.databind-Methode.deser.BeanDeserializer.Deserialisieren(BeanDeserializer.java:140)
bei com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:240)
bei com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:212)
bei com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:25)
bei com.fasterxml.jackson.databind-Methode.deser.SettableBeanProperty.Deserialisieren(SettableBeanProperty.java:523)
...
Dies ist die Einheit, wo der Fehler sein soll:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
/**
* The label name is unique and is therefore the
* primary key.
*/
@Entity
@JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "linkLabel")
public class LinkLabel implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@JsonFormat(shape = JsonFormat.Shape.STRING)
@Column(name = "LinkLabel")
@GeneratedValue(strategy = GenerationType.AUTO)
private String linkLabel;
@JsonIgnore
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinTable(
name="LINKLABEL_LINKSET",
joinColumns={@JoinColumn(name="LINKLABEL_ID", referencedColumnName="LinkLabel")},
inverseJoinColumns={@JoinColumn(name="LINK_LABEL_SET_ID", referencedColumnName="id")})
private Set<LinkSet> linkSet = new HashSet();
public String getLinkLabel() {
return linkLabel;
}
public void setLinkLabel(String linkLabel) {
this.linkLabel = linkLabel;
}
public Set<LinkSet> getLinkSet() {
return linkSet;
}
public void addLinkSet(LinkSet linkSet) {
this.linkSet.add(linkSet);
}
}
Dies ist ein Beispiel JSON, die gesendet wurde, durch den server:
{
"links": [{
"id": 2,
"section1": {
...
},
"section2": {
...
},
"listLinkLabel": [{
"linkLabel": 1,
"linkLabel": "after"
}]
}, {
"id": 5,
"section1": {
...
},
"section2": {
...
},
"listLinkLabel": [{
"linkLabel": 2,
"linkLabel": "before"
}, {
"linkLabel": 3,
"linkLabel": "overlap"
}, 1]
}, {
"id": 3,
"section1": {
...
},
"section2": {
...
},
"listLinkLabel": [3]
}
}
Dies ist den Verantwortlichen snippet des frontend:
this.addLink = function(source, target) {
var JSONTemplate = {
"id":null,
"section1":{
...
},
"section2":{
...
},
"listLinkLabel":[{
// "linkLabel": 1
// ,
"linkLabel": "before"
}]
};
$http.post('service/sectionrelation', JSON.stringify(JSONTemplate));
}
Ich sehe nicht ein, warum Jackson versucht zu konvertieren "linkLabel" "vor", um eine ganze Zahl, wenn der Typ ist definitiv ein String, sogar @JsonFormat ändert sich nichts. Nur "linkLabel": 1" weckt keine Fehler , aber es muss doch eine Möglichkeit nur senden ""linkLabel": "vor"". Dies scheint ziemlich einfach und einfach zu mir, denn dies ist die normale Darstellung der Entität.
In der pom.xml Jackson verwendet 2.6.3 und GlassFish 4.1 ist der application server.
InformationsquelleAutor Rooky | 2016-01-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie zwei Attribute namens "linkLabel" in jedem der JSON-Objekte. Attribut-Namen in ein JSON-Objekt werden einzigartig, wenn Sie wollen, dass Sie ordnungsgemäß extrahiert, indem eine standard-JSON-parser.
Was passieren wird ist, dass eines der Attribute werden ignoriert (im hintergrund), die durch den JSON-parser. Zum Beispiel:
Unter der Annahme, dass das erste Attribut wird ignoriert, Ihr code wird dann versuchen, zu konvertieren
"after"
eine Ganzzahl ... das wird scheitern.Im Grunde, Sie Ihre JSON ist (semantisch) fehlerhaft ist, und Sie brauchen, um zu korrigieren, was es erzeugt.
UPDATE - ich glaube, ich habe herausgefunden, warum Jackson generiert malformed JSON. Sie haben:
und auch
In anderen Worten, Sie haben erzählt Jackson, dass 1) es wird ein id-Attribut mit dem Typ
int
und NamenlinkLabel
, 2) es gibt eine Eigenschaft namenslinkLabel
deren TypString
.Jackson hat sich mittlerweile ein bisschen verwirrt durch diese widersprüchlichen Angaben, und davon ausgegangen, dass Sie angegeben haben, gibt es zwei verschiedene Attribute genannt
linkLabel
... das funktioniert nicht1.Du auch >>angezeigt<<, zu versuchen, zu verwenden
linkLabel
als Daten-Feld (mit nicht-integer-Inhalte) und das ist auch problematisch2.Lösung: entweder loszuwerden, die
@JsonIdentityInfo
annotation zu ändern, oder Sie verwenden ein verschiedene Eigenschaft name, und deklarieren Sie die entsprechenden Java-Feld mit dem korrekten Java-Typ.1 - Es funktioniert nicht mit dem Jackson-parser ... aber könnten Sie es mit einer benutzerdefinierten parser. Daher gibt es eine (dürftige) Begründung für Jackson, um dies zu tun, anstatt behandeln dies als ein Fehler.
2 - Es gibt keine Möglichkeit, dass Jackson könnte diese Figur ein ...
"listLinkLabel":[{ // "linkLabel": 1 // , "linkLabel": "before" }]
enthalten war, zu zeigen, dass die kommentierte und unkommentierte Lösung funktioniert nicht, nur " "linkLabel": 1", was keinen Sinn machtdie JSON gelesen werden kann, aber mit duplicate keys zu führen, dass viele Probleme vermeiden, es sei denn, Sie möchten zur-hand-code-parser als gut. Die Fehlermeldung, die Sie anführen, ist keine überraschung und absolut sinnvoll. "linkLabel" bestimmt wird, die Objekt-ID und ist definiert als eine ganze Zahl.
Ich danke Ihnen sehr, Sie sind genial! Ich dachte, das ist normal json-standard zum speichern von Zeichen.
InformationsquelleAutor Stephen C
Wenn Sie mit Google Endpunkte Rahmen: vergewissern Sie Sich, dass alle angegebenen Parameter im @Api-annotation @Named sind einzigartig, unabhängig von allen anderen Objekten übergeben, die als Teil des Körpers. Wenn Sie die @Named-parameter "id" und haben auch ein Objekt mit den gleichen parameter Endpunkte verwirrt.
Dies scheint ein bug in den Endpunkten, die Umsetzung der Spezifikation sollte unterscheiden zwischen serialisiert die Werte in den Pfad und in den Körper: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameter-object
Zum Beispiel, wenn Sie haben:
Sehen Sie Ihre Endgeräte-server werfen:
Endpunkte Rahmen sieht die @Named("id") thingId Feld und de-Serialisierung in MyData, die nicht pro-spec oder gewünscht ist. Einfach re-naming wird der parameter fix: @Named("thingId") thingId.
InformationsquelleAutor Chris