How to make a Hirarchical Json Structure with java program - java

I am working on a generation JSON. The desired result is:
{
"nodes": [
{
"name": "Jeet123",
"type": 1,
"slug": "",
"entity": "company"
}
],
"links": [
{
"source": 0,
"target": 1,
"value": 1,
"distance": 5
}
]
}
This JSON i have to make. I am Writing this java code.. But it only shows {}
Entry1:
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
class Entry1 {
private String name;
private int type;
private String slug;
private String entity;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getEntity() {
return entity;
}
public void setEntity(String entity) {
this.entity = entity;
}
}
Entry2:
class Entry2 {
private String source;
private String target;
private String value;
private String distance;
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDistance() {
return distance;
}
public void setDistance(String distance) {
this.distance = distance;
}
}
EntryListContainer:
class EntryListContainer {
public List<Entry1> nodes;
public List<Entry2> links;
public void setEntryList1(List<Entry1> entryList1) {
this.nodes = nodes;
}
public List<Entry1> getEntryList1() {
return nodes;
}
public void setEntryList2(List<Entry2> entryList1) {
this.links = links;
}
public List<Entry2> getEntryList2() {
return links;
}
}
LinkJson:
public class LinkJson {
public static void main(String[] args) {
EntryListContainer container = new EntryListContainer();
List<Entry1> entryList1 = new ArrayList<>();
List<Entry2> entryList2 = new ArrayList<>();
Entry1 entry1 = new Entry1();
entry1.setName("Jeet123");
entry1.setType(1);
entry1.setSlug("");
entry1.setEntity("company");
entryList1.add(entry1);
Entry2 entry2 = new Entry2();
entry2.setSource("0");
entry2.setTarget("1");
entry2.setValue("1");
entry2.setDistance("5");
entryList2.add(entry2);
container.setEntryList1(entryList1);
container.setEntryList2(entryList2);
Gson gson = new Gson();
System.out.println(gson.toJson(container));
}
}

Bad copy/paste !
public void setEntryList2(List<Entry2> entryList1) {
this.links = links;
}
public void setEntryList1(List<Entry1> entryList1) {
this.nodes = nodes;
}
You should have this :
public void setEntryList2(List<Entry2> links) {
this.links = links;
}
public void setEntryList1(List<Entry1> nodes) {
this.nodes = nodes;
}

The way JSON is usually parsed to get the properties is to find the property names (nodes and links in your code) and then capitalise the first letter and append the get word onto the front to try and use the getter method. Basically your EntryListContainer doesn't follow the Java Bean Conventions that JSON (and GSON by proxy) relies on.
So it didn't print anything because you had no getter method for getNodes or getLinks, you have getEntryList1 and getEntryList2
I'm pretty sure you EntryListContainer class needs to look like this:
class EntryListContainer {
public List<Node> nodes;
public List<Link> links;
public void setNodes(final List<Node> nodes) {
this.nodes = nodes;
}
public List<Node> getNodes() {
return this.nodes;
}
public void setLinks(final List<Link> links) {
this.links = links;
}
public List<Link> getLinks() {
return this.links;
}
}

Create Constructor for your EntryListContainer class:
class EntryListContainer {
private List<Entry1> nodes;
private List<Entry2> links;
public EntryListContainer(List<Entry1> nodes, List<Entry2> links) {
this.nodes = nodes;
this.links = links;
}
}
And then create the container object this way:
EntryListContainer container = new EntryListContainer(entryList1,entryList2);
And then create the json:
Gson gson = new Gson();
System.out.println(gson.toJson(container));
Edit: Not necessary to use the constructor,
Change the following methods in your EntryListContainer class and it will work:
public void setEntryList1(List<Entry1> entryList1) {
this.nodes = entryList1;
}
public void setEntryList2(List<Entry2> entryList2) {
this.links = entryList2;
}

Related

Elasticsearch improve search accuracy on Boolean query match, matchesNot, matchesPartial

Need a help about the implementation of how to improve the search accuracy of the elasticSearch logic on the JAVA side which is in the springboot application.
Why I am aiming for search accuracy? Because in the production side whenever I am searching for products using the search bar in the app ex. Laptops it shows different results of product also.
First I have a **controller class ** where the request goes to this endpoint:
#PostMapping("/bsl/view/products/sort-filter")
public Response<SearchByFilterByResponse> viewSortByFilterBy(#RequestBody SearchByDto searchBy) throws IOException{
return Response.success(elasticSearchProductBslService.viewSortByFilterBy(searchBy));
}
RequestBody contains the SearchByDto class where inside of that class I have the filterBy object, where inside of it the structure of query is there.
SearchByDto class:
SearchByDto class
FilterBy class:
private Map<String, List<String>> filter;
private List<KeyValue<String, String>> matches;
private List<KeyValue<String, String>> matchesPartial;
private List<KeyValue<String, String>> matchesNot;
private List<KeyValue<String, RangeValue>> ranges;
private List<String> discludeFieldNotNullAndEmpty;
public List<String> getDiscludeFieldNotNullAndEmpty() {
if(discludeFieldNotNullAndEmpty==null) {
this.discludeFieldNotNullAndEmpty = new ArrayList<>();
}
return discludeFieldNotNullAndEmpty;
}
public void setDiscludeFieldNotNullAndEmpty(List<String> discludeFieldNotNullAndEmpty) {
this.discludeFieldNotNullAndEmpty = discludeFieldNotNullAndEmpty;
}
public List<KeyValue<String, RangeValue>> getRanges() {
if(ranges==null) {
this.ranges = new ArrayList<>();
}
return ranges;
}
public void setRanges(List<KeyValue<String, RangeValue>> ranges) {
this.ranges = ranges;
}
public Map<String, List<String>> getFilter() {
if(filter==null) {
this.filter = new HashMap<>();
}
return filter;
}
public void setFilter(Map<String, List<String>> filter) {
this.filter = filter;
}
public List<KeyValue<String, String>> getMatches() {
if(matches==null) {
this.matches = new ArrayList<>();
}
return matches;
}
public void setMatches(List<KeyValue<String, String>> matches) {
this.matches = matches;
}
public List<KeyValue<String, String>> getMatchesPartial() {
if(matchesPartial==null) {
this.matchesPartial = new ArrayList<>();
}
return matchesPartial;
}
public void setMatchesPartial(List<KeyValue<String, String>> matchesPartial) {
this.matchesPartial = matchesPartial;
}
public List<KeyValue<String, String>> getMatchesNot() {
if(matchesNot==null) {
this.matchesNot = new ArrayList<>();
}
return matchesNot;
}
public void setMatchesNot(List<KeyValue<String, String>> matchesNot) {
this.matchesNot = matchesNot;
}
}
As based on the structure of the code the matches, matchesPartial, matchesNot is nested under the filter Map, and each keyword queries should have key and value.
Now let's go back to the controller class, as you can see inside of the Response.success method
it is calling also the elasticSearchProductBslService.viewSortByFilterBy(searchBy) where inside of the searchBy it contains the request including the filterBy.
Let's jump to the viewSortByFilterBy() method inside of the elasticSearchProductBslService class.
public SearchByFilterByResponse viewSortByFilterBy(SearchByDto searchBy) throws IOException{
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
SearchRequest request = new SearchRequest();
request.indices("product_bsl");
request.source(sourceBuilder);
int fromIndex = searchBy.getPagination().getFrom();
int size = searchBy.getPagination().getSize();
elasticSearchHelper.buildFieldSort(searchBy, sourceBuilder);
sourceBuilder.from(fromIndex);
sourceBuilder.size(size);
BoolQueryBuilder queryBuilder = elasticSearchHelper.boolQueryBuilder(searchBy);
sourceBuilder.query(queryBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHit[] searchHits = response.getHits().getHits();
SearchByFilterByResponse resp = new SearchByFilterByResponse();
resp.setTotalHits(response.getHits().getTotalHits().value);
List<ProductWithImage> products = searchHitToDto(searchHits);
resp.setProducts(products);
return resp;
}
Additional information for you, this is the DTO class for "product_bsl" index. As I will show it to you how it look like in the OpenAPI later.
ProductBslElasticDto class:
public class ProductBslElasticDto {
private String id;
private String name;
private List<OfferElasticDto> offers;
private List<ProductBslElasticCategory> productBslElasticCategory;
private String brandId;
private String brandName;
private String shortdesc;
private String longDesc;
private int brandRating;
private long dateInserted;
private List<String> imagePath;
private String isActive;
private List<String> images;
private List<String> imageId;
private long totalVisits;
private long totalVisitUpdateTime;
private long totalViewCount;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getShortdesc() {
return shortdesc;
}
public void setShortdesc(String shortdesc) {
this.shortdesc = shortdesc;
}
public String getLongDesc() {
return longDesc;
}
public void setLongDesc(String longDesc) {
this.longDesc = longDesc;
}
public int getBrandRating() {
return brandRating;
}
public void setBrandRating(int brandRating) {
this.brandRating = brandRating;
}
public String getBrandId() {
return brandId;
}
public void setBrandId(String brandId) {
this.brandId = brandId;
}
public long getDateInserted() {
return dateInserted;
}
public void setDateInserted(long dateInserted) {
this.dateInserted = dateInserted;
}
public List<ProductBslElasticCategory> getProductBslElasticCategory() {
return productBslElasticCategory;
}
public void setProductBslElasticCategory(List<ProductBslElasticCategory> productBslElasticCategory) {
this.productBslElasticCategory = productBslElasticCategory;
}
public long getTotalVisits() {
return totalVisits;
}
public void setTotalVisits(long totalVisits) {
this.totalVisits = totalVisits;
}
public long getTotalVisitUpdateTime() {
return totalVisitUpdateTime;
}
public void setTotalVisitUpdateTime(long totalVisitUpdateTime) {
this.totalVisitUpdateTime = totalVisitUpdateTime;
}
public String getIsActive() {
return isActive;
}
public void setIsActive(String isActive) {
this.isActive = isActive;
}
public List<String> getImages() {
return images;
}
public void setImages(List<String> images) {
this.images = images;
}
public List<String> getImageId() {
return imageId;
}
public void setImageId(List<String> imageId) {
this.imageId = imageId;
}
public List<OfferElasticDto> getOffers() {
return offers;
}
public void setOffers(List<OfferElasticDto> offers) {
this.offers = offers;
}
public long getTotalViewCount() {
return totalViewCount;
}
public void setTotalViewCount(long totalViewCount) {
this.totalViewCount = totalViewCount;
}
public List<String> getImagePath() {
return imagePath;
}
public void setImagePath(List<String> imagePath) {
sortIndexedImagePaths(imagePath);
this.imagePath = imagePath;
}
private void sortIndexedImagePaths(List<String> imagePaths) {
if (null == imagePaths) return;
for (String path : imagePaths) {
if (null == path ||
!PRODUCT_INDEXED_IMAGE_PATH_PATTERN.matcher(path).find()) {
return;
}
}
imagePaths.sort(String::compareTo);
}
}
Now after I show the DTO you can look back to the viewSortByFilterBy() again. I think you can disregard the SourceBuilder and SearchRequest let's focus on the elasticSearchHelper.boolQueryBuilder(searchBy) as we will jump inside of it.
ElasticSearchHelper class:
#Service
public class ElasticSearchHelper {
private static final String KEY_NAME = "name";
private static final String REGEX_SPACE = " ";
private static final String REGEX_WILDCARD = "*";
public BoolQueryBuilder boolQueryBuilder(SearchByDto searchBy) {
FilterBy filterBy = searchBy.getFilterBy();
BoolQueryBuilder rootBuilder = QueryBuilders.boolQuery();
if(filterBy!=null) {
nestedTermsQueryBuilder(rootBuilder, filterBy.getFilter());
nestedBoolQueryBuilder(rootBuilder, filterBy.getMatches(), MUST);
nestedBoolQueryBuilder(rootBuilder, filterBy.getMatchesNot(), MUST_NOT);
nestedBoolQueryBuilder(rootBuilder, filterBy.getMatchesPartial(), SHOULD);
nestedExistsQueryBuilder(rootBuilder, filterBy.getDiscludeFieldNotNullAndEmpty());
nestedRangeQueryBuilder(rootBuilder, filterBy.getRanges());
}
return rootBuilder;
}
private void nestedTermsQueryBuilder(BoolQueryBuilder rootBuilder, Map<String, List<String>> filter) {
filter.forEach((key, value) -> {
TermsQueryBuilder nestedBuilder = QueryBuilders.termsQuery(key, value);
rootBuilder.must(nestedBuilder);
});
}
private void nestedBoolQueryBuilder(BoolQueryBuilder rootBuilder, List<KeyValue<String, String>> entries, ElasticSearchBoolQueryType queryType) {
if(entries != null && !entries.isEmpty()) {
Set<String> distinctKeys = entries.stream().map(KeyValue::getKey).collect(Collectors.toSet());
for (String key : distinctKeys) {
BoolQueryBuilder nestedBuilder = QueryBuilders.boolQuery();
for (KeyValue<String, String> entry : entries) {
nestedQueryStringOrDisMaxQueryBuilder(key, entry, nestedBuilder);
}
switch (queryType) {
case MUST:
rootBuilder.must(nestedBuilder);
break;
case MUST_NOT:
rootBuilder.mustNot(nestedBuilder);
break;
case SHOULD:
rootBuilder.should(nestedBuilder);
break;
default:
break;
}
}
}
}
I just included the boolQueryBuilder and nestedBoolQueryBuilder only just to focus relating to my concern. don't get confuse on the MUST, MUST_NOT, SHOULD it is the same for matches, matchesNot, matchesPartial as I have told earlier on the FilterBy class. So in this class I think the logic happens here, any suggestions for any changes and how should I improve search accuracy for this kind of structure?
How it looks like in OpenAPI as I will search for product name:
Request: POST "/bsl/view/products/sort-filter"
{
"pagination": {
"from": 0,
"size": 20
},
"sortBy": {
"fieldsAscOrDesc": {
"offers.financing.finalAmount": "desc"
}
},
"filterBy": {
"matches": [
{
"key": "name",
"value": "Lenovo IdeaPad3 81Y4001NPH"
}
],
"matchesNot": [
{
"key": "isActive",
"value": "false"
}
],
"discludeFieldNotNullAndEmpty": [
"offers"
]
}
}
Result was it had total of 17 hits and I used the matches keyword where it should be search the exact word right? But it shows different Lenovo products in the result.
Result

Java 17 java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.time.ZoneOffset

I have been trying to convert a json string to variables my java program can use but when i run this it doesnt work.
(responseString is a valid json string)
GetConversion conversion = new ObjectMapper().readValue(responseString, GetConversion.class);
class GetConversion{
private State state;
private Swupdate swupdate;
private String type;
private String name;
private String modelid;
private String manufacturername;
private String productname;
private Capabilities capabilities;
private Config config;
private String uniqueid;
private String swversion;
private String swconfigid;
private String productid;
public State getState() { return state; }
public void setState(State value) { this.state = value; }
public Swupdate getSwupdate() { return swupdate; }
public void setSwupdate(Swupdate value) { this.swupdate = value; }
public String getType() { return type; }
public void setType(String value) { this.type = value; }
public String getName() { return name; }
public void setName(String value) { this.name = value; }
public String getModelid() { return modelid; }
public void setModelid(String value) { this.modelid = value; }
public String getManufacturername() { return manufacturername; }
public void setManufacturername(String value) { this.manufacturername = value; }
public String getProductname() { return productname; }
public void setProductname(String value) { this.productname = value; }
public Capabilities getCapabilities() { return capabilities; }
public void setCapabilities(Capabilities value) { this.capabilities = value; }
public Config getConfig() { return config; }
public void setConfig(Config value) { this.config = value; }
public String getUniqueid() { return uniqueid; }
public void setUniqueid(String value) { this.uniqueid = value; }
public String getSwversion() { return swversion; }
public void setSwversion(String value) { this.swversion = value; }
public String getSwconfigid() { return swconfigid; }
public void setSwconfigid(String value) { this.swconfigid = value; }
public String getProductid() { return productid; }
public void setProductid(String value) { this.productid = value; }
}
class Capabilities {
private boolean certified;
private Control control;
private Streaming streaming;
public boolean getCertified() { return certified; }
public void setCertified(boolean value) { this.certified = value; }
public Control getControl() { return control; }
public void setControl(Control value) { this.control = value; }
public Streaming getStreaming() { return streaming; }
public void setStreaming(Streaming value) { this.streaming = value; }
}
class Control {
private long mindimlevel;
private long maxlumen;
private String colorgamuttype;
private double[][] colorgamut;
private CT ct;
public long getMindimlevel() { return mindimlevel; }
public void setMindimlevel(long value) { this.mindimlevel = value; }
public long getMaxlumen() { return maxlumen; }
public void setMaxlumen(long value) { this.maxlumen = value; }
public String getColorgamuttype() { return colorgamuttype; }
public void setColorgamuttype(String value) { this.colorgamuttype = value; }
public double[][] getColorgamut() { return colorgamut; }
public void setColorgamut(double[][] value) { this.colorgamut = value; }
public CT getCT() { return ct; }
public void setCT(CT value) { this.ct = value; }
}
class CT {
private long min;
private long max;
public long getMin() { return min; }
public void setMin(long value) { this.min = value; }
public long getMax() { return max; }
public void setMax(long value) { this.max = value; }
}
class Streaming {
private boolean renderer;
private boolean proxy;
public boolean getRenderer() { return renderer; }
public void setRenderer(boolean value) { this.renderer = value; }
public boolean getProxy() { return proxy; }
public void setProxy(boolean value) { this.proxy = value; }
}
class Config {
private String archetype;
private String function;
private String direction;
private Startup startup;
public String getArchetype() { return archetype; }
public void setArchetype(String value) { this.archetype = value; }
public String getFunction() { return function; }
public void setFunction(String value) { this.function = value; }
public String getDirection() { return direction; }
public void setDirection(String value) { this.direction = value; }
public Startup getStartup() { return startup; }
public void setStartup(Startup value) { this.startup = value; }
}
class Startup {
private String mode;
private boolean configured;
public String getMode() {
return mode;
}
public void setMode(String value) {
this.mode = value;
}
public boolean getConfigured() {
return configured;
}
public void setConfigured(boolean value) {
this.configured = value;
}
}
class State {
private boolean on;
private long bri;
private long hue;
private long sat;
private String effect;
private double[] xy;
private long ct;
private String alert;
private String colormode;
private String mode;
private boolean reachable;
public boolean getOn() { return on; }
public void setOn(boolean value) { this.on = value; }
public long getBri() { return bri; }
public void setBri(long value) { this.bri = value; }
public long getHue() { return hue; }
public void setHue(long value) { this.hue = value; }
public long getSat() { return sat; }
public void setSat(long value) { this.sat = value; }
public String getEffect() { return effect; }
public void setEffect(String value) { this.effect = value; }
public double[] getXy() { return xy; }
public void setXy(double[] value) { this.xy = value; }
public long getCT() { return ct; }
public void setCT(long value) { this.ct = value; }
public String getAlert() { return alert; }
public void setAlert(String value) { this.alert = value; }
public String getColormode() { return colormode; }
public void setColormode(String value) { this.colormode = value; }
public String getMode() { return mode; }
public void setMode(String value) { this.mode = value; }
public boolean getReachable() { return reachable; }
public void setReachable(boolean value) { this.reachable = value; }
}
class Swupdate {
private String state;
private OffsetDateTime lastinstall;
public String getState() { return state; }
public OffsetDateTime getLastinstall() { return lastinstall; }
}
I believe it may have something to do with the last part of the code "public OffsetDateTime getLastinstall() { return lastinstall; }" because the error mentions java.time.OffsetDateTime and this is where that is called.
When I run this it gives a this error:
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.time.ZoneOffset java.time.OffsetDateTime.offset accessible: module java.base does not "opens java.time" to unnamed module #3578436e
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
at com.fasterxml.jackson.databind.util.ClassUtil.checkAndFixAccess(ClassUtil.java:891)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.fixAccess(FieldProperty.java:102)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder._fixAccess(BeanDeserializerBuilder.java:484)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder.build(BeanDeserializerBuilder.java:350)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:245)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:137)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:411)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(DeserializationContext.java:467)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:473)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:293)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(DeserializationContext.java:467)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:473)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:293)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4190)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4009)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
at sendCommands.Loft.runGet(Loft.java:141)
at sendCommands.Loft.routine(Loft.java:103)
at sendCommands.Main.main(Main.java:7)
Help fix this pls. The json I used for response string is :
{
"state": {
"on": true,
"bri": 198,
"hue": 25360,
"sat": 254,
"effect": "none",
"xy": [
0.1749,
0.6963
],
"ct": 500,
"alert": "none",
"colormode": "xy",
"mode": "homeautomation",
"reachable": true
},
"swupdate": {
"state": "noupdates",
"lastinstall": "2021-08-13T13:51:54"
},
"type": "Extended color light",
"name": "Hue color spot 6",
"modelid": "LCG002",
"manufacturername": "Signify Netherlands B.V.",
"productname": "Hue color spot",
"capabilities": {
"certified": true,
"control": {
"mindimlevel": 200,
"maxlumen": 300,
"colorgamuttype": "C",
"colorgamut": [
[
0.6915,
0.3083
],
[
0.17,
0.7
],
[
0.1532,
0.0475
]
],
"ct": {
"min": 153,
"max": 500
}
},
"streaming": {
"renderer": true,
"proxy": true
}
},
"config": {
"archetype": "spotbulb",
"function": "mixed",
"direction": "downwards",
"startup": {
"mode": "safety",
"configured": true
}
},
"uniqueid": "00:17:88:01:08:3f:fb:56-0b",
"swversion": "1.88.2",
"swconfigid": "4AF23F6F",
"productid": "Philips-LCG002-1-GU10ECLv2"
}
It looks to me like it's a problem with Jackson attempting to serialize an OffsetDateTime field - it's trying to access the OffsetDateTime's private 'offset' property.
Jackson needs to be told how to serialize OffsetDateTime properly.
You can either add another Jackson library dependency to take care of this, or write a custom object mapper, if you need a format not provided by the library.
See Jackson date-format for OffsetDateTime in Spring Boot
I encountered a similar issue when I was unit testing Twilio SMS.
I solved the issue by registering JavaTimeModule on the ObjectMapper.
String json = "{\"status\": \"sent\"}";
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
var message = Message.fromJson(json, mapper);

SAXParser parse complex object

I am a novice in SAXParser. I don't know is it possible to parse complex object with SAXParser. I have a class which contain Item list. And my response xml is like that :
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><GetPaymentServiceInfoResponse xmlns="http://quetzalcoatlus/EpulPaymentService"><GetPaymentServiceInfoResult><ResultCodes>OK</ResultCodes><Description>User is temporary blocked</Description><Items><Item><Amount>122</Amount></Item><Item><Amount>23232</Amount></Item></Items></GetPaymentServiceInfoResult></GetPaymentServiceInfoResponse></s:Body></s:Envelope>
And my POJO class is like following:
#XmlRootElement(name = "PGResponse")
public class CheckAbonSuccessResponseModel {
private String message;
private String message_code;
private BigDecimal amount;
private String invoiceCode;
private String operationCode;
private List<Item> items;
#XmlElement(name = "message")
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
#XmlElement(name = "message_code")
public String getMessage_code() {
return message_code;
}
public void setMessage_code(String message_code) {
this.message_code = message_code;
}
#XmlElement(name = "amount")
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
#XmlElement(name = "invoice_code")
public String getInvoiceCode() {
return invoiceCode;
}
public void setInvoiceCode(String invoiceCode) {
this.invoiceCode = invoiceCode;
}
#XmlElement(name = "operation_code")
public String getOperationCode() {
return operationCode;
}
public void setOperationCode(String operationCode) {
this.operationCode = operationCode;
}
#XmlElement(name = "items")
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
#XmlRootElement(name = "item")
public static class Item {
private String label;
private String value;
#XmlElement(name = "label")
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
#XmlElement(name = "value")
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
How I can parse my xml string to CheckAbonSuccessResponseModel. Is it possible or not? I was trying but it shows just amount inside Result element.I need just know how I must write DefaultHandler class.
Thanks in advance.

JAXB check if XML-Tag has specific attribute

I'm working at a Method to filter a collection (FileList) of xml-files if a specific xml-tag has an attribute...
In detail... I want to filter all xml-files where the xml-tag has an attribute "is_special", but I've problems to setup my model-classes for the attribute.
At the end I want to store the name of the file and a list of its items, where the value has the attribute is_special="true"
Also I'm using the JAXB Framework with the Moxy extension...
The XML-Structure as followed:
<document>
<id>75C8866AB078DCE541256D16002CF636</id>
<size>806220</size>
<author>xxx</author>
<last_modified>2017.06.12 07:15:41 GMT</last_modified>
<added_to_file>2016.07.05 09:50:44 GMT</added_to_file>
<created>2003.04.28 08:11:06 GMT</created>
<items>
<item>
<name>someName/name>
<type>LNITEMTYPE_DATETIMES</type>
<values>
<value is_special="true"/>
</values>
<last_modified>2003.04.28 08:11:10 GMT</last_modified>
...
</item>
<item>
<name>someName/name>
<type>LNITEMTYPE_TEXT</type>
<values>
<value>SOMETEXT</value>
<value>SOMETEXT</value>
</values>
<last_modified>2003.04.28 08:11:10 GMT</last_modified>
...
</item>
</items>
Therefor I've got 3 Classes for the XML-File...
"XMLDocument.java" implements the list of "Items.java" which implements the list of "Value.java"
XMLDocument.java
#XmlRootElement(name = "notes_document")
public class XMLDocument {
...
private List<Item> items;
...
#XmlElementWrapper(name = "items")
#XmlElement(name = "item")
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
}
item.java
#XmlRootElement(name = "items")
public class Item {
private String name;
private List<String> values;
private boolean valueIsSpecial;
#XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElementWrapper(name = "values")
#XmlElement(name = "value")
public List<String> getValues() {
return values;
}
public void setValues(List<String> values) {
this.values = values;
}
#XmlPath("value/#is_special")
public boolean getValueIsSpecial() {
return valueIsSpecial;
}
public void setValueIsSpecial(boolean valueIsSpecial) {
this.valueIsSpecial = valueIsSpecial;
}
}
value.java
#XmlRootElement(name = "values")
public class Value {
#XmlElement(name = "value")
private String itemValue;
#XmlPath("value/#is_special")
private boolean isSpecial;
public String getValue() {
return itemValue;
}
public void setValue(String value) {
this.itemValue = value;
}
public boolean getValueIsSpecial() {
return isSpecial;
}
public void setValueIsSpecial(boolean isSpecial) {
this.isSpecial = isSpecial;
}
}
My Method so far...
public void FilterTree_isSpecial() throws JAXBException, FileNotFoundException {
for(String file: FileList) {
if (file.endsWith(".xml") && !file.contains("databaseinfo.xml")) {
JAXBContext context = JAXBContext.newInstance(NotesDocumentMetaFile.class);
Unmarshaller um = context.createUnmarshaller();
NotesDocumentMetaFile docMetaFile = (XMLDocument) um.unmarshal(new FileReader(file));
for (int i = 0; i < docMetaFile.getItems().size(); i++) {
// CHECK IF THE <value> OF THIS ITEM HAS ATTRIBUTE is_special
}
}
}
}
Much text... I hope anyone can give me a solution :/
Actually the xpath in your Item.java needs to be : values/value/#is_special like #XmlPath("values/value/#is_special")
If you want the is_special in your Value.java also your xpath should be :
#is_special like : #XmlPath(#is_special)
Also your Item.java, Value.java needs a little change. You don't need #XmlRootElement, you already had it in your XmlDocument.java
Your Item.java should be :
public class Item
{
private String name;
private String type;
private String lastModified;
private List<Value> values;
private String isSpecial;
#XmlPath("values/value/#is_special")
public String getIsSpecial() {
return isSpecial;
}
public void setIsSpecial(String isSpecial) {
this.isSpecial = isSpecial;
}
#XmlElement(name="type")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#XmlElement(name="last_modified")
public String getLastModified() {
return lastModified;
}
public void setLastModified(String lastModified) {
this.lastModified = lastModified;
}
#XmlElement(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElementWrapper(name="values")
#XmlElement(name="value")
public List<Value> getValues() {
return values;
}
public void setValues(List<Value> values) {
this.values = values;
}
}
Your Value.java should be :
public class Value
{
#XmlPath("text()")
private String value;
#XmlPath("#is_special")
private String isSpecial;
public String getIsSpecial() {
return isSpecial;
}
public void setIsSpecial(String isSpecial) {
this.isSpecial = isSpecial;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Note that to get value and is_special in Value.java, you could use #XmlPath.
Now you can call getIsSpecial() on Item.java to check if it is special.

Error when using DocumentReferences with Ektorp and JSF

I have been getting an error with DocumentReferences in a small JSF project i created to learn CouchDB/Ektorp .
I belive everything is working as is should in the CRUD, the id of the parent document is stored as a string, similar to the tutorial project.
But when I retrieve the parent object from the database I get this error:
org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type
[simple type, class com.pro.documents.Apple] from JSON String; no single-String
constructor/factory method (through reference chain: com.pro.documents.Eiere["apple"])
Here is the rest of the code:
{
"_id": "_design/Eiere",
"_rev": "17-ebb06b0d3102622a3d9849b9399cd94f",
"language": "javascript",
"views": {
"all": {
"map": "function(doc){if (doc.type == 'eiere') {emit(doc._id, doc);}}"
},
"ektorp_docrefs_apple": {
"map": "function(doc){ if(doc.eiere){emit([doc.eiere, 'apple', doc.kategori], null);}}"
}
}
}
{
"_id": "_design/Apple",
"_rev": "8-e04d8b5633776545b9eacdc998db4aea",
"language": "javascript",
"views": {
"all": {
"map": "function(doc){ if(doc.type == 'apple'){emit(doc._id, doc);}}"
}
}
}
public class Eiere extends CouchDbDocument {
#TypeDiscriminator
private String type;
private String navn;
private String telefon;
#DocumentReferences(backReference = "eiere", fetch = FetchType.LAZY, descendingSortOrder = true)
private Set<Apple> apple;
private Date dateCreated;
public Set<Apple> getApple() {
return apple;
}
public void setApple(Set<Apple> apples) {
this.apple = apples;
}
public void addApple(Apple c) {
Assert.notNull(c, "Apple may not be null");
if (getApple() == null) {
apple = new TreeSet<Apple>();
}
c.setEiere(this.getId());
apple.add(c);
}
public String getType() {
if (type == null) {
type = "eiere";
}
return type;
}
public void setType(String type) {
this.type = type;
}
public String getNavn() {
return navn;
}
public void setNavn(String navn) {
this.navn = navn;
}
public String getTelefon() {
return telefon;
}
public void setTelefon(String telefon) {
this.telefon = telefon;
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
}
public class Apple extends CouchDbDocument implements Comparable<Apple>{
private static final long serialVersionUID = 1L;
#TypeDiscriminator
private String type;
private List<String> prices;
private String kategori;
private String eiere;
private Date dateCreated;
public String getType() {
if(type == null){
type = "apple";
}
return type;
}
public void setType(String type) {
this.type = type;
}
public List<String> getPrices() {
if(prices == null){
prices = new ArrayList<String>();
prices.add(0, " ");
prices.add(1, " ");
prices.add(2, " ");
}
return prices;
}
public void setPrices(List<String> prices) {
this.prices = prices;
}
public String getKategori() {
return kategori;
}
public void setKategori(String kategori) {
this.kategori = kategori;
}
public String getEiere() {
return eiere;
}
public void setEiere(String eiere) {
this.eiere = eiere;
}
#Override
public String toString() {
return prices.toString();
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
#Override
public int compareTo(Apple other) {
if (other == this) return 0;
if (dateCreated != null) {
return - dateCreated.compareTo(other.dateCreated);
}
return 0;
}
}
Any help or advice to help me understand what I'm doing wrong will be much appreciated.
Edit: If there is any information that I could add that would make my problem clearer or help in determining the cause of it please let me know.
Br.

Categories

Resources