MappingJackson2HttpMessageConverter doesn't seem to work #408

I’m trying to add a customer HttpMessageConverter to my portal module, but it doesn’t seem to work. I need JSON to ignore the metaclass and some other fields that are a part of the standardEntity class. Do you guys have a working example I can use to figure this out?

Hi, Kent!
I think, you can try the CUBA JSONConvertor. This class is used by the REST API for entities serialization/deserialization. It can convert an entity to the JSON string. Fields that must be serialized can be restricted by the view object.
I attached a demo project. Take a look at the EntitiesController#getBookWithCubaJsonCoverter().
If you still want to use a Jackson message converter, then I think you’ll have to set a custom ObjectMapper to the MappingJackson2HttpMessageConverter. This objectMapper must use a custom serializer for the Entity class. You’ll have to implement the serializer by yourself. Take a look at the EntitiesController#getBookWithJacksonCoverter() and at the CustomObjectMapper class of the attached demo.
BTW, we plan to introduce a new REST API in the release 6.3 (September 2016). The new API will allow you to address entities as resources by the URI (like this: http://localhost:8080/app/api/entities/sec$User/353e71e5-fc8d-d1c6-a742-68cb843f0f3e), perform CRUD operations by HTTP methods, executed predefined JPQL queries by http requests, get metadata and so on.

portal-demo.zip (146.5K)

That works great! Now how do I customize besides just having it conform to a view. I’d like to not include null values at times or change the date format etc.

Thanks!

Also how do we apply a view for a child entity?

The datetime format in JSONConverter response is taken from the datatypes.xml file. So if you want another format you’ll have to change it globally in the datatypes.xml. See https://doc.cuba-platform.com/manual-6.1/datatypes.xml.html and https://doc.cuba-platform.com/manual-6.1/datatype.html for details.

As for ignoring nulls, there is no such option. If the property is included in the view then the value will be placed into the result JSON. As a workaround, in the controller, you can build the view object on the fly not including some properties if their values in the entity are null.

The view that is passed to the JSONConverter must describe the whole view hierarchy including child entities.

JSONConvertor seems to be working fine, however I don’t like that it adds the name of the entity as a prefix to the id. I’m passing a list of items back to my angular app. On update I’m passing back JSON, but the object mapper doesn’t like that the id has the entity name in it. Is there a simple work around to this? I should be able to receive the response json and use that information to store in my JS array. Then on update or delete I should be able to make a call using the id to modify or remove the item.

I don’t quite understand what object mapper are you writing about? Do you encode an entity using JSONConverter and decode the JSON using your custom object mapper? If so then you have to use JSONConverter.parseEntity(String content) method to decode the JSON.

I’m returning a list of phones from cuba. JSONConvertor transforms this into JSON for me, but it add a prefix of project$table- to the id field.
“id”:“8” becomes “id”:“edge$ApplicantPhone-8”

No on my angular side I have a javascript array that I turn into the view. This allows the user to click on one from the list to modify. Once they submit the change, I pass the json over to cuba.

I’ve been using:
MetaClass metaClass = metadata.getClassNN(ApplicantPhone.class);
ObjectMapper objectMapper = new ObjectMapper();
ApplicantPhone newPhone = objectMapper.readValue(phone, ApplicantPhone.class);

this blows up because it doesn’t like the prefix added to the id field because it’s trying to store an int. Is there a better solution to passing json back and forth that works with the prefix or is there a simple way to tell it not to add the prefix?

I tried using JSONConvertor.parseEntity in the past, but it would blow up. I think I’ve tracked down why. When I pull this list of Phone records it has an association to PhoneType entity. When I run JSONConvertor.process it creates the json but places 2 “id” fields within the record. When my angular app receives the string it looks like it replaces the first occurrence with the second.

This is how it looks from JSONConvertor:


[
    {"id":"edge$ApplicantPhone-8",
        "createTs":"2016-08-06 10:52:37.150",
        "createdBy":"admin",
        "deleteTs":null,
        "deletedBy":null,
        "phoneNumber":"66666666666",
        "phoneType":{"id":"edge$PhoneType-{HOME}",
            "createTs":"2016-05-16 16:12:01.373",
            "createdBy":"ptaylor",
            "deleteTs":null,
            "deletedBy":null,
            "id":"HOME",
            "name":"home",
            "updateTs":"2016-08-07 22:35:43.340",
            "updatedBy":"admin"
        },
        "updateTs":"2016-08-07 22:35:43.340",
        "updatedBy":"admin"
    },
    {"id":"edge$ApplicantPhone-18",
        "createTs":"2016-08-07 15:03:42.837",
        "createdBy":"admin",
        "deleteTs":null,
        "deletedBy":null,
        "phoneNumber":"33333333333",
        "phoneType":{"id":"edge$PhoneType-{fax}",
            "createTs":"2016-06-29 15:37:36.250",
            "createdBy":"kbeesley",
            "deleteTs":null,
            "deletedBy":null,
            "id":"fax",
            "name":"Fax",
            "updateTs":"2016-08-07 22:36:27.303",
            "updatedBy":"admin"
        },
        "updateTs":"2016-08-07 22:36:27.303",
        "updatedBy":"admin"
    }
]

This is how it looks within my angular app response.json():


{"id":"edge$ApplicantPhone-18","createTs":"2016-08-07 15:03:42.837","createdBy":"admin","deleteTs":null,"deletedBy":null,"phoneNumber":"33333333333","phoneType":{"id":"fax","createTs":"2016-06-29 15:37:36.250","createdBy":"kbeesley","deleteTs":null,"deletedBy":null,"name":"Fax","updateTs":"2016-08-07 22:36:27.303","updatedBy":"admin"},"updateTs":"2016-08-07 22:36:27.303","updatedBy":"admin"}

Does the identifier attribute of the PhoneType entity (the one annotated with @Id) has the name ‘id’? Seems that there is a bug in the REST API. It occurs for BaseStringIdEntity which has an @Id attribute named ‘id’. As a workaround you can change its name to something else (‘code’ for example). This should work for now.