BLOG
Obtaining JCR Session in a Sling based application
By shankha - JCRDev | Posted on 2009-09-04 00:14
Sling is based upon JCR, the java content repository. So, whenever we are storing some data in a Sling based application, ideally we are storing the data in the underlying JCR.
Now, to store any data in the repository we need a JCR Session Object. The root cause of writing this post is to show you the way to get the JCR Session in the Sling based application.
Sling itself overrides the HttpServletRequest object what we widely use in all J2EE application. Sling provides us with the HttpSlingHttpServletRequest instead. With all the properties of the HttpServletRequest, it adds, the Resource object to the request. In the JSPs in a Sling based application we use the Sling tag to get the Sling defined objects in the following manner.
<%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0" %>
<%-- Ensure the presence of the Sling objects --%>
Here, with other objects, a currentNode object is defined by Sling from where we can esily get the JCR session by writing code as follows.
javax.jcr.Session jcrSession = currentNode.getSession();
Now, say, from the same JSP we send the request to a servlet. As in the servlet the doGet or doPost method, by default works on HttpServletRequest and HttpServletResponse objects, we have to do the following to get
the JCR session.
public class MyDemoServlet extends javax.servlet.http.HttpServlet implements
javax.servlet.Servlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
log.info("Bypassing doGet ... sending to process");
process(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
log.info("Bypassing doPost ... sending to process");
process(request, response);
}
private void process(HttpServletRequest request,
HttpServletResponse response) throws IOException{
SlingHttpServletRequest req = (SlingHttpServletRequest) request;
/*Here we are typecasting the HttpServletRequest to
SlingHttpServletRequest object*/
javax.jcr.Session jcrsession = null;
org.apache.sling.api.resource.Resource resource = null;
javax.jcr.Node currNode = null;
try{
resource = req.getResource();
// getting the Resource object from SlingHttpServletRequest
currNode = resource.adaptTo(Node.class);
// adapting the Resource Object to Node
jcrsession = currNode.getSession();
//getting the JCR Session from the Node
.... rest of the code
}
}
Alternatively we can get the JCR session by using the ResourceResolver object from the SlingHttpServletRequest. In that case the process method may look like the following.
private void process(HttpServletRequest request,
HttpServletResponse response) throws IOException{
SlingHttpServletRequest req = (SlingHttpServletRequest) request;
/*Here we are typecasting the HttpServletRequest to
SlingHttpServletRequest object*/
javax.jcr.Session jcrsession = null;
try{
jcrsession = req.getResourceResolver().adaptTo(Session.class);
... rest of the code
}
Hope this helps.
Previous comments on this post
By bhatasuj - JCRDev | Posted on 2009-09-04 03:42
This is really helpful, but this is always advisable to use
jcrsession = req.getResourceResolver().adaptTo(Session.class) when you want to have the jcrsession inside sling.
sujoy
By thaneshk - JCRLead | Posted on 2009-09-04 06:29
Shankha,
Very nice post. I have one quick question - the session that is created - is this with a particular instance of a repository or a particular workspace in a repository. Therefore if the answer is the latter, can this session be shared across multiple workspaces. If the answer is a particular instance of a repository -can the session be used to talk to more repositories?
Cheers,
-Thanesh
By shankha - JCRDev | Posted on 2009-09-08 05:51
Thanesh,
Thanks for the comment. A javax.jcr.Session object can return you the instance of the Repository you are currently working with. The workspace is also prefixed. In case of Sling, it will be the "default" workspace.
The session cannot be shared withing different workspaces, but we can get another session from the current session in the following manner,
public static void testRepo(HttpServletRequest request){
/* Idea is to login to a new workspace from the present one */
Session jcrsession = null;
Session newSession = null;
Resource resource = null;
SlingHttpServletRequest req = (SlingHttpServletRequest)request;
Repository repo = null;
Credentials cred = null;
try{
jcrsession = req.getResourceResolver().adaptTo(Session.class);
repo = jcrsession.getRepository();
log.info("Session has following workspaces:"+jcrsession.getWorkspace().getName());
//*** try to get another session
char[] pass = "admin".toCharArray();
cred = new SimpleCredentials("admin",pass);
newSession = repo.login(cred,"security");
log.info("newSession has following workspaces:"+newSession.getWorkspace().getName());
}catch (Exception e) {
// TODO: handle exception
log.info("Some Exception in getMetatags:"+e.getMessage());
e.printStackTrace();
}
}
Obviously we can get the new "security" workspace, traverse in it. As we are getting the repository from the session itself, we cannot login to a new repository from here.
Please comment on this.
Thanks, Shankha
BLOG STATS
5625 visitors have read this BlogPopular Posts
The Apache Sling FrameworkTemplate Creation in Day Communique 4.x
JCR and ECM Vendors
Writing Filters in Apache Sling Web Application
Sling based JCR Explorer
JCR DEVELOPERS (level, posts)

