1 Reply Latest reply on Aug 8, 2013 10:29 AM by wangliyu

    Performance Optimization in WELD2

    wangliyu

      In WELD 2, it move the conversation scope to Servlet (default init in the Servlet Listener).

      For typical JSF2 web app, it translate some static resource with extends of .jsf, for example "jsf.js.jsf", "jquery.js.jsf", also there are some other static resources (css, png, jpg, gif, css, js), when the request for  the static resources is received, the initial context will be triggered.

      Right now I have to extended the default org.jboss.weld.environment.servlet.Listener & org.jboss.weld.servlet.ConversationFilter to filter the request url, only activate context on the real request and skip the static resources request.

       

      here is what I did:

       

      public class MyContextListener extends Listener {
          private static final Logger logger = LoggerFactory.getLogger(HorizonContextListener.class);
          private String pattern;
          @Override
          public void contextInitialized(ServletContextEvent sce) {
              this.pattern = sce.getServletContext().getInitParameter("horizon.context.activation.url");
              logger.info("Initialize context activation url pattern: {}", this.pattern);
              super.contextInitialized(sce);
          }
          @Override
          public void requestDestroyed(ServletRequestEvent sre) {
              if (sre.getServletRequest().getAttribute(MyConversationFilter.CONTEXT_ACTIVATION_FLAG) != null) {
                  super.requestDestroyed(sre);
              }
          }
          @Override
          public void requestInitialized(ServletRequestEvent sre) {
              if (sre.getServletRequest() instanceof HttpServletRequest) {
                  HttpServletRequest req = (HttpServletRequest) sre.getServletRequest();
                  String path = req.getServletPath();
                  if (path != null && path.matches(this.pattern)) {
                      logger.debug("activate context on request {}", path);
                      req.setAttribute(MyConversationFilter.CONTEXT_ACTIVATION_FLAG, "Y");
                      super.requestInitialized(sre);
                  }
              } else {
                  logger.error("Invalid Servlet Environment.");
              }
          }
      }
      public class MyConversationFilter extends ConversationFilter { // has to extends from the filter, the COnversationFilter has @Inject in it.
          public static final String CONTEXT_ACTIVATION_FLAG= "com.cgi.horizon.common.context.activation";
          private static final Logger logger = LoggerFactory.getLogger(HorizonConversationFilter.class);
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              if (request.getAttributeCONTEXT_ACTIVATION_FLAG) != null) {
                  try {
                      super.doFilter(request, response, chain);
                  } catch (Exception e) { // this part is try to deligate the exception handling to JSF exception handling.
                      logger.warn("**** Caught exception before JSF lifecycle.", e);
                      if (!response.isCommitted()) {
                          request.setAttribute(ServletException.class.getCanonicalName(), e);
                          String path = ((HttpServletRequest) request).getServletPath();
                          logger.info("**** Dispatch to {} with exception.", path);
                          request.getRequestDispatcher(path).forward(request, response);
                      }
                  }
              } else {
                  chain.doFilter(request, response);
              }
          }
      }

       

      Can we do something in the WELD listenr and filter to test if request has attribute, if they have then active the context, otherwise just defer to the normal process?

       

      Thanks,

      Liyu