This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 5 years ago.
I have these two classes:
public class MyParent
{
public string a;
public MySub[] b;
}
public class MySub
{
public int sub;
}
I initialize them like this:
myPC = new MyParent();
myPC.a = "test";
myPC.b = new MySub[2];
myPC.b[0] = new MySub();
myPC.b[1] = new MySub();
myPC.b[0].sub = 1;
myPC.b[2].sub = 2;
But when I serialize the object, The result is only {"a":"test"}
string json = JsonUtility.ToJson(myPC);
Debug.Log(json); // {"a":"test"}
How do I do that correctly and convert JSON back to an object?
Internally, JsonUtility uses the Unity Serializer; therefore the object you pass in must be supported by the serializer: it must be a MonoBehaviour, ScriptableObject, or plain class/struct with the Serializable attribute applied.
To ensure a custom class can be serialized, it needs the Serializable attribute
and must follow these rules:
Is not abstract
Is not static
Is not generic, though it may inherit from a generic class
Change your custom class to this:
[System.Serializable]
public class MyParent
{
public string a;
public MySub[] b;
}
[System.Serializable]
public class MySub
{
public int sub;
}
For more in-depth information on Script Serialization, check the official documentation: https://docs.unity3d.com/Manual/script-Serialization.html
Related
I have a rest service which returns marker interface and this interface have multiple implementations and don't have any common property in the implementations.
#RequestMapping(value = "/users/{userName}", method = RequestMethod.GET)
public User getUser(#PathVariable("userName") String userName) {
return userService.getUser(userName);
}
User and its implementations.Note : User is marker interface.
public interface User {}
public AdminUser implements User { // some properties & its setters & getters }
public SupportUser implements User { // some properties & its setters & getters }
I use Jackson 1.9.1 to serialize and deserialize.
When I hit above service, I am getting below response
{}
When I debug it, I see user implementation object is prepared and sent back to Jackson for serialization.But jackson is sending empty response to browser.Can anyone suggest how to use serialize when return type is marker interface.
Use #JsonTypeInfo and #JsonSubTypes to deserialization polymorphic types, which maintain sub type information while serializing java object and recreate the exact sub type.
Lets take a example, animal is a Interface and it can be an tiger or a lion, and they both extend the Animal Interface . While deserializing we want to create the exact animal type and demonstrate the use of #JsonTypeInfo and #JsonSubTypes annotations.
#JsonTypeInfo(use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY,
property="name")
#JsonSubTypes({
#JsonSubTypes.Type(value=Lion.class, name="lion"),
#JsonSubTypes.Type(value=Tiger.class, name="tiger"),
})
public interface Animal {
}
#JsonTypeName("lion")
public class Lion implements Animal {
private String name;
private String roar;
//constructor & setters & getters
}
#JsonTypeName("tiger")
public class Tiger implements Animal {
private String name;
private String purr;
//constructor & setters & getters
}
Main Method :
List<Animal> animal = new ArrayList<Animal>();
animal.add(new Lion("lion", "roar"));
animal.add(new Tiger("tiger", "purr"));
animal.add(new Tiger("tiger", "purrrrrrrrr"));
URL url = JacksonPolymorphicSerialization.class.getClassLoader().getResource("animals.json");
File file = new File(url.getPath());
// de-serailization sub types
new ObjectMapper().writeValue(file, animal);
// serailization animals and its subtype
List<Animal> animals = new ObjectMapper().readValue(file, List.class);
System.out.println(animals);
output : [{name=lion, roar=roar}, {name=tiger, purr=purr}, {name=tiger, purr=purrrrrrrr}]
Hope this helps you understanding serializing and deserializing polymorphic types using Jackson.
You can use #JsonTypeInfo annotation which adds a property to share type information between serializing/deserializing.
Read more here: JsonTypeInfo.html
I want to convert Optional<BigDecimal> in morphia. I created BigDecimalConverter, and it works fine. Now I want to create OptionalConverter.
Optional can hold any object type. In my OptionalConverter.encode method I can extract underlying object, and I'd like to pass it to default mongo conversion. So that if there is string, I'll just get string, if there is one of my entities, I'll get encoded entity. How can I do it?
There are two questions:
1. How to call other converters?
2. How to create a converter for a generic class whose type parameters are not statically known?
The first one is possible by creating the MappingMongoConveter and the custom converter together:
#Configuration
public class CustomConfig extends AbstractMongoConfiguration {
#Override
protected String getDatabaseName() {
// ...
}
#Override
#Bean
public Mongo mongo() throws Exception {
// ...
}
#Override
#Bean
public MappingMongoConverter mappingMongoConverter() throws Exception {
MappingMongoConverter mmc = new MappingMongoConverter(
mongoDbFactory(), mongoMappingContext());
mmc.setCustomConversions(new CustomConversions(CustomConverters
.create(mmc)));
return mmc;
}
}
public class FooConverter implements Converter<Foo, DBObject> {
private MappingMongoConverter mmc;
public FooConverter(MappingMongoConverter mmc) {
this.mmc = mmc;
}
public DBObject convert(Foo foo) {
// ...
}
}
public class CustomConverters {
public static List<?> create(MappingMongoConverter mmc) {
List<?> list = new ArrayList<>();
list.add(new FooConverter(mmc));
return list;
}
}
The second one is much more difficult due to type erasure. I've tried to create a converter for Scala's Map but haven't found a way. Unable to get the exact type information for the source Map when writing, or for the target Map when reading.
For very simple cases, e.g. if you don't need to handle all possible parameter types, and there is no ambiguity while reading, it may be possible though.
Since version 1.4.2 of XStream, the XStreamConverter annotation takes additional parameters (very good feature and just what I need).
#XStreamConverter(value=CustomXStreamConverter.class, strings={xyz"})
private List<String> phones;
But how can I read this values (xyz) in my custom converter?
public class CustomXStreamConverter implements Converter {
//?
}
I figure out the solution, just override the class constructor in order to receive the parameter.
public class CustomXStreamConverter implements Converter {
private String alias;
public ListToStringXStreamConverter(String alias) {
super();
this.alias = alias; //xyz
}
//...
I am trying to send over MyClass through RPC, but am getting :
Type MyClass was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer.For security purposes, this type will not be serialized.
I have looked at GWT - occasional com.google.gwt.user.client.rpc.SerializationException and tried their solution, but it did not work.
The difference is that MyClass is located in another project.
The project structure is:
MyApiProject
-contains MyClass
MyClientProject
MyServerProject
I have also tried passing an enum through the RPC from MyApiProject, which also failed.
public class MyClass
implements Serializable
{
private static final long serialVersionUID = 5258129039653904120L;
private String str;
private MyClass()
{
}
public MyClass(String str)
{
this.str = str;
}
public String getString()
{
return this.str;
}
}
in the RemoteService I have:
mypackage.MyClass getMyClass();
in the RemoteServiceAsync I have:
void getMyClass(AsyncCallback<mypackage.MyClass> callback);
I had to change implements Serializable to implements IsSerializable
This usually pops up when you are using another type inside of your class that is not serializable. Check the properties of your class and make sure they are all serializable, post the code of MyClass here and I can look at it as well.
I believe GWT requires an RPC serializable class to also have a public no-argument constructor.
Try removing
private MyClass()
{
}
or set it to
public MyClass()
{
}
In my application I'm getting some data from a file located in the server. The data is stored in a text file (.obj), so I'm using an rpc to read the file and get the data. The file is read using a third party library http://www.pixelnerve.com/processing/libraries/objimport/ I'm sending the data to the client using ArrayLists, basicly I'm sending this: ArrayList[ArrayList[Vertex3dDTO]] where Vertex3dDTO is an serializable object with contains float parameters. ArrayList[Vertex3dDTO] is contained in another serializable class Face3dDTO, and ArrayList[Face3dDTO] is in the serializable class Group3dDTO.
package com.nyquicksale.tailorapp.shared;
import java.io.Serializable;
public class Vertex3dDTO implements Serializable {
float x,y,z;
public Vertex3dDTO(){
}
public Vertex3dDTO(float x, float y, float z){
this.x = x;
this.y = y;
this.z = z;
}
}
public class Face3dDTO implements Serializable {
ArrayList<Vertex3dDTO> vL = new ArrayList<Vertex3dDTO>();
Vertex3dDTO normal = new Vertex3dDTO();
Vertex3dDTO color = new Vertex3dDTO();
public Face3dDTO(){
}
public Face3dDTO(ArrayList<Vertex3dDTO> v) {
for(Vertex3dDTO v3dDTO : v){
vL.add(v3dDTO);
}
updateNormal();
}
public class Group3dDTO implements Serializable {
ArrayList<Face3dDTO> fL = new ArrayList<Face3dDTO>();
String name;
public Group3dDTO(){
}
public Group3dDTO(ArrayList<Face3dDTO> f) {
for(Face3dDTO f3dDTO : f){
fL.add(f3dDTO);
}
}
}
Now, everything is working well in development mode, but when I tested the application in hosted mode, everything I receive as response is: //OK[0,1, ["java.util.ArrayList/4159755760"],0,7]
So, I've been checked some other questions and seems the problem is about deserialization, but I've not found anything concrete.
The question is what do I have to do to get the app working well in hosted mode?
To successfully use RPC, your object needs to implement Serializable and should also have a default no arg constructor
Have you made sure this is a serialization problem? You can write a simple RPC test method to pass an array list of your DTO's over the wire in hosted mode.
If I were to bet money on a guess, I would say the problem is those array lists are sent empty in hosted mode. The .obj file read could be the problem. Perhaps in hosted mode the path of file doesn't match as in dev mode(different server configurations perhaps?), since file operations are in a try catch block an exception is most likely swallowed.
Long word short, Did you make sure those array lists are not sent empty in hosted mode?
Your object may well be Serializable, but that doesn't equate to something usable by Remote Procedure Calls. You need to implement Serializable, have a default contructor with no arguments (that calls super() if necessary), and a serial version ID, like so:
public class MyObject implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1796729355279100558L;
private Float someValue;
public MyObject() {
super();
}
public MyObject(Float someValue) {
super();
this.someValue = someValue;
}
public Float getSomeValue() {
return someValue;
}
public void setSomeValue(Float someValue) {
this.someValue = someValue;
}
}