Ich habe das seltsame Problem, dass Jackson versucht, einen String in eine Ganzzahl umzuwandeln, wenn der Server einen JSON über REST empfängt:
BlockquoSchwerwändig: Die in MappableContainerException enthaltene Ausnahme konnte keiner Antwort zugeordnet werden, die erneut in den HTTP-Container com.fasterxml.jackson.databind.exc.InvalidFormatException geworfen wurde: Instanz von int kann nicht aus dem String-Wert 'before' erstellt werden: keine gültige Ganzzahliger Wert bei [Quelle: org.apache.catalina.connector.CoyoteInputStream@3916f0; Zeile: 1, Spalte: 182] (über die Referenzkette: com.entities.SectionRelation ["listLinkLabel"] -> java.util.HashSet [0] -> com.entities.LinkLabel ["linkLabel"]) bei com.fasterxml .jackson.databind.exc.InvalidFormatException.from (InvalidFormatException.java:55) unter com.fasterxml.jackson.databind.DeserializationContext.weirdStringException (DeserializationContext.java:883) unter com.fasterxml.jackd.d ._parseInteger (StdDeserializer.java:
Dies ist die Entität, in der 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 für JSON, das vom Server gesendet wurde:
{
"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 der verantwortliche Ausschnitt des Frontends:
this.addLink = function(source, target) {
var JSONTemplate = {
"id":null,
"section1":{
...
},
"section2":{
...
},
"listLinkLabel":[{
// "linkLabel": 1
// ,
"linkLabel": "before"
}]
};
$http.post('service/sectionrelation', JSON.stringify(JSONTemplate));
}
Ich verstehe nicht, warum Jackson versucht, "linkLabel" "vor" in eine Ganzzahl umzuwandeln, wenn der Typ definitiv ein String ist, ändert auch @JsonFormat nichts. Nur "" linkLabel ": 1" ruft keine Fehler hervor, es muss jedoch die Möglichkeit bestehen, nur "" linkLabel ":" before "" zu senden. Dies scheint mir ziemlich einfach und einfach zu sein, da dies die normale Darstellung der Entität ist.
In der pom.xml wird Jackson 2.6.3 verwendet und GlassFish 4.1 ist der Anwendungsserver.
Sie haben zwei Attribute namens "linkLabel" in jedem der JSON-Objekte. Attributnamen in einem JSON-Objekt müssen eindeutig sein, wenn sie von einem Standard-JSON-Parser korrekt extrahiert werden sollen.
Was passieren wird, ist, dass eines der Attribute vom JSON-Parser (stillschweigend) ignoriert wird. Zum Beispiel:
"listLinkLabel": [{
"linkLabel": 1,
"linkLabel": "after"
}]
Angenommen, das erste Attribut wird ignoriert, dann versucht Ihr Code, "after"
in eine Ganzzahl zu konvertieren ... was fehlschlägt.
Grundsätzlich ist Ihr JSON (semantisch) fehlerhaft und Sie müssen korrigieren, was auch immer es generiert.
UPDATE - Ich glaube, ich habe herausgefunden, warum Jackson fehlerhaften JSON generiert. Du hast:
@JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "linkLabel")
und auch
@Column(name = "LinkLabel")
@GeneratedValue(strategy = GenerationType.AUTO)
private String linkLabel;
Mit anderen Worten, Sie haben Jackson gesagt, dass 1) es ein ID-Attribut mit Typ int
und Name gibt linkLabel
, 2) es eine Eigenschaft mit dem Namen gibt, linkLabel
deren Typ ist String
.
Jackson ist durch diese widersprüchlichen Informationen etwas verwirrt und hat angenommen, dass Sie angegeben haben, dass es zwei unterschiedliche Attribute gibt, die als linkLabel
... bezeichnet werden und nicht funktionieren 1 .
Sie >> scheinen auch << zu versuchen, linkLabel
als Datenfeld (mit nicht ganzzahligem Inhalt) zu verwenden, und das ist auch problematisch 2 .
Lösung: Entfernen Sie entweder die @JsonIdentityInfo
Anmerkung oder ändern Sie sie, um einen eindeutigen Eigenschaftsnamen zu verwenden, und deklarieren Sie das entsprechende Java-Feld mit dem richtigen Java-Typ.
1 - Es funktioniert nicht mit dem Jackson-Parser ... aber Sie können es mit einem benutzerdefinierten Parser zum Laufen bringen. Daher gibt es eine (schwache) Rechtfertigung für Jackson, dies zu tun, anstatt dies als Fehler zu behandeln.
2 - Jackson kann das auf keinen Fall herausfinden ...
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen