cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to get 'WebApplicationContext' in custom servlet

sam4alf
Champ in-the-making
Champ in-the-making
All Java JCR enthusiasts out there,

I have a custom servlet from where I'm trying to access repository and a node. I need to get this node's content and send it to an applet running in the same context. I have user login ticket and node reference. Using those, I'm trying to get the node and it's content.

Here is my code. Somehow, I always get NullPointerException while getting request. It won't move anywhere from that line. What am I missing? Any clues are really appreciated. Thanks.
       
  
 
             System.out.println("ticketFromApplet given to content handler is: " +    ticketFromApplet);
             System.out.println("NodeRef given to content handler is: " +  nodeRef);
             Ticket ticket = new Ticket("http://<host>:8080/alfresco",  ticketFromApplet);
             StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE,  "SpacesStore");
             HttpServletRequest request = (HttpServletRequest) MessageContext.getCurrentContext()                                                                                     .getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
            ServletContext sc = request.getSession().getServletContext();
            WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
            // get registry of services
            final ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
            SearchService searchService = serviceRegistry.getSearchService();
            ResultSet rs = searchService.query(storeRef,SerchService.LANGUAGE_LUCENE, "ID:\"" + nodeRef + "\"");
            ResultSetRow row = rs.getRow(0);
            NodeRef docRef = row.getNodeRef();
            ContentServiceImpl contentService = new ContentServiceImpl();
            contentService.readContentIntoStream(ticket, docRef, QName.createQName("cm:content"), outputStream);

-Sarma.
12 REPLIES 12

romschn
Star Collaborator
Star Collaborator
I couldn't understand why you are explicitly getting the request in your servlet.It should be available to you in service method.I might have misunderstood something.

Anyways In your custom servlet, You can access the serviceRegistry and all other alfresco repository services in following way.

You need to write below in service method of your servlet,
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
ServiceRegistry serviceRegistry = (ServiceRegistry) wc.getBean(ServiceRegistry.SERVICE_REGISTRY);

Similar way you can get access to all the alfresco services.

Hope this helps.

Thanks,

sam4alf
Champ in-the-making
Champ in-the-making
Hi Romschn,

Thanks for your reply. I tried your suggestion but got NPE at getting webapplicationcontext. See trace below:

13:09:54,348 INFO  [STDOUT] ticketFromApplet given to content handler is: TICKET_30df483da72e1e75cc77015a5cd816aff1c397b4

13:09:54,348 INFO  [STDOUT] NodeRef given to content handler is: workspace://SpacesStore/1558798a-941a-4c9f-a2ba-93fa445c44c6

13:09:54,348 INFO  [STDOUT] Creating ticket…

13:09:54,348 INFO  [STDOUT] Done.. Getting storeRef

13:09:54,348 INFO  [STDOUT] getting request…

13:09:54,348 INFO  [STDOUT] getting ApplicationContext…

13:09:54,348 ERROR [STDERR] java.lang.NullPointerException

13:09:54,348 ERROR [STDERR]     at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:160)

Am I missing something? Some configurations etc?

Thanks,
Sarma.

romschn
Star Collaborator
Star Collaborator
Did you override the init method in your custom servlet without making a call to super.init(ServletConfig)?

Could you please post your entire servlet code so as I can take a look and could help you solve this.

Thanks,

sam4alf
Champ in-the-making
Champ in-the-making
Hi,

I added the following to init method and tried again. This time, it failed at a different line:

 public ServletContext servContext = null;
  public void init(javax.servlet.ServletConfig servletConfig) {
       this.servContext = servletConfig.getServletContext();
    }

Method code (this is just testing code, so please bear with me on quality part of it):

public ContentHandlerResult getDocumentContent(
        ContentHandlerInput contentHandlerInput) throws FlexSnapSIAPIException {
        ContentHandlerResult result = new ContentHandlerResult();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        try {
            // now get the content and pass it on to Applet
            String ticketFromApplet = contentHandlerInput.getDocumentId();
            String nodeRef = contentHandlerInput.getClientInstanceId();

            System.out.println("ticketFromApplet given to content handler is: " +
                ticketFromApplet);
            System.out.println("NodeRef given to content handler is: " +
                nodeRef);
            System.out.println("Creating ticket…");

            Ticket ticket = new Ticket("http://ohqvuda15:8080/alfresco",
                    ticketFromApplet);
            System.out.println("Done.. Getting storeRef");

            StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE,
                    "SpacesStore");
            System.out.println("getting request…");

       
            System.out.println("getting ApplicationContext…");

            WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(servContext);

            // get registry of services
            System.out.println("Getting service registry…");

            ServiceRegistry serviceRegistry = (ServiceRegistry) wc.getBean(ServiceRegistry.SERVICE_REGISTRY);

            System.out.println("creating search service");

            SearchService searchService = serviceRegistry.getSearchService();
            System.out.println("Getting results..");

            ResultSet rs = searchService.query(storeRef,
                    SearchService.LANGUAGE_LUCENE, "ID:\"" + nodeRef + "\"");
            System.out.println("getting row 0 from resutl set");

            ResultSetRow row = rs.getRow(0);
            System.out.println("getting noderef from this row");

            NodeRef docRef = row.getNodeRef();
            System.out.println("Creating contentserviceImpl");

            ContentServiceImpl contentService = new ContentServiceImpl();
            System.out.println("Reading content into stream…");
            contentService.readContentIntoStream(ticket, docRef,
                QName.createQName("cm:content"), outputStream);
            System.out.println("Getting bytes out of this stream…");

            byte[] binaryData = outputStream.toByteArray();
            System.out.println(
                "Putting these bytes in ContentHandlerResult …");

            try {
                result.put("KEY_DOCUMENT_CONTENT", binaryData);
            } catch (Exception e) {
                e.printStackTrace();
                throw new FlexSnapSIAPIException(e.getMessage());
            }

            System.out.println("Done.");
        } catch (FlexSnapSIAPIException flexsnapSIAPIException) {
            //throw flexsnapSIAPIException;
            flexsnapSIAPIException.printStackTrace();
        } catch (Exception ex) {
            //throw new FlexSnapSIAPIException(ex.getMessage());
            ex.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

Error log:

13:22:38,294 INFO  [STDOUT] ticketFromApplet given to content handler is: TICKET_f623018e59c29d54d9a377b6da4fae513057e2c4
13:22:38,294 INFO  [STDOUT] NodeRef given to content handler is: workspace://SpacesStore/1558798a-941a-4c9f-a2ba-93fa445c44c6
13:22:38,294 INFO  [STDOUT] Creating ticket…
13:22:38,296 INFO  [STDOUT] Done.. Getting storeRef
13:22:38,297 INFO  [STDOUT] getting request…
13:22:38,297 INFO  [STDOUT] getting ApplicationContext…
13:22:38,297 INFO  [STDOUT] Getting service registry…
13:22:38,297 INFO  [STDOUT] creating search service
13:22:38,297 INFO  [STDOUT] Getting results..
13:22:38,315 ERROR [STDERR] net.sf.acegisecurity.AuthenticationCredentialsNotFoundException: A valid SecureContext was not provided in the RequestContext
13:22:38,316 ERROR [STDERR]     at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:477)
13:22:38,316 ERROR [STDERR]     at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:355)
13:22:38,316 ERROR [STDERR]     at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:77)
13:22:38,316 ERROR [STDERR]     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
13:22:38,316 ERROR [STDERR]     at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:44)
13:22:38,316 ERROR [STDERR]     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
13:22:38,316 ERROR [STDERR]     at org.alfresco.repo.audit.AuditMethodInterceptor.proceedWithAudit(AuditMethodInterceptor.java:217)
13:22:38,316 ERROR [STDERR]     at org.alfresco.repo.audit.AuditMethodInterceptor.proceed(AuditMethodInterceptor.java:184)
13:22:38,316 ERROR [STDERR]     at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:137)
13:22:38,317 ERROR [STDERR]     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
13:22:38,317 ERROR [STDERR]     at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
13:22:38,317 ERROR [STDERR]     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
13:22:38,317 ERROR [STDERR]     at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
13:22:38,317 ERROR [STDERR]     at $Proxy440.query(Unknown Source)
13:22:38,317 ERROR [STDERR]     at com.matson.idm.viewstar.alfresco.IDMViewStarContentHandlerForAlfresco.getDocumentContent(Unknown Source)
13:22:38,317 ERROR [STDERR]     at com.snowbound.snapserv.servlet.VirtualViewerRetrievalProcessor.getDocumentBytes(VirtualViewerRetrievalProcessor.java:1512)
13:22:38,317 ERROR [STDERR]     at com.snowbound.snapserv.servlet.VirtualViewerRetrievalProcessor.getImageData(VirtualViewerRetrievalProcessor.java:279)
13:22:38,317 ERROR [STDERR]     at com.snowbound.snapserv.servlet.FlexSnapSIRetrievalServlet.getImageData(FlexSnapSIRetrievalServlet.java:1008)
13:22:38,317 ERROR [STDERR]     at com.snowbound.snapserv.servlet.FlexSnapSIRetrievalServlet.getImage(FlexSnapSIRetrievalServlet.java:880)
13:22:38,317 ERROR [STDERR]     at com.snowbound.snapserv.servlet.FlexSnapSIRetrievalServlet.service(FlexSnapSIRetrievalServlet.java:182)
13:22:38,317 ERROR [STDERR]     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
13:22:38,317 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
13:22:38,317 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
13:22:38,317 ERROR [STDERR]     at org.alfresco.web.app.servlet.GlobalLocalizationFilter.doFilter(GlobalLocalizationFilter.java:58)
13:22:38,317 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
13:22:38,317 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
13:22:38,317 ERROR [STDERR]     at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
13:22:38,317 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
13:22:38,317 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
13:22:38,317 ERROR [STDERR]     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
13:22:38,317 ERROR [STDERR]     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
13:22:38,317 ERROR [STDERR]     at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
13:22:38,318 ERROR [STDERR]     at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
13:22:38,318 ERROR [STDERR]     at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
13:22:38,318 ERROR [STDERR]     at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
13:22:38,318 ERROR [STDERR]     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
13:22:38,318 ERROR [STDERR]     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
13:22:38,318 ERROR [STDERR]     at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
13:22:38,318 ERROR [STDERR]     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
13:22:38,318 ERROR [STDERR]     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
13:22:38,318 ERROR [STDERR]     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
13:22:38,318 ERROR [STDERR]     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
13:22:38,318 ERROR [STDERR]     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
13:22:38,318 ERROR [STDERR]     at java.lang.Thread.run(Thread.java:662)

romschn
Star Collaborator
Star Collaborator
Hi,

Instead of posting the code in parts, it would be great if you could post the entire servlet code so as I can take a look and would be easier to solve your problem. Because looking at the partial code it is difficult to identify why it is not working.

Thanks,

romschn
Star Collaborator
Star Collaborator
Hi,

I missed looking at the method code previously. However, it will still be helpful if you could share the entire servlet code.

It seems that getting application context error has now been resolved and now you are facing a completely different error for authentication.

Could you please try with below :
1. Firstly, Try putting super.init(ServletConfig) in your init method and re-run with your existing code.

If above does not work - try puttin super.init(ServletConfig) in init method and do below.
2. I couldn't understand which Ticket API you are using. Instead do the below.
    As you already have the ticket available from applet, just get the authentication status from alfresco using below method in your service method.
    AuthenticationHelper.authenticate(getServletContext(), req, res, ticket).
   if authentication status returned by above method is success then only proceed further.

Hope this helps.

Thanks,

sam4alf
Champ in-the-making
Champ in-the-making
Hi,

Thanks for your time again.

I tried both your suggestions. First one (simply adding super.init()) didn't work.

2nd one gave the following error. Looks like it didn't get the user details in session.

11:41:59,868 INFO  [STDOUT] ticketFromApplet given to content handler is: TICKET_a7df7515359d591682144901de6b8ada15c3c369
11:41:59,868 INFO  [STDOUT] NodeRef given to content handler is: workspace://SpacesStore/119c7a97-ddc7-468a-8473-dca379f4c447
11:41:59,868 INFO  [STDOUT] Creating ticket…
11:41:59,870 INFO  [STDOUT] Authenticating …
11:41:59,872 ERROR [STDERR] java.lang.NullPointerException
11:41:59,872 ERROR [STDERR]     at org.alfresco.web.app.servlet.AuthenticationHelper.getUser(AuthenticationHelper.java:463)
11:41:59,872 ERROR [STDERR]     at org.alfresco.web.app.servlet.AuthenticationHelper.authenticate(AuthenticationHelper.java:170)
11:41:59,872 ERROR [STDERR]     at org.alfresco.web.app.servlet.AuthenticationHelper.authenticate(AuthenticationHelper.java:151)
11:41:59,872 ERROR [STDERR]     at com.matson.idm.viewstar.alfresco.IDMViewStarContentHandlerForAlfresco.getDocumentContent(Unknown Source)
11:41:59,873 ERROR [STDERR]     at com.snowbound.snapserv.servlet.VirtualViewerRetrievalProcessor.getDocumentBytes(VirtualViewerRetrievalProcessor.java:1512)

romschn
Star Collaborator
Star Collaborator
Hi,

I found the root cause why you are getting the - a valid SecureContext was not provided in the RequestContext error.

It was failing because the ticket was not being validated and the valid user was not found. Hence, it was not allowing to perform operation on node to read the content.

I have written a sample servlet code for your reference which basically reads the content from a text file.

You may not need to override the init method in your custom servlet. However , if you do so just call the super method in it.

package com.test.servlet;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class CustomServlet extends HttpServlet {

   private static final long serialVersionUID = 1L;

   @Override
   public void init(ServletConfig config) throws ServletException {
      super.init(config);
   }
   
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException, IOException {
      
         super.doGet(req, resp);
      
         // Get servlet context
         ServletContext objContext = getServletConfig().getServletContext();
         
         // NodeRef of the document 1.txt
         NodeRef objRef = new NodeRef("workspace://SpacesStore/3bf87bea-41cb-4a93-a98b-38ab3805085c");
         
         // Get webapplication context
         WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(objContext);
         
         ServiceRegistry serviceRegistry = (ServiceRegistry) wc.getBean(ServiceRegistry.SERVICE_REGISTRY);

         // Get authentication service
         AuthenticationService objService = serviceRegistry.getAuthenticationService();
         
         // MUST TO AVOID THE ERROR - a valid SecureContext was not provided in the RequestContext
         // example : req.getParameter("alf_ticket") = TICKET_2fa55c64371087b642fdf8107083456f81fd1e1f
         objService.validate(req.getParameter("alf_ticket"));
         
         ContentService contentService = serviceRegistry.getContentService();

         // Get the content reader
         ContentReader contentReader = contentService.getReader(objRef, ContentModel.PROP_CONTENT);
         
         // Read the data as string
         System.out.println("Content Data is :: " + contentReader.getContentString());
      }
}

For my sample test, I used to retrieve the ticket hitting the out-of-the-box webscript : http://localhost:8080/alfresco/service/api/login?u=admin&pw=admin

and then passing the ticket to my servlet code : http://localhost:8080/alfresco/testservlet?alf_ticket=TICKET_2fa55c64371087b642fdf8107083456f81fd1e1...

Please try implement it this way…I think your problem is resolved now.

Hope this helps.

Thanks,

sam4alf
Champ in-the-making
Champ in-the-making
Hi Romschn,

Thanks allot for all your time and effort. Your suggestion worked like a charm in my custom code. I used the ticket and noderef received from FTL template and able to display content inside a 3rd party applet. Your code helped me in crossing a big hurdle in a critical POC.

Thanks again.

-Sarma.