Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

ResourceResolver getResource returns null inside servlet

Avatar

Level 3

On AEM 6.5.3, I'm trying to create a content fragment programmatically inside a servlet using a content fragment model. This is my code. The content fragment model and parent folder do exist in the JCR at the paths I am specifying in modelPath and targetFolderPath, but resourceResolver.getResource is returning null for both. What am I doing wrong?

 

package com.ab.mysite.core.servlets;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import javax.servlet.Servlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.cq.dam.cfm.ContentFragment;
import com.adobe.cq.dam.cfm.ContentFragmentManager;
import com.adobe.cq.dam.cfm.FragmentTemplate;
import org.apache.sling.api.servlets.ServletResolverConstants;

@Component(
	service=Servlet.class,
	property= {
		Constants.SERVICE_DESCRIPTION+"=Bio Sync Servlet",
		"sling.servlet.paths="+"/bin/biosync",
		ServletResolverConstants.SLING_SERVLET_METHODS + "=POST"
	}	
)
public class BioSyncServlet extends SlingAllMethodsServlet {

	private static final long serialVersionUID = 1L;
	private static final Logger log = LoggerFactory.getLogger(BioSyncServlet.class);	
	
	@Reference 
	private ContentFragmentManager fragmentManager;
    	
	@SuppressWarnings("deprecation")
	@Override
	protected void doPost(
			SlingHttpServletRequest request, 
			SlingHttpServletResponse response)	
	{
		try {			
			ResourceResolver resourceResolver = request.getResourceResolver();
			
			String modelPath = "/conf/mysite/settings/dam/cfm/models/test-model";
			String targetFolderPath = "/content/dam/mysite/us/en/content-fragments/test";
			
			Resource contentFragmentModel = resourceResolver.getResource(modelPath);
			Resource parentFolder = resourceResolver.getResource(targetFolderPath);
			
			ContentFragment fragment = null;
			
			// depreciated way to create
			fragment = fragmentManager.create(parentFolder, contentFragmentModel, "test", "test");
			
			// recommended way
			fragment = contentFragmentModel.adaptTo(FragmentTemplate.class).createFragment(parentFolder, "test", "test");
		} 
		catch (Exception ex) {
			log.error(ex.getMessage());
		}
	}
}

 

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @mpalme1 ,

 

Try to get the resource resolver from servlet request object as,

                ResourceResolver resourceResolver = null;
                resourceResolver = request.getResourceResolver();   or

Create system user and use the subservice to get the ResourceResolver from ResourceResolverFactory.

              Map<String, Object> param = new HashMap<String, Object>();
              param.put(ResourceResolverFactory.SUBSERVICE, "<systemUser>");
              ResourceResolver resolver = null;
              resolver = resolverFactory.getServiceResourceResolver(param);

 

Regards,

Santosh

View solution in original post

3 Replies

Avatar

Level 8

Hi @mpalme1 

Whenever we need to write/create content on JCR, we should create service user with required permission & using ResourceResolverFactory we need to get the service resource resolver by passing service user details. request.getResourceResolver() will be anonymous on publisher instance whenever it gets request from user & will not be having write permission to write/create content on JCR.

 

 

@Reference
private ResourceResolverFactory resourceResolverFactory;

private static final Map<String, Object> AUTH_DETAILS = ImmutableMap
.of(ResourceResolverFactory.SUBSERVICE, (Object) "writeServiceTest"); //create new service user with proper name & required permission

try
(ResourceResolver resourceResolver = resourceResolverFactory.getServiceResourceResolver(AUTH_DETAILS)){
//code to create content using service resource resolver
}catch (LoginException e) {
LOGGER.error("LoginException occurred", e);
}

 

 

 

Avatar

Community Advisor

It seems to be an User and permission issue, please check the service user and its permission.

Avatar

Correct answer by
Community Advisor

Hi @mpalme1 ,

 

Try to get the resource resolver from servlet request object as,

                ResourceResolver resourceResolver = null;
                resourceResolver = request.getResourceResolver();   or

Create system user and use the subservice to get the ResourceResolver from ResourceResolverFactory.

              Map<String, Object> param = new HashMap<String, Object>();
              param.put(ResourceResolverFactory.SUBSERVICE, "<systemUser>");
              ResourceResolver resolver = null;
              resolver = resolverFactory.getServiceResourceResolver(param);

 

Regards,

Santosh