1

我有一个服务类,如下所示,我使用 Maven 部署并在 Sling Web 控制台上处于活动状态。当我getSearchAssetNames()从这个捆绑包访问该方法时,它会根据 AEM 6.0 的 Authoring 实例日志被调用。

但是,诸如存储库、资源解析器工厂、查询生成器之类的隐式对象都通过我使用@Reference注释派生它们的方式获得空指针异常。

这是该类的代码。我已经尝试删除激活、停用方法、添加启动/停止方法等所有内容,但这仍然不起作用。

错误日志显示:

*01.07.2015 12:05:24.014 INFO [127.0.0.1 [1435732523998] GET /content/test/en/headerfooter/jcr:content/footerpar/testassetfinder..html HTTP/1.1] com.test.example.assetfinder.AssetFinderImpl查询生成器:空 01.07.2015 12:05:24.014 INFO [127.0.0.1 [1435732523998] GET /content/test/en/fordheaderfooter/jcr:content/footerpar/testassetfinder..html HTTP/1.1] com.test.example。 assetfinder.AssetFinderImpl JCR 存储库:null 原因:java.lang.NullPointerException:com.test.example.assetfinder.AssetFinderImpl.getSearchAssetNames 处为 null(AssetFinderImpl.java:61)*

谁能帮我解决这个问题?

            package com.test.example.assetfinder;

            import java.util.ArrayList;
            import java.util.HashMap;
            import java.util.List;
            import java.util.Map;

            import javax.jcr.RepositoryException;
            import javax.jcr.Session;

            import org.apache.felix.scr.annotations.Activate;
            import org.apache.felix.scr.annotations.Component;
            import org.apache.felix.scr.annotations.Deactivate;
            import org.apache.felix.scr.annotations.Reference;
            import org.apache.felix.scr.annotations.Service;
            import org.apache.sling.jcr.api.SlingRepository;
            import org.osgi.service.component.ComponentContext;
            import org.slf4j.Logger;
            import org.slf4j.LoggerFactory;

            import com.day.cq.search.PredicateGroup;
            import com.day.cq.search.Query;
            import com.day.cq.search.QueryBuilder;
            import com.day.cq.search.result.Hit;
            import com.day.cq.search.result.SearchResult;


            /**
             * Example Asset Finder in AEM DAM.
             */
            @Service(value=com.test.example.assetfinder.AssetFinderService.class)
            @Component
            public class AssetFinderImpl implements AssetFinderService {

                @Reference
                private QueryBuilder builder;

                @Reference
                private ResourceResolverFactory resolverFactory;

                @Reference
                private SlingRepository repository;

                private static final Logger LOGGER = LoggerFactory.getLogger(AssetFinderImpl.class);

                @Activate
                protected void activate(final ComponentContext pCtx) throws RepositoryException {
                }
                @Deactivate
                protected void deactivate(ComponentContext pCtx) throws RepositoryException {
                }

                public List<String> getSearchAssetNames() {
                    List<String> assetList = new ArrayList<String>();
                    Session session = null;
                    try {
                        LOGGER.info("Query Builder: "  +builder);
                        LOGGER.info("Resolver Factory: "  +resolverFactory);
                        LOGGER.info("JCR Repository: " +repository);

                        session = repository.loginAdministrative(null);           
                        Map<String, String> map = new HashMap<String, String>();
                        map.put("path",         "/content/dam");
                        map.put("type",         "dam:Asset");
                        map.put("nodename",     "*example*.*");
                        map.put("orderby.sort", "asc");           
                        Query query = builder.createQuery(PredicateGroup.create(map), session);
                        SearchResult result = query.getResult();

                        // Iterating over the results
                        for (Hit hit : result.getHits()) {
                            assetList.add(hit.getTitle());
                        }
                    } catch(RepositoryException re) {
                        re.printStackTrace();       
                    } finally {
                        if(null != session) {
                            session.logout();
                        }
                    }       
                    return assetList;
                }
            }
4

1 回答 1

2

这里的关键是,当您使用 时@Reference,它将服务引用注入到由服务组件运行时 (SCR) 管理的类的实例中,并且注入到该托管实例中。如果您创建类的新(即不同)实例,则不会注入该字段。这就是为什么您需要使用该sling.getService()方法来获取托管实例的原因。

最佳实践是避免将实现类放在导出的包中。这样,您就不能直接从 JSP 中引用实现类;您只能引用服务接口,因此您永远无法从 JSP 创建新实例,因此不会遇到使用类的非托管实例的问题。

关于@Activateand @Deactivate,只有当您的激活/停用方法做了任何事情时,您才需要这些。在这种情况下,它们不会(至少在您的代码示例中)。如果你命名你的方法activatedeactivate,你也可以避免使用它们,但我个人总是建议使用它们只是为了安全起见,例如,如果你错误地输入了名称activte或类似的东西。

于 2015-07-07T10:49:34.930 回答