Override JSON Serialization inside SPA Page model request | Community
Skip to main content
November 14, 2022
Question

Override JSON Serialization inside SPA Page model request

  • November 14, 2022
  • 1 reply
  • 2244 views

Hey folks,


I'm working on an implementation for custom Sling Model exporters that rely on a GSON-based export framework we've built. What I want to do is change the way the JSON serialization happens every time this component is serialized.

 

I have it working so that if I fetch the component directly:

 

http://localhost:4502/content/my-app/us/en/jcr:content/root/container/container/section_container/mycomponent_54231355.model.json

 

 

I get the custom JSON I am expecting. However, if I fetch the page:

 

http://localhost:4502/content/my-app/us/en.model.json

 

 

Then I just get the OOTB serialization for this component (which is nested in the child components for the page).

 

How can I override the way this component is serialized including as part of the full page JSON?

 

My component:

 

@Model( resourceType = Breadcrumb.RESOURCE_TYPE, adaptables = { Resource.class, SlingHttpServletRequest.class } ) @Exporter( name = CustomSlingModelExporter.NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION ) public class Breadcrumb extends Component { public static final String RESOURCE_TYPE = "my-app/components/breadcrumb"; // other fields and methods }

 

 

The exporter:

 

@org.osgi.service.component.annotations.Component(service = ModelExporter.class) public class CustomSlingModelExporter implements ModelExporter { public static final String NAME = "gson"; public <T> T export(@NotNull Object model, Class<T> clazz, Map<String, String> options) throws org.apache.sling.models.factory.ExportException { return (T) new Gson().toJson(model); } public String getName() { return NAME; } public boolean isSupported(@NotNull Class<?> clazz) { return clazz.equals(String.class); } }

 

 

 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

1 reply

SantoshSai
Community Advisor
Community Advisor
November 14, 2022
November 14, 2022

Hi Santosh,


I have reviewed the documents here but it doesn't explain why the code I have above does not work when requesting the full page. As far as I can tell, I've done what should be required, but I am still getting default (jackson) serialization when fetched at the page level.

November 14, 2022

@jamiec4451712 - Just to double check - I believe you have specified name and extension eg.

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL, resourceType = {
		"weretail/components/content/text" })

@Exporter(name = "jackson" , extensions = "json")
public class RickTextModel {
	
	@ValueMapValue
	private String text;

	
	@JsonRawValue
	public String getText() {
		return StringEscapeUtils.unescapeHtml4(text).replaceAll("\\<.*?\\>", "");
	}

}

Hi Santosh,


Yes I've specified the name of my custom exporter and the "json" extension. I did not modify the "selector" as I want this to still be ".model.". 

 

Here are the annotations on my Sling Model:

@Model(
    resourceType = MyComponent.RESOURCE_TYPE,
    adaptables = {
        Resource.class,
        SlingHttpServletRequest.class
    }
)
@Exporter(
    // default selector = "model"
    name = ComponentSlingModelExporter.NAME, // this is "gson"
    extensions = ExporterConstants.SLING_MODEL_EXTENSION // this is "json"
)
public class MyComponent {

}

But I don't want to use "jackson", I want to use this custom exporter instead, but just for this component. So, for example, the page JSON will be 99% Jackson serialized, and this component will be GSON serialized.