我们正在尝试为外部端点提供一个干净的URI结构,以便从CQ5中提取json信息。
例如,如果您想获取有关特定用户历史记录的信息(假设您拥有权限等),理想情况下我们希望端点能够执行以下操作:
/bin/api/user/abc123/phone/555-klondike-5/history.json
在URI中,我们将指定/bin/api/user/{username}/phone/{phoneNumber}/history.json,这样可以非常轻松地利用调度程序使缓存更改无效等,而不会使广泛的区域无效缓存信息。
我们想使用sling servlet来处理请求,但是,我不知道如何将变量放入路径中。
如果有来自JaxRS的@PathParam之类的内容添加到sling路径变量会很棒,但我怀疑它不可用。
我们想到的另一种方法是使用选择器来识别我们何时访问api,从而可以从路径返回我们想要的任何内容,但是需要一个单一的sling servlet来处理所有请求,所以我对这种方法并不满意,因为它将很多不相关的代码粘合在一起。
对此有任何帮助将不胜感激。
更新:
如果我们要使用OptingServlet,然后在接受函数中放入一些逻辑,我们可以堆叠一系列sling servlet并使用正则表达式从路径做出接受决定。
然后在执行期间,可以为变量解析路径本身。
答案 0 :(得分:5)
如果您提供的数据来自JCR存储库,那么最好是按照您希望的URL来完全构建它,这是使用Sling执行操作的推荐方法。
如果数据是外部的,您可以创建一个自定义Sling ResourceProvider,它安装在/ bin / api / user路径上,并根据路径的其余部分获取或生成相应的数据。
Sling测试套件的PlanetsResourceProvider就是一个简单的例子,请参阅http://svn.apache.org/repos/asf/sling/trunk/launchpad/test-services/src/main/java/org/apache/sling/launchpad/testservices/resourceprovider/
https://sling.apache.org/documentation/the-sling-engine/resources.html处的Sling资源文档记录了一般资源解析机制。
答案 1 :(得分:2)
现在可以将jersy(JAX-RS)与CQ集成。我们可以创建原始原型来向世界说“你好”。
https://github.com/hstaudacher/osgi-jax-rs-connector
有了这个,我们可以使用@PathParam来映射请求
谢谢和问候, 圣
答案 2 :(得分:1)
没有直接的方法来创建这样的动态路径。您可以在/bin/api/user.json
下注册servlet,并将其余路径作为suffix提供:
/bin/api/user.json/abc123/phone/555-klondike-5/history
^ ^
| |
servlet path suffix starts here
然后你可以手动解析后缀:
@SlingServlet(paths = "/bin/api/user", extensions = "json")
public class UserServlet extends SlingSafeMethodsServlet {
public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
String suffix = request.getRequestPathInfo().getSuffix();
String[] split = StringUtils.split(suffix, '/');
// parse split path and check if the path is valid
// if path is not valid, send 404:
// response.sendError(HttpURLConnection.HTTP_NOT_FOUND);
}
}
答案 3 :(得分:0)
解决此问题的RESTful方法是将信息存储在您要使用的结构中。即/ content / user / abc123 / phone / 555-klondike-5 / history /将包含该路径的所有历史节点。
在那种用法中。只需调用
即可获得开箱即用的json响应/content/user/abc123/phone/555-klondike-5/history.json
或者,如果您需要特定json格式的内容,则可以使用sling资源解析来使用自定义json响应。
答案 4 :(得分:0)
很高兴分享这个!我已经工作了一个星期来解决这个问题,最后得到了最好的答案。
首先:尝试使用Jersey
kallada提出的osgi-jax-rs-connector是最好的,但我无法让它在Sling 8上工作。我失去了整整一天的尝试,所有我必须展示它是怪异的类未找到错误和依赖性问题。
解决方案:ResourceProvider
Bertrand的链接仅适用于Sling 9,但未发布。所以这就是你在Sling 8及更早版本中的表现!
两个文件:
ResourceProvider
这样做的目的只是在/ service处侦听所有请求,然后在该虚拟路径上生成“资源”,这在JCR中实际上不存在。
@Component
@Service(value=ResourceProvider.class)
@Properties({
@Property(name = ResourceProvider.ROOTS, value = "service/image"),
@Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
})
public class ImageResourceProvider implements ResourceProvider {
@Override
public Resource getResource(ResourceResolver resourceResolver, String path) {
AbstractResource abstractResource;
abstractResource = new AbstractResource() {
@Override
public String getResourceType() {
return TypeServlet.RESOURCE_TYPE;
}
@Override
public String getResourceSuperType() {
return null;
}
@Override
public String getPath() {
return path;
}
@Override
public ResourceResolver getResourceResolver() {
return resourceResolver;
}
@Override
public ResourceMetadata getResourceMetadata() {
return new ResourceMetadata();
}
};
return abstractResource;
}
@Override
public Resource getResource(ResourceResolver resourceResolver, HttpServletRequest httpServletRequest, String path) {
return getResource(resourceResolver , path);
}
@Override
public Iterator<Resource> listChildren(Resource resource) {
return null;
}
}
Servlet
现在您只需编写一个servlet来处理来自该路径的任何资源 - 但这是通过处理资源类型来完成的,该资源类型由在该路径上侦听的ResourceProvider生成。
@SlingServlet(
resourceTypes = TypeServlet.RESOURCE_TYPE,
methods = {"GET" , "POST"})
public class TypeServlet extends SlingAllMethodsServlet {
static final String RESOURCE_TYPE = "mycompany/components/service/myservice";
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
final String [] pathParts = request.getResource().getPath().split("/");
final String id = pathParts[pathParts.length-1];
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try {
out.print("<html><body>Hello, received this id: " + id + "</body></html>");
} finally {
out.close();
}
}
}
显然你的servlet会做一些更聪明的事情,例如更智能地处理“path”字符串并且可能产生JSON。