How to convert OpenRTB object to JSON in Java - java

I try to use the com.google.openrtb package https://github.com/google/openrtb in my micronaut project.
Google remove the support of JSON serialization in the last version of the package.
(If someone know how to convert the BidResponse of the last version of this package to a valid JSON, it will help a lot! )
So you can see my code :
Logger logger = Logger.getLogger(TestController.class.getName());
logger.info("ok");
BidResponse.Builder bid = BidResponse.newBuilder()
.setId("123")
.setCur("EUR")
.addSeatbid(BidResponse.SeatBid.newBuilder()
.addBid(BidResponse.SeatBid.Bid.newBuilder()
.setId("123")
.setAdid("ad-1234567")
.setImpid("123")
.setPrice(1.2))
);
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(bid);
return HttpResponse.status(HttpStatus.OK).body(json);
But when I call this function I get this error :
{"message":"Bad Request","_embedded":{"errors":[{"message":"Invalid JSON: No serializer found for class com.google.protobuf.UnknownFieldSet$Parser and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.google.openrtb.OpenRtb$BidResponse$Builder[\"seatbidList\"]->java.util.Collections$UnmodifiableRandomAccessList[0]->com.google.openrtb.OpenRtb$BidResponse$SeatBid[\"unknownFields\"]->com.google.protobuf.UnknownFieldSet[\"parserForType\"])"}]},"_links":{"self":{"href":"/test","templated":false}}}
I try to put SerializationFeature.FAIL_ON_EMPTY_BEANS configuration, And i get this error :
Invalid JSON: Direct self-reference leading to cycle (through reference chain: com.google.openrtb.OpenRtb$BidResponse[\"unknownFields\"]->com.google.protobuf.UnknownFieldSet[\"defaultInstanceForType\"])
Someone already got this type of error in Java ?

Related

Json wrong fields

How can I get all wrong fields names? For example, I have next input string as JSON format:
{
"name": "name#1",
"address": "address#1",
"pone": "000000000",
"ail": "mail#smth.ru"
}
Where 'pone' and 'ail' fields are wrong. It needs to use 'phone' and 'email'. I also use this property
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
For catching exception. And I catch it inside of try/catch when deserializing JSON to an object, but there is info about only one field in the exception message.
I need to get all wrong fields at once.
Maybe somebody have an idea about it? I also tried use jsonSchema but I think it isn't good idea, because in the end I have this message $: string found, object expected by this code:
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(VersionFlag.V201909);
InputStream stream=TestClass.class.getResourceAsStream("/file.json");
JsonSchema schema=factory.getSchema(stream);
JsonNode node =mapper.convertToJsonNode(MyObject.builder().build());
Set<ValidationMessage> validationResult = schema.validate(node);

strip identifier from result of .toString() method

It is out of desperation and I don't know java. Basically, I want to resolve a couchbase lite Document back to a react-native application as follows:
Document doc = database.getDocumet('id');
promise.resolve(doc);
that doesn't work with error can't be cast so I turned to toString(), hoping to parse it in react-native:
promise.resolve(doc.toString());
// in js:
const document = getNativeDocument('id');
console.log(document)
const v = JSON.parse(document);
but that fails too with error:
SyntaxError: JSON Parse error: Unexpected identifier "Document"].
The console result is:
Document{#0xb3181c18e30a7f1-1f61-49a0-9ca0-1dc3d2e343ed#1-a7ed608736c34cf5860a0d35968e6441e1f089ef(..):obj=>Dictionary{(..)a=>A,b=>B},age=>20,firstPromo=>null}
I have tried solutions to convert the Document into other times that can easily be resolved by promise.resolve() but now wondering if there is away to work with results of the .toString()
the toString method generates an internal representation of the object for debugging, not JSON of the document. You need to use a different method to serialize your Document to JSON.
The most popular option for this is to use the Jackson library: https://www.baeldung.com/jackson-object-mapper-tutorial
If you're using Spring framework with Spring data couchbase connector then Jackson's ObjectMapper should already be available to your application as a Bean.

Jackson: Object to String via writeValueAsString: NPE

Im attempting to convert a Java Object into JSON using the Jackson parser. The original object comes to me via protobuf and contains some #annotations specific to Jackson.
When I call String jsonView = objectMapper.writeValueAsString(values);
I get this exception. The object doesn't contain any recursive values so I'm not clear why Im seeing this error (or even this code path).
ObjectMapper is configured with: objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); (although removing it doesn't seem to change anything)
java.lang.NullPointerException: null
at com.fasterxml.jackson.databind.type.ResolvedRecursiveType.equals(ResolvedRecursiveType.java:103)
at com.fasterxml.jackson.databind.type.TypeBindings$AsKey.equals(TypeBindings.java:458)
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:940)
at com.fasterxml.jackson.databind.util.LRUMap.get(LRUMap.java:68)
at com.fasterxml.jackson.databind.type.TypeFactory._fromClass(TypeFactory.java:1211)
at com.fasterxml.jackson.databind.type.TypeFactory._fromParamType(TypeFactory.java:1384)
at com.fasterxml.jackson.databind.type.TypeFactory._fromAny(TypeFactory.java:1154)
at com.fasterxml.jackson.databind.type.TypeFactory._resolveSuperInterfaces(TypeFactory.java:1298)
at com.fasterxml.jackson.databind.type.TypeFactory._fromClass(TypeFactory.java:1243)
at com.fasterxml.jackson.databind.type.TypeFactory._fromAny(TypeFactory.java:1150)
at com.fasterxml.jackson.databind.type.TypeFactory._resolveSuperInterfaces(TypeFactory.java:1298)
at com.fasterxml.jackson.databind.type.TypeFactory._fromClass(TypeFactory.java:1247)
at com.fasterxml.jackson.databind.type.TypeFactory._fromAny(TypeFactory.java:1150)
at com.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeFactory.java:618)
at com.fasterxml.jackson.databind.cfg.MapperConfig.constructType(MapperConfig.java:290)
at com.fasterxml.jackson.databind.cfg.MapperConfig.introspectClassAnnotations(MapperConfig.java:320)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.removeIgnorableTypes(BeanSerializerFactory.java:714)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanProperties(BeanSerializerFactory.java:573)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.constructBeanSerializer(BeanSerializerFactory.java:390)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanSerializer(BeanSerializerFactory.java:273)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:225)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:159)
at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1272)
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1243)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:535)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.resolve(BeanSerializerBase.java:332)
at com.fasterxml.jackson.databind.ser.SerializerCache.addAndResolveNonTypedSerializer(SerializerCache.java:174)
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1254)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:535)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.resolve(BeanSerializerBase.java:332)
at com.fasterxml.jackson.databind.ser.SerializerCache.addAndResolveNonTypedSerializer(SerializerCache.java:174)
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1254)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:535)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.resolve(BeanSerializerBase.java:332)
at com.fasterxml.jackson.databind.ser.SerializerCache.addAndResolveNonTypedSerializer(SerializerCache.java:197)
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1233)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:499)
at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:697)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:270)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3672)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3048)
Fixed in latest versions (see 2.8.1 or above):
https://github.com/FasterXML/jackson-databind/issues/1302

access nested property value using apcahe propertyUtilbean

I am converting json response to Object type using jakson api and after i want to verify the property values .
ObjectMapper mapper = new ObjectMapper();
Object jsonobj = mapper.readValue(inputStream,Object.class);
i am getting correct mapped json response to Object type .
{fatalError=false,messages=[{code=1234,xyz=abcd}]}
using PropertyUtilbean class i want to get my object property value
String val =propertyutil.getProperty(jsonobj,"fatalError")--- this will give value as false, but if i want to get value using key messages.[0].code it is giving me no such method found. please help me out if i am using wrong key format. any help will be appreciated.!
this is nested arrayList object and messages is a arrayList ,can you try with index number---- messages[0]

Read Facebook Post-related Object with Spring Social

I read all my likes using FQL with Spring Social Facebook
here is the method:
public List<LikeObject> startF(String token){
Facebook facebook = new FacebookTemplate(token);
FacebookProfile profile = facebook.userOperations().getUserProfile();
//System.out.println(facebook.isAuthorized());
System.out.println("Authenticcated user: "+profile.getFirstName()+" "+profile.getLastName());
PagedList<String> friendListIds = facebook.friendOperations().getFriendIds();
List<LikeObject> resultsLikes = facebook.fqlOperations().query("SELECT object_id, object_id_cursor,object_type, post_id, post_id_cursor, user_id "+
"FROM like "+
"WHERE user_id =me() ", new FqlResultMapper<LikeObject>(){
public LikeObject mapObject(FqlResult result) {
LikeObject like = new LikeObject();
like.object_id = result.getString("object_id");
like.object_id_cursor = result.getString("object_id_cursor");
like.object_type = result.getString("object_type");
like.post_id = result.getString("post_id");
like.post_id_cursor = result.getString("post_id_cursor");
like.user_id = result.getString("user_id");
return like;
}
});
return resultsLikes;
}
Here results:
LikeObject [object_id=578416.., object_id_cursor=null,
object_type=status, post_id=, post_id_cursor=null, user_id=10217..]
Then I would like to parse like.object_id and convert it to java object. But I've no idea how to do it using spring social facebook.
I've tried facebook.fetchObject(like.object_id, PostType.STATUS) . But it seems to be a wrong way.
Is there any possible way to parse an "object_id" in spring social without parsing raw JSON response from GET query?
I've tried this:
LinkPost post = facebook.fetchObject(obj_id, LinkPost.class);
I believe that obj_id has type link, I've checked it
and it cause following exception:
Exception in thread "main" org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'postType' that is to contain type id (for class org.springframework.social.facebook.api.LinkPost)
at [Source: java.io.ByteArrayInputStream#6ca79a6a; line: 1, column: 11114]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'postType' that is to contain type id (for class org.springframework.social.facebook.api.LinkPost)
at [Source: java.io.ByteArrayInputStream#6ca79a6a; line: 1, column: 11114]
at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:171)
at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.read(MappingJackson2HttpMessageConverter.java:163)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:94)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:491)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:460)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:228)
at org.springframework.social.facebook.api.impl.FacebookTemplate.fetchObject(FacebookTemplate.java:202)
at com.repost.facebook.FbConnection.getLikedPosts(FbConnection.java:58)
at com.repost.facebook.MainClass.main(MainClass.java:15)
I'm still unclear what you mean by "parse". But let me attempt to answer this anyway...
I think you simply want to be able to fetch the object as a Post (or LinkPost) object...is that right? If so, then there's some special magic that I unfortunately had to bake into the API to be able to both grab the post type and do polymorphic deserialization into a specific type of Post (e.g., LinkPost, StatusPost, etc).
You can see the setup taking place in https://github.com/SpringSource/spring-social-facebook/blob/master/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/FeedTemplate.java. In the deserializePost() method, you see that I read the "type" property and copy it into a new "postType" field. One of those fields is used to populate the Post's type property and the other is used to determine which specific subclass of Post should be created. It's a hack to work around a problem I had with Jackson 1.9.x...I think that Jackson 2 will make that hack unnecessary, but I've not tried it yet.
Therefore, I see only one practical way of doing this: Don't do all the work yourself. Instead use facebook.feedOperations().getPost(objectId). It knows how to do the magic under the covers to give you a Post object. From there, if you know the specific kind of Post, you can cast it as (and if) needed to LinkPost, StatusPost, etc.
The only other option I see is to go even lower level and make the request through facebook.restOperations() and to handle the binding for yourself. That's obviously a lot more work on your part.

Categories

Resources