1)我试图像这样在ResourceResolverFactory类中注入SlingModel:
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,下面是错误:
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:
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 )
完全跟着它,但却找不到决议。任何帮助都是非常感谢的。
提前谢谢。
发布于 2017-10-19 17:16:54
我看到您正在使用OSGI声明性服务(DS)。
有几件事:
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工作得很好,但特定的注入器对可读性和性能更好,尽管性能不高,因为我们只使用特定的注入器。
这里是一个使用您的代码的服务示例:
气象服务界面:
package com.aem.sites.services;
public interface WeatherService
{
public String checkApps();
}气象服务推动:
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() {
}
}横幅模型:
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读取一些属性,或者您希望启动一个工作流.在这种情况下,将这些代码保存在服务中而不是模型本身中更有组织,并且可能会对其进行泛化,以便在其他模型中重用它。
https://stackoverflow.com/questions/46822745
复制相似问题