Is there a way to represent an object array in JSON? e.g. Supposing I have the server-side method Test(object[]) which expects any of the three following classes:
class ObjectA{ int a; }
class ObjectB{ bool a; }
class ObjectC{ string a; }
What would new object[]{ new ObjectA(), new ObjectB(), new ObjectC() } look like when represented in JSON?
I guess it would be:
[{"a": 42}, {"a": true}, {"a": "The answer is"}]
The only way to preserve the type of object, would be to add an additional property. JSON does not know anything about classes. There are only objects which have certain properties.
Related
I'm trying to parse JSON to POJO using jackson with polymorphic types.
I have the following JSON which I'd like to deserialize to a POJO.
I have created wrapper classes to parse all JSON values, but I have problems with the "geometry" and "geometryType" objects.
I have created POJO's for each type of geometry, and I'l like to use the value from "geometryType" to parse the value from "geometry" to different Java class depending on the value of "geometryType". E.g.: if geometryType = 'geometryPolygon' then I'll like to parse "geometry" to Polygon class.
I know its possible with annotation #JsonTypeInfo and using a property to choose the correct subtype for my POJO, but in my case, the "type" is actually in a different object, and not inside the same JSON object like all the other tutorials I saw online.
Any help will be appreciated.
{
"results": [{
"layerId": 3,
"layerName": "Parcels",
"displayFieldName": "LAND_CO",
"value": "0",
"attributes": {
"Feature identifier": "6",
"SHAPE": "Polygon",
"PROPERTY_I": "5006",
"LANDUSE_CO": "0",
"ZONING": "1",
"PARCEL_ID": "6363",
"Res": "Non-Residential",
"Zoning_simple": "Null",
"SHAPE_Length": "3594.570779",
"SHAPE_Area": "112648.196175"
},
"geometryType": "geometryPolygon",
"geometry": {
"rings": [[[-85.802587291351813, 32.394007668298649], .........]]
}
}
]
}
Example of POJO classes:
class Polygon extends Geometry { ... }
class Polyline extends Geometry {...}
Have a look at examples with JsonTypeInfo.As.EXTERNAL_PROPERTY
Inclusion mechanism similar to PROPERTY, except that property is included one-level higher in hierarchy, i.e. as sibling property at same level as JSON Object to type. Note that this choice can only be used for properties, not for types (classes). Trying to use it for classes will result in inclusion strategy of basic PROPERTY instead.
// Polygon and Polyline extends Geometry.
#JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
property = "geometryType")
#JsonSubTypes({
#JsonSubTypes.Type(name = "geometryPolygon", value = Polygon.class),
#JsonSubTypes.Type(name = "geometryPolyline", value = Polyline.class),
....})
private Geometry geometry;
See:
Java: Jackson polymorphic JSON deserialization of an object with an interface property?
Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY doesn't work as expected
You can use this amazing tool for converting your JSON to POJO.
http://www.jsonschema2pojo.org/
I think the title of this is wrong but can't create a title that reflects, in the abstract, what I want to achieve.
I am writing a function which calls a service and retrieves data as a JSON string. The function parses the string with a JSON type provider. Under certain conditions I want to amend properties on that JSON object and then return the string of the amended object. So if the response from the call was
{"property1" : "value1","property2" : "value2", "property3": "value3" }
I want to change property3 to a new value and then return the JSON string.
If the JsonProvider was mutable this would be an exercise like:
type JsonResponse =
JsonProvider<""" {"property1" : "value1",
"property2" : "value2",
"property3": "value3" } """>
let jsonResponse = JsonResponse.Parse(response)
jsonResponse.Property3 <- "new value"
jsonResponse.ToString()
However, this does not work as the property cannot be set. I am trying to ascertain the best way to resolve this. I am quite happy to initialise a new object based on the original response but with amended parameters but I am not sure if there is an easy way to achieve this.
For reference, the JSON object is much more involved than the flat example given and contains a deep hierarchy.
Yes, you would need to create a new object, changing the bits you want and using the existing object's values for the rest. We added write APIs for both the XML and JSON type providers a while back. You will notice the types representing your JSON have constructors on them. You can see an example of this in use at the bottom of this link
Is it possible to parse a JSON message using GWT AutoBeans when one of the objects returned may be a collection but not always?
For example, if I have a JSON message returning an author and his/her associated writings, it's possible that there could be zero or more books being returned.
{ "name" : "William Gibson", "books" : { bookname : "Neuromancer" } }
could be one response, but so could this:
{ "name" : "William Gibson", "books" : [ { bookname: "Neuromancer"}, { bookname : "Pattern Recognition" } ] }
When I attempt to model this with an interface to be used for marshalling with an AutoBean, I get "expecting indexed data" errors if only one book is returned.
Interface for the AutoBean:
public interface Author {
#PropertyName(value="name")
String getAuthorName();
#PropertyName(value="book")
List<String> getBooks();
}
Snippet of error:
java.lang.AssertionError: Expecting indexed data
at com.google.web.bindery.autobean.shared.impl.SplittableList.<init>(SplittableList.java:64)
Is this not possible with AutoBeans?
(Note: using GWT 2.5.0 GA)
If you have a List, AutoBeans expects a JSON array. That array could contain zero, one or more elements, but it has to be an array (or be absent).
I think you can make your getBooks method return a Splittable though. You could then know whether it's an array (isIndexed()) or not. If you need the array to contain objects, you'd then have to iterate on the array (size() and get(int)) and pass each element to AutoBeanCodex.decode() to decode them (or directly pass the splittable if it's not an array).
Assuming the following JSON structure:
{
\"is_something\": false,
\"name\": \"Some Name\",
\"subtype\": {
\"total\": 0.0
}
}
Instead of creating two autobean interfaces (one for the whole structure and one for the subtype), I would like to have one which contains all the properties.
public interface ExampleAutoBean {
#PropertyName("is_something")
boolean isSomething();
String getName();
#PropertyName("subtype.total")
double getTotal();
}
So, the getTotal() method is expected to contain the total property of the nested subtype in the JSON structure. I can't find any documentation in the source code or online which states whether or not this is possible.
Thanks in advance!
Nope: AutoBeans are designed to be a mapping from the JSON structure to Java interfaces, plus or minus collections like List, Set, and Map and String encodings of a long or a Date. Additionally, it is legal to have json like the following:
{
"some.property.with.dots" : "abcd",
"name" : "wxyz"
}
If the . character could only be used for traversing into sub-objects, there would be no way to have a getter for the first property.
I'm looking to create what I feel is probably a basic JSON object, but my limited knowledge of JSON is making it difficult.
I am trying to create an object that will ultimately be passed to a .NET AMSX web service. The parameter for the web service is a P1Request object, which is defined as follows:
Public Class P1RequestClause
Public Property FieldId() As Integer
Public Property OperatorId() As Integer
Public Property Value() As String
End Class
Public Class P1Request
Public Property Fields() As String()
Public Property Clauses() As P1RequestClause()
End Class
On the client side, I have a number of different form fields, the values of which I would like to wrap up in a JSON object to pass.
I am unsure of what structure my JSON object needs to match the .NET class.
Ideally my data, in psudocode, would look like:
P1Request:
Fields:
Field1,
Field2,
Field3
Clauses:
P1RequestClause:
Id1,
OpId1,
SomeValue
P1RequestClause:
Id2,
Opid2,
AnotherValue
What would this look like in JSON? It's the array of Fields in P1Request is the part that confuses me the most. As I understand JSON, it's all name:value pairs, and making an array of a single field is throwing me.
{
"Fields": [
"moo",
"says",
"the cow"
],
"Clauses": [
{
"FieldId": 1,
"OperatorId": 3,
"Value": "foo"
},
{
"FieldId": 2,
"OperatorId": 0,
"Value": "bar"
}
]
}
JSON consists of primitive types (numbers, strings, null...), objects (which are key-value pair collections), and arrays, which is what you were missing.