1

Getting exception below while using Jackson api.See attached image.

enter image description here

class BlogSwiftJSONUtil {

static String parseToJSON(Object object){
        ObjectMapper objectMapper = new ObjectMapper()
        return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object)
    }
 }

Line below I have used to parse output json on all actions.

render contentType: 'application/json', text:BlogSwiftJSONUtil.parseToJSON(listAllResources(params))

Added jackson library in BuildConfig.groovy is as below:

dependencies {
        // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g.
        // runtime 'mysql:mysql-connector-java:5.1.29'
        // runtime 'org.postgresql:postgresql:9.3-1101-jdbc41'
        test "org.grails:grails-datastore-test-support:1.0.2-grails-2.4"
        runtime 'com.fasterxml.jackson.core:jackson-core:2.0.4'
        runtime 'com.fasterxml.jackson.core:jackson-databind:2.0.4'
        runtime 'com.fasterxml.jackson.core:jackson-annotations:2.0.4'
    }

Anyone why am I getting this exception.

Below are some findings from me:

  1. if I pass map like object.properties rather than object itself it works.
  2. It seems that it's also trying to serialize validation errors as well.

Any helps would be worth.

Please let me know if I could share any other details.

Thanks!

Adesh Kumar
  • 99
  • 11
Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86

2 Answers2

2

Inorder for jackson to marshall your response, you need a bean which has private field with public getter/setter or define a field with public visibility. From the screenshot you pasted, it seems somehow your api call failed which redirected for spring to handle the exception which jackson couldn't serialize.

You need to overcome this by adding following:

objectMapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);
SMA
  • 36,381
  • 8
  • 49
  • 73
  • 1
    There is nothing like Visibilty.ANY. I am using faster json 2.0 which has no such enum. – Vinay Prajapati Jan 02 '16 at 15:53
  • 2
    Then use `objectMapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker() .withFieldVisibility(JsonAutoDetect.Visibility.ANY) .withGetterVisibility(JsonAutoDetect.Visibility.NONE) .withSetterVisibility(JsonAutoDetect.Visibility.NONE) .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));` – SMA Jan 02 '16 at 16:24
  • it worked for me. Can you please add it to answer than in comment. – Vinay Prajapati Jan 02 '16 at 17:03
  • @SMA I believe it won't work in case you want to skip out some fields like in grails it will show version field that is added internally by gorm. In that either you will need to mark domain properties to be ignored which is not possible for version until it is declared in the domain. – Adesh Kumar Jan 02 '16 at 17:08
  • @SMA there is not an option for choosing both answers as correct on stackoverflow but softi venture's answer is more relevant to me. Hence, choosing it as answer. – Vinay Prajapati Jan 02 '16 at 17:27
  • @SoftIVenture I agree. But that's not the case with OP. See the class which its complaining.. – SMA Jan 02 '16 at 17:28
0

As you are using it for rest-api and would most probably serialise domains, enums and some custom read-only pojos. This issue is because of failure in serialising the validation errors which are injected to domains. You may customise domains to choose fields for serialisations and deserialisations.

See this.

To be more flexible manually add your own serialiser and give your own definitions as below:

Below is the way to add a custom serialiser

import com.blog.swift.marshaller.JacksonSerializer
import com.fasterxml.jackson.databind.Module
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.module.SimpleModule

class JSONUtil{
    static String parsetoJSON(Object object){
        ObjectMapper objectMapper = new ObjectMapper()

        Module testModule = new SimpleModule()
        testModule.addSerializer(new JacksonSerializer(object.getClass())); 
        objectMapper.registerModule(testModule)
        return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object)
        }
    }

Below is a sample custom serialiser.

class JacksonSerializer extends StdSerializer{
    protected BSJacksonSerializer(Class t) {
        super(t)
    }

    @Override
    void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
            jsonGenerator.writeStartObject()

            jsonGenerator.writeStringField("test","test")
            jsonGenerator.writeEndObject()
    }
}

StdSerializer is an abstract class which gives base implementations to help leverage focus on custom serialisation logic than exception handling and any other thing.

Hope it helps!

Community
  • 1
  • 1
Adesh Kumar
  • 99
  • 11
  • It works though I am just able to see {"test":"test"} . which means a lot need to be worked around for this but I believe this is the right place of doing customisation rather than in adding in domains. – Vinay Prajapati Jan 02 '16 at 17:04