Expand my Community achievements bar.

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