首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ResourceResolverFactory在服务中为空,在Sling模型类中抛出LoginException

ResourceResolverFactory在服务中为空,在Sling模型类中抛出LoginException
EN

Stack Overflow用户
提问于 2017-10-19 04:14:18
回答 1查看 5.6K关注 0票数 1

1)我试图像这样在ResourceResolverFactory类中注入SlingModel:

代码语言:javascript
复制
package com.aem.sites.models;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aem.sites.services.WeatherService;


@Model(adaptables=Resource.class)
public class Banner {

    final static Logger logger = LoggerFactory.getLogger(Banner.class);

    @Inject
    private WeatherService weatherService;

    private String serviceEndpoint;

    private String apiKey;

    private String temperature;

    @Inject
    @Optional
    @Named("bannerText")
    private String bannerText;

    @Inject
    @Optional
    @Named("button1Text")
    private String button1Text;

    @Inject
    @Optional
    @Named("button2Text")
    private String button2Text;

     @Inject
    private ResourceResolverFactory resourceResolverFactory;

        @PostConstruct
        public void init() {
            serviceEndpoint = weatherService.getServiceEndpoint();
            apiKey = weatherService.getApiKey();
            temperature = weatherService.getTemperatureValue()+" "+weatherService.getUnit();
            checkTemperatureProperty();
        }


        public String getServiceEndpoint() {
            return serviceEndpoint;
        }

        public String getApiKey() {
            return apiKey;
        }


        public String getTemperature() {
            return temperature;
        }


        public String getBannerText() {
            return bannerText;
        }


        public String getButton1Text() {
            return button1Text;
        }


        public String getButton2Text() {
            return button2Text;
        }

        private void checkTemperatureProperty() {
            logger.info("**********************checkTemperatureProperty****************");
            Map<String, Object> param = new HashMap<String, Object>();
            param.put(ResourceResolverFactory.SUBSERVICE,"getResourceResolver");
            ResourceResolver resourceResolver = null;
            try {
                if(resourceResolverFactory == null) {
                    logger.info("***********************resourceResolverFactory is null******************************");
                }
                else {
                    resourceResolver = resourceResolverFactory.getServiceResourceResolver(param);
                    logger.info("**********************resource resolver id****************"+resourceResolver.getUserID());
                    //Resource resource = resourceResolver.getResource("/content/aemsite/en/jcr:content/root/responsivegrid/banner");
                    //ValueMap readMap = resource.getValueMap();
                    //logger.info(readMap.get("temperature", ""));
                }
            }
            catch (LoginException e) {
                logger.error("LoginException",e);
            } finally{
                if(resourceResolver != null && resourceResolver.isLive()){
                    resourceResolver.close();
                }
            }
        }

}

这里讨论的方法是checkTemperatureProperty()。我创建了如下所示的系统用户:

我还配置了Mapper服务修正案如下:

包的符号名如下所示:

ResourceResolverFactor注入在Sling Model类中抛出LoginException,下面是错误:

代码语言:javascript
复制
com.aem.sites.models.Banner LoginException
org.apache.sling.api.resource.LoginException: Cannot derive user name for bundle org.apache.sling.models.impl [489] and sub service getResourceResolver
    at org.apache.sling.resourceresolver.impl.ResourceResolverFactoryImpl.getServiceResourceResolver(ResourceResolverFactoryImpl.java:86)

当我试图使用@Reference在服务中使用ResourceResolverFactory时,它将抛出一个空指针异常。

下面给出了所讨论的类,方法checkTemperatureProperty()行号195:

代码语言:javascript
复制
package com.aem.sites.services.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Reference;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aem.sites.interfaces.Configuration;
import com.aem.sites.pojos.CurrentConditions;
import com.aem.sites.services.WeatherService;
import com.google.gson.Gson;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.resource.LoginException;


// TODO: Auto-generated Javadoc
/**
 * The Class WeatherServiceImpl.
 */
@Component(service = WeatherService.class,
immediate = true,
configurationPid = "com.aem.sites.services.impl.WeatherServiceImpl")
@Designate(ocd = Configuration.class)
public class WeatherServiceImpl implements WeatherService {

    /** The Constant logger. */
    final static Logger logger = LoggerFactory.getLogger(WeatherServiceImpl.class);

    /** The service endpoint. */
    private String serviceEndpoint;

    /** The api key. */
    private String apiKey;

    /** The response body. */
    private String responseBody;

    /** The temperature value. */
    private String temperatureValue;

    /** The unit. */
    private String unit;

    /** The resource resolver factory. */
    @Reference
    private ResourceResolverFactory resourceResolverFactory;

    /* (non-Javadoc)
     * @see com.aem.sites.services.WeatherService#getServiceEndpoint()
     */
    @Override
    public String getServiceEndpoint() {
        return serviceEndpoint;
    }

    /* (non-Javadoc)
     * @see com.aem.sites.services.WeatherService#getApiKey()
     */
    @Override
    public String getApiKey() {
        return apiKey;
    }

    /**
     * Activate.
     *
     * @param config the config
     */
    @Activate
    @Modified
    protected final void activate(Configuration config) {
        logger.info("**********************************************activate********************************************");
        serviceEndpoint = config.getServiceURL();
        apiKey = config.getApiKey();
        String serviceURL = createRequestURL();
        logger.info("**************************The serviceURL is*******************************************"+serviceURL);
        callWebService(serviceURL);
        String responseString = getResponseBody();
        logger.info("**************************The response body is*******************************************"+responseString);
        convertStringToPojos(responseString);
        checkTemperatureProperty();
        //saveTemperatureInTheNode();

    }

    /**
     * Creates the request URL.
     *
     * @return the string
     */
    private String createRequestURL() {
        StringBuilder sb = new StringBuilder(); ;
        if(!StringUtils.isEmpty(serviceEndpoint)) {
            sb.append(serviceEndpoint);
            sb.append("/currentconditions/v1/33785");
            sb.append("?apikey=");
            sb.append(apiKey);
        }
        return sb.toString();
    }

    /**
     * Call web service.
     *
     * @param serviceURL the service URL
     */
    private void callWebService(String serviceURL) {
        if(!StringUtils.isEmpty(serviceURL))  {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            HttpGet httpget = new HttpGet(serviceURL);
            CloseableHttpResponse response = null;
            try {
                response = httpclient.execute(httpget);
                HttpEntity entity = response.getEntity();
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    if (entity != null) {
                        String responseString = EntityUtils.toString(entity);
                        setResponseBody(responseString);
                    }
                }
                else {
                    logger.info("*********************Unexpected response status: " + status);
                }
            } catch (IOException | UnsupportedOperationException e) {
                // TODO Auto-generated catch block
                logger.info("***********************************inside catch block****************IOException"+e.getMessage());
            }
            finally {
                if(null != response){
                    try {
                        response.close();
                        httpclient.close();
                    } catch (IOException e) {
                        logger.info("***********************************inside finally block****************IOException"+e.getMessage());
                    }
                }
            }
        }
    }

    /**
     * Convert string to pojos.
     *
     * @param jsonString the json string
     */
    private void convertStringToPojos(String jsonString) {
        if(!StringUtils.isEmpty(jsonString))  {
            jsonString = jsonString.substring(1);
            if(!StringUtils.isEmpty(jsonString))  {
                int ind = jsonString.lastIndexOf("]");
                if(ind >= 0) {
                    jsonString = jsonString.substring(0,jsonString.length()-1);
                }
                Gson gson = new Gson();
                if(!StringUtils.isEmpty(jsonString))  {
                    CurrentConditions conditions = gson.fromJson(jsonString, CurrentConditions.class);
                    logger.info("***************current temperature is*****************"+conditions.getTemperature().getImperial().getValue());
                    temperatureValue = conditions.getTemperature().getImperial().getValue();
                    unit = conditions.getTemperature().getImperial().getUnit();
                }
            }
        }
    }


    /**
     * Save temperature in the node.
     */
    private void checkTemperatureProperty() {
        logger.info("**********************checkTemperatureProperty****************");
        Map<String, Object> param = new HashMap<String, Object>();
        param.put(ResourceResolverFactory.SUBSERVICE,"getResourceResolver");
        ResourceResolver resourceResolver = null;
        try {
            resourceResolver = resourceResolverFactory.getServiceResourceResolver(param);
            logger.info("**********************resource resolver id****************"+resourceResolver.getUserID());
            Resource resource = resourceResolver.getResource("/content/aemsite/en/jcr:content/root/responsivegrid/banner");
            ValueMap readMap = resource.getValueMap();
            logger.info(readMap.get("temperature", ""));
        }
        catch (LoginException e) {
            logger.error("LoginException",e);
        } finally{
            if(resourceResolver != null && resourceResolver.isLive()){
                resourceResolver.close();
            }
        }
    }

    private void saveTemperatureProperty() {

    }

    /**
     * Gets the response body.
     *
     * @return the response body
     */
    public String getResponseBody() {
        return responseBody;
    }

    /**
     * Sets the response body.
     *
     * @param responseBody the new response body
     */
    public void setResponseBody(String responseBody) {
        this.responseBody = responseBody;
    }

    /* (non-Javadoc)
     * @see com.aem.sites.services.WeatherService#getTemperatureValue()
     */
    @Override
    public String getTemperatureValue() {
        // TODO Auto-generated method stub
        return temperatureValue;
    }

    /* (non-Javadoc)
     * @see com.aem.sites.services.WeatherService#getUnit()
     */
    @Override
    public String getUnit() {
        // TODO Auto-generated method stub
        return unit;
    }

    /**
     * Deactivate.
     */
    @Deactivate
    protected void deactivate() {
    }
}

我首先尝试在服务类(第二类)中使用ResourceResolverFactory,然后在Banner.java(第一类)中使用。但在这两种情况下都没有用。

我已经阅读了各种教程,以及在这里提出的关于堆栈溢出的类似问题。其中一些人在这里:

ResourceResolverFactory getServiceResourceResolver在AEM6.1中抛出异常

服务类中的ResourceResolverFactory和SlingRepository null

ResourceResolverFactory为NULL (Adobe )

完全跟着它,但却找不到决议。任何帮助都是非常感谢的。

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-19 17:16:54

我看到您正在使用OSGI声明性服务(DS)。

有几件事:

  1. 如果您是而不是使用SCR注释的,则应该从POM/s中删除SCR依赖项以消除混淆。
  2. 如果您只使用OSGI,则必须具有以下内容:
    • 阅读Nate的优秀帖子
    • 您的maven-bundle-plugin依赖项必须是版本3.2.0或更高版本。
    • 您必须在包org.osgi.service.component.annotations中使用注释,而不是在org.apache.felix.scr.annotations.Reference包中使用SCR注释。

在您的气象服务中,我看到您使用的是SCR的@Reference,而不是OSGI的@Reference

吊索模型中的:您应该为服务使用OSGI服务注入器:@OSGiService虽然使用@Inject工作得很好,但特定的注入器对可读性和性能更好,尽管性能不高,因为我们只使用特定的注入器。

这里是一个使用您的代码的服务示例:

气象服务界面:

代码语言:javascript
复制
package com.aem.sites.services;

public interface WeatherService
{
  public String checkApps();

}

气象服务推动:

代码语言:javascript
复制
package com.aem.sites.services.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.felix.scr.annotations.Reference;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aem.sites.services.Configuration;
import com.aem.sites.services.WeatherService;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.LoginException;



/**
 * The Class WeatherServiceImpl.
 */
@Component(service = WeatherService.class,
        immediate = true,
        configurationPid = "com.aem.sites.services.impl.WeatherServiceImpl")
@Designate(ocd = Configuration.class)
public class WeatherServiceImpl implements WeatherService {

  /** The Constant logger. */
  final static Logger logger = LoggerFactory.getLogger(WeatherServiceImpl.class);


  /** The resource resolver factory. */
  @Reference
  private ResourceResolverFactory resourceResolverFactory;

  private ResourceResolver resolver;


  /**
   * Activate.
   *
   * @param config the config
   */
  @Activate
  @Modified
  protected final void activate(Configuration config) {}



  /**
   * check if we can get /apps resource, print weather it's null or not
   */
  public String checkApps() {
    logger.info("*************** checkApps");
    Map<String, Object> param = new HashMap<String, Object>();
    param.put(ResourceResolverFactory.SUBSERVICE,"getResourceResolver");
    ResourceResolver resourceResolver = null;
    try
    {
      resourceResolver = resourceResolverFactory.getServiceResourceResolver(param);
      logger.info("*************** resource resolver user id: "+resourceResolver.getUserID());
      Resource appsResource = resourceResolver.getResource("/apps");

      // return appropriate msg
      return appsResource == null
             ? "apps resource is null"
             : "apps resource is NOT null";

    }
    catch (LoginException e)
    {
      logger.error("LoginException",e);
      return e.toString();
    }
    finally
    {
      if(resourceResolver != null && resourceResolver.isLive()){
        resourceResolver.close();
      }
    }

  }
  /**
   * Deactivate.
   */
  @Deactivate
  protected void deactivate() {
  }
}

横幅模型:

代码语言:javascript
复制
package com.aem.sites.models;

import javax.annotation.PostConstruct;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aem.sites.services.WeatherService;


@Model(adaptables=Resource.class)
public class Banner {

  final static Logger logger = LoggerFactory.getLogger(Banner.class);

  @OSGiService
  private WeatherService weatherService;

  private String msg;

  @PostConstruct
  public void init() {
    msg = weatherService.checkApps();
  }

  public String getMsg() {
    return msg;
  }

}

显示msg的简单组件:

<h1 data-sly-use.banner="com.aem.sites.models.Banner">${banner.msg}</h1>

更新:关于resourceResolver在吊索模型中的使用:

最好将逻辑保持在单独的服务中,而不使用模型的资源/资源解析器。在您的代码中,Banner#checkTemperatureProperty应该在服务中而不是在模型本身中。

这是我个人的观点,这里没有对错:

您始终可以通过注入resourceResolver模型或通过注入资源或请求来获取吊带模型中的解析器,然后从资源/请求中获取解析器。在任何一种情况下,您都会得到一个与请求用户具有相同权限的resourceResolver,这对于组件来说是首选的。例如,如果您需要从同一页面上的不同组件或一般的/content中获取一个资源,这就是方法。

如果您有一个需要执行操作的用例--请求用户或匿名用户没有足够的权限来执行,也不想为其授予权限,则可以通过具有足够权限的系统用户获得resourceResolver。例如,您希望从/apps读取一些属性,或者您希望启动一个工作流.在这种情况下,将这些代码保存在服务中而不是模型本身中更有组织,并且可能会对其进行泛化,以便在其他模型中重用它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46822745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档