java - Jackson, howto deserialize fields with custom name? -


i try deserialize jira issues rest api object. thats quite straight forward. struggle mapping custom field in jira onto property. i've tried using custom deserializer not "kick in".

this how json rest call looks like: (some parts stripped)

{   "expand": "renderedfields,names,schema,...",   "id": "53899",   "key": "dpt-12",   "fields": {     "issuetype": {       "id": "10001",       "name": "story",       "subtask": false     },     "timespent": null,     "project": {       "id": "10823",       "key": "dpt"     },     "fixversions": [],     "customfield_10111": null,     "aggregatetimespent": null,     "resolution": null,     "customfield_10112": null,     "customfield_10700": [       "entwicklung-w"     ],     "customfield_10304": null,     "resolutiondate": null,     "lastviewed": "2017-04-04t14:34:19.868+0200",     "created": "2017-02-02t12:01:31.443+0100",     "priority": {       "name": "schwer",       "id": "10001"     },     "assignee": {       "displayname": "me :-)"     },     "updated": "2017-04-04t14:34:19.710+0200",     "status": {       "iconurl": "https://jira.mobi.ch/",       "name": "backlog",       "statuscategory": {         "name": "aufgaben"       }     },     "summary": "ereignisse in rocket chat schreiben",     "creator": {       "displayname": "me :-)"     },     "reporter": {       "displayname": "me :-)"     }   } } 

the custom field name configured in application ("customfield_10700") , want map on property:

private set<string> deploymentenvironments; 

so here relevant dto's , test class (getters , setter stripped here).

test:

import static org.hamcrest.collection.iscollectionwithsize.hassize; import static org.hamcrest.collection.isemptycollection.empty; import static org.hamcrest.core.is.is; import static org.hamcrest.core.isnot.not; import static org.hamcrest.core.isnull.nullvalue; import static org.junit.assert.assertthat;  import java.io.ioexception; import java.net.urisyntaxexception; import java.nio.file.files; import java.nio.file.paths; import java.util.set;  import com.fasterxml.jackson.databind.module.simplemodule; import org.junit.test;  import com.fasterxml.jackson.databind.deserializationfeature; import com.fasterxml.jackson.databind.objectmapper;  public class issuefieldswithdeserializertest {      @test     public void testjiraresponsedeserializer() throws ioexception, urisyntaxexception {         // arrange         string deploymentenvskey = "customfield_10700";          string json = new string(files.readallbytes(paths.get(getclass().getclassloader().getresource("jira-example-issue-with-customfield-poc.json").touri())));          objectmapper mapper = new objectmapper();         mapper.disable(deserializationfeature.fail_on_unknown_properties);         simplemodule module = new simplemodule();         module.adddeserializer(set.class, new customfielddeserializer(deploymentenvskey));         mapper.registermodule(module);           // act         issueresponsepoc issue = mapper.readvalue(json, issueresponsepoc.class);           // assert         assertthat("issue not null", issue, is(not(nullvalue())));         assertthat("fields not null", issue.getfields(), is(not(nullvalue())));         assertthat("custom field not null", issue.getfields().getdeploymentenvironments(), is(not(nullvalue())));         assertthat("custom field not empty", issue.getfields().getdeploymentenvironments(), is(not(empty())));         assertthat("custom field has 1 value", issue.getfields().getdeploymentenvironments(), hassize(1));     }  } 

issueresponsepoc class:

import java.io.serializable;  import com.fasterxml.jackson.annotation.jsonproperty;  public class issueresponsepoc implements serializable {      @jsonproperty private string id;     @jsonproperty private string key;      @jsonproperty private issuefieldspoc fields;  } 

interesting class: issuefieldspoc

import java.io.serializable; import java.util.date; import java.util.list; import java.util.set;  import com.fasterxml.jackson.databind.annotation.jsondeserialize;  import com.fasterxml.jackson.annotation.jsonproperty;  public class issuefieldspoc implements serializable {      @jsonproperty private string summary;     @jsonproperty private issuetype issuetype;     @jsonproperty private issueuser creator;     @jsonproperty private date created;     @jsonproperty private issueuser reporter;     @jsonproperty private issuepriority priority;     @jsonproperty private issueresolution resolution;     @jsonproperty private list<string> labels;     @jsonproperty private date resolutiondate;     @jsonproperty private issueuser assignee;     @jsonproperty private date updated;     @jsonproperty private issuestatus status;      @jsondeserialize private set<string> deploymentenvironments;     // @jsondeserialize(using = customfielddeserializer.class) private set<string> deploymentenvironments;      public set<string> getdeploymentenvironments() {         return deploymentenvironments;     }      public void setdeploymentenvironments(set<string> deploymentenvironments) {         this.deploymentenvironments = deploymentenvironments;     } } 

my deserializer:

import com.fasterxml.jackson.core.jsonparser; import com.fasterxml.jackson.core.jsonprocessingexception; import com.fasterxml.jackson.databind.deserializationcontext; import com.fasterxml.jackson.databind.deser.std.stddeserializer;  import java.io.ioexception; import java.util.collection; import java.util.collections; import java.util.set;  public class customfielddeserializer extends stddeserializer<set<string>> {      private final string customfieldname;      public customfielddeserializer(string customfieldname) {         super((class<?>) null);         this.customfieldname = customfieldname;     }      @override     public set<string> deserialize(jsonparser jsonparser, deserializationcontext deserializationcontext) throws ioexception, jsonprocessingexception {         system.out.println("deserializer started!");         return null;     }      @override     public collection<object> getknownpropertynames() {         return collections.singletonlist(customfieldname);     } } 

i tried registering custom deserializer not start, suspect ignored because jackson cannot identify field name. adding "getknownpropertynames" method did not help. since need put jira custom field name (i read configuration) somewhere tried put deserializer. using jackson annotation @jsondeserialize.

i tried wrapping class , not using set directly have stronger typing. no luck either.

i tried configuring deserializer within annotation requires default constructor , can no longer configure jira custom field name.

the current solution uses @jsonanysetter annotation:

@jsonanysetter public void setcustomproperty(string name, object value) {     if(stringutils.startswith(name, "customfield_")) {         this.customfields.put(name, value);     } } 

but prefer having logic within deserializer.

is there way jackson when start deserializer (since knows property name) dynamic property name?

update: registered module mapper. suggested in answers adding exact property name field:

@jsonproperty("customfield_10700") @jsondeserialize private set<string> deploymentenvironments; 

will allow deserializer start. mentioned above configurable value cannot put (or dont want to) directly in mapping code.

well, if understand right, need transform json java object.

if want class ignore unknown properties need add @jsonignoreproperties(ignoreunknown = true) classes must ignore (issueresponsepoc or issuefieldspoc too).

in @jsonproperty(value = <name_of_property_in_json>) allow use name field in java class.

if repeat nested levels of json java classes corresponding annotations (@jsonproperty, @jsonignore , on) don't need use deserializer whole.

and if want process unknown fields in classes, can use @jsonanysetter purposes


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -