简体   繁体   中英

Spring MVC & Freemarker session attribute not exposed

I've got a problem with Freemarker's viewResolver with Spring - session attributes are not exposed to view, as it is in Spring's InternalResourceViewResolver.

Now, important part is: when I change from Spring's resolver to Freemarker's one, session attribute is not passed, it's null. When Spring's resolver is working, session is passed.

My code:

dispatcher-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

    <bean id="userSession" class="com.revicostudio.web.session.UserSession" scope="session">
    </bean> 

   <context:component-scan base-package="com.revicostudio.web" />
    <mvc:annotation-driven />
     <!-- 
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
      <property name="templateLoaderPath" value="/WEB-INF/ftl/"/>
        <property name="freemarkerVariables">
          <map>
            <entry key="xml_escape" value-ref="fmXmlEscape"/>
          </map>
        </property>
    </bean>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="cache" value="true"/>
        <property name="prefix" value=""/>
        <property name="suffix" value=".jsp"/>

        <property name="exposeSpringMacroHelpers" value="true"/>
        <property name="exposeRequestAttributes" value="true"/>
        <property name="allowRequestOverride" value="false" />
        <property name="exposeSessionAttributes" value="true"/>
        <property name="allowSessionOverride" value="false" />
        <property name="exposePathVariables" value="true"/>
    </bean>

    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>-->

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/ftl/" />
        <property name="suffix" value=".jsp" />
        <property name="exposeContextBeansAsAttributes" value="true" />
    </bean>
</beans>

LoginController.java:

@Controller
@RequestMapping("/login")
@SessionAttributes("userSession")
public class LoginController {

    @Autowired
    private UsersDatabaseService usersDatabaseService;

    @RequestMapping(method = RequestMethod.POST)
    public String login(
            @ModelAttribute UserLoginCredentials userLoginCredentials,
            UserSession userSession,
            final RedirectAttributes redirectAttributes)
    {
        int failedLoginAttempts = userSession.getFailedLoginAttempts();

        if (failedLoginAttempts < LoginConfig.maxLoginTries ||
                System.currentTimeMillis()-userSession.getFailedLoginsWaitTimeStart() > LoginConfig.failedLoginsWaitMinutes*60*1000) {

            if (usersDatabaseService.isValidPassword(userLoginCredentials.getUsername(), userLoginCredentials.getPassword())) {
                userSession.setUser(usersDatabaseService.getUser(userLoginCredentials.getUsername()));    
                userSession.setFailedLoginsWaitTimeStart(System.currentTimeMillis());
            }
            else {
                failedLoginAttempts++;

                if (failedLoginAttempts == LoginConfig.maxLoginTries) {
                    redirectAttributes.addFlashAttribute("error", 
                            "You've entered invalid username or password more than "
                            + LoginConfig.maxLoginTries + " times. Try again in "
                            + LoginConfig.failedLoginsWaitMinutes +" minutes.");
                }
                else { 
                    redirectAttributes.addFlashAttribute("error", "Invalid username or password");
                    userSession.setFailedLoginAttempts(failedLoginAttempts);
                    System.out.println(failedLoginAttempts);
                }
            }
        }
        else {
            redirectAttributes.addFlashAttribute("error", 
                    "You've entered invalid username or password more than "
                    + LoginConfig.maxLoginTries + " times. Try again in "
                    + LoginConfig.failedLoginsWaitMinutes +" minutes."); 
        }

        return "redirect:/";
    }
}

IndexController:

@Controller
@RequestMapping("/index")
public class IndexController {
    @RequestMapping(method=RequestMethod.GET)
    public String getIndex(Model model) {
        return "index";
    }

    @ModelAttribute("userRegisterCredentials")
    public UserRegisterCredentials getUserRegisterCredentials() {
        return new UserRegisterCredentials();
    }

    @ModelAttribute("userLoginCredentials")
    public UserLoginCredentials getUserLoginCredentials() {
        return new UserLoginCredentials();
    }
}

index.jsp:

<body>
    <!-- Code for Freemarker -->
    <#if error??>
        ${error}
    </#if>

    <#if userSession??>
        ${userSession}
    </#if>

    <#if !(userSession??)>
        b
    </#if>

    <!-- Code for JSTL -->
    ${userSession}

You have a session problem because of that redirectAttributes.addFlashAttribute(). which means addFlashAttribute actually stores the attributes in a flashmap (which is internally maintained in the users session and removed once the next redirected request gets fulfilled),

Just try without redirectAttributes.addFlashAttribute() you will get session.

May be this will help you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM