Announcement Announcement Module
Collapse
No announcement yet.
using resourceBundle outside of WebFlow / FlowResourceELResolver Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • using resourceBundle outside of WebFlow / FlowResourceELResolver

    Another question regarding the message source (it's a never-ending story...). I'm using Spring 2.5.5 with Web Flow 2.0.2, MyFaces 1.2.3 and Facelets 1.1.14.

    I use Spring Security together with Web Flow. I had some difficulties initially and settled for a solution where the login page has no flow attached and is handled by its own controller (org.springframework.web.servlet.mvc.UrlFilenameVi ewController). A flow wouldn't do anything here anyway because it is only a single page and the processing is handled by Spring Security. It looks like this in the config file:

    Code:
      <!-- maps request URLs to the flow controller (URLs are relative to the servlet path) -->
      <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
          <value>
            login=loginController
            loginProcess=loginController
            logout=loginController
            logoutSuccess=loginController
            *=flowController
          </value>
        </property>
      </bean>
    
      <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
        <property name="flowExecutor" ref="flowExecutor"/>
        <property name="ajaxHandler">
          <bean class="org.springframework.faces.richfaces.RichFacesAjaxHandler"/>
        </property>
      </bean>
    
      <bean id="loginController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController">
        <property name="prefix" value="login/" />
      </bean>
    Unfortunately I discovered earlier today that the message source is causing trouble in the login page. Apparently, something under the hood is still using flow classes which try to get the message source via the current flow which leads to a NullPointerException (because there is no flow). To be more exact, the FlowResourceELResolver's getValue() method handles the expression and calls getMessageSource().

    I'm not sure what to do here. The message source is of course available, as Spring bean "messageSource". But EL doesn't really give me a way to access it. Can I configure the whole thing so that another ELResolver is used for this controller? Or if I write my own resolver, how would I insert it into the resolver chain?!? Why is this resolver used anyway on a page that doesn't use web flow? Or is there some EL magic that can help me retrieve the value from the message source bean? Any help is appreciated.

  • #2
    The ELResolvers are set up on an application-wide level.

    FlowResourceELResolver should just be passing through as the variable you're looking up is "messageSource", but the variable it expects is "resourceBundle".

    In order to resolve the bean "messageSource" from a root application context, you will need to have the SpringBeanELResolver registered manually in your faces-config.xml. This should work as the first pass through the resolver chain should resolve "messageSource" using the SpringBeanELResolver, and then the FlowResourceELResolver should kick in on the next pass to take care of the rest.

    Comment


    • #3
      I havbe a quite similar problem:

      I have configured an ELResolver in my faces-config:

      <application>
      <view-handler>com.sun.facelets.FaceletViewHandler</view-handler> <el-resolver>org.springframework.web.jsf.el.WebApplica tionContextFacesELResolver</el-resolver>
      </application>

      and a messageSource in my web-application-config:

      <bean id="messageSource"
      class="org.springframework.context.support.Reloada bleResourceBundleMessageSource">
      <property name="basenames">
      <list>
      <value>WEB-INF/i18n/messages</value>
      <value>WEB-INF/i18n/labels</value>
      <value>WEB-INF/i18n/text</value>
      </list>
      </property>
      </bean>

      When i try to access a message from outside of a flow via #{webApplicationContext.messageSource['labels.some.key']} (would this be the correct syntax by the way?), still the FlowResourceELResolver tries to pick up the message, resulting in a NPE when obtaining the locale from a null-requestContext.

      Why does the FlowResourceELResolver try to serve the message when i am not inside a flow and not using the implicit "resourceBundle" variable?

      Comment


      • #4
        Ahh, that is indeed a problem that I didn't notice at first. The issue is that "messageSource" resolves to the MessageSource instance from the application context and then gets passed through the resolver chain as the "base" parameter to get the "labels.some.key" value (staying with your example). What is needed is a separate resolver (similar to FlowResourceELResolver) that knows how to get the current locale without going through SWF.

        Comment


        • #5
          I have added a Jira for this:
          http://jira.springframework.org/browse/SWF-841

          Comment


          • #6
            Thanks for the response! I guess that's my problem, too. I played around a bit with writing my own resolver but gave it up in the end. Adding that directly in Spring would be great! :-)

            Comment


            • #7
              I think, I found simple workaround your problem.

              In faces-config.xml I have defined my el-resolver
              Code:
              <faces-config xmlns="http://java.sun.com/xml/ns/javaee"
              	    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               	    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
               	    http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
               	    version="1.2">
              	<application>
              	
              		<!-- Enables Facelets -->
              		<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
              	
              		<!-- message soruce in el expressions  -->
              		<el-resolver>test.TestResolver</el-resolver>
              	</application>
              </faces-config>
              The code for TestResolver look like this:
              Code:
              public class TestResolver extends SpringBeanFacesELResolver {
              
                  private final static Log log = LogFactory.getLog(TestResolver.class);
              
                  @Override
                  public Object getValue(ELContext elContext, Object base, Object property) throws ELException {
                      if (log.isDebugEnabled())
                          log.debug("getValue(" + elContext + ", " + base + ", " + property + ")");
              
                      if (base instanceof MessageSource && property instanceof String) {
                          if (log.isDebugEnabled()) {
                              log.debug("getting message from MessageSource with key: " + property + " for locale: " + getLocale());
                          }
              
                          String result = ((MessageSource) base).getMessage((String) property, null, getLocale());
              
                          if (log.isDebugEnabled()) {
                              log.debug("Result: " + result);
                          }
              
                          if (null != result) {
                              elContext.setPropertyResolved(true);
                          }
              
                          return result;
                      }
              
                      return super.getValue(elContext, base, property);
                  }
              
                  private Locale getLocale() {
                      FacesContext context = FacesContext.getCurrentInstance();
              
                      return context.getExternalContext().getRequestLocale();
              
                  }
              }
              I don't know if this is the best solution but it does for me. Hope it helps you too.

              Comment


              • #8
                @lukg: It's been some time, but I just wanted to say thank you for your reply! A colleague adapted your code for our system and it works! Thanks! :-)

                Comment

                Working...
                X