Spring mvc 在freemarker中实现分页并获取错误

Spring mvc 在freemarker中实现分页并获取错误,spring-mvc,freemarker,Spring Mvc,Freemarker,创建寻呼时获取freemarker错误: 堆栈跟踪是: freemarker.template.TemplateException: Expected hash. data evaluated instead to freemarker.template.SimpleSequence on line 68, column 15 in include/pagination.ftl. at freemarker.core.TemplateObject.invalidTypeException

创建寻呼时获取freemarker错误:

堆栈跟踪是:

freemarker.template.TemplateException: Expected hash. data evaluated instead to freemarker.template.SimpleSequence on line 68, column 15 in include/pagination.ftl.
    at freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:135)
    at freemarker.core.Dot._getAsTemplateModel(Dot.java:78)
    at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
    at freemarker.core.ComparisonExpression.isTrue(ComparisonExpression.java:111)
    at freemarker.core.ParentheticalExpression.isTrue(ParentheticalExpression.java:66)
    at freemarker.core.IfBlock.accept(IfBlock.java:80)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.MixedContent.accept(MixedContent.java:92)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.Macro$Context.runMacro(Macro.java:172)
    at freemarker.core.Environment.visit(Environment.java:603)
    at freemarker.core.UnifiedCall.accept(UnifiedCall.java:106)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.MixedContent.accept(MixedContent.java:92)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.Environment.process(Environment.java:190)
    at freemarker.template.Template.process(Template.java:237)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:366)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:283)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:233)
    at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1180)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:950)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
spring mvc代码:

@RequestMapping(method=RequestMethod.GET)
    public String index(Model model)
    {
        System.out.println("#############************%%%%%%%%%%%%%%%%%%%");

        List<RouteAddress> routeAddressList = new ArrayList<RouteAddress>();

        for(int i = 0;i<=100;i++){

            RouteAddress routeAddress = new RouteAddress();
            routeAddress.setAm_pm("am");
            routeAddress.setCity1("city1");
            routeAddress.setCity2("city2");
//          routeAddress.setDaysOfWeek("daysOfWeek");
            routeAddress.setEmail("email");
            routeAddress.setMobile(00000123);
            routeAddress.setName("name");
            routeAddress.setState1("state1");
            routeAddress.setState2("state2");
            routeAddress.setStreet11("street11");
            routeAddress.setStreet12("street12");
            routeAddress.setStreet21("street21");
            routeAddress.setStreet22("street22");
            routeAddress.setZip1("zip1");
            routeAddress.setZip2("zip2");
            routeAddress.setPageNumber(20);
            routeAddress.setPagesAvailable(true);
            routeAddress.setPageSize(10);
            routeAddress.setSortDirection("ascending");
            routeAddress.setSortField("city1");
            routeAddressList.add(routeAddress);

        }




        model.addAttribute(routeAddressList);
        return "address/searchroute";

    }
这是pagenation.ftl:

#if routeAddressList??>
    <#assign data = routeAddressList />
</#if>

<#--
 * Bind pagination data to the current data set these macros are using.
-->
<#macro bind routeAddressList>
    <#assign data = routeAddressList /> 
</#macro>

<#--
 * Outputs the first page link
-->
<#macro first>
    <#if (data.pageNumber < 1)>   <#-- I am getting the error at this line -->
        <#local classAttr = "class=\"disabled\"" />
    <#else>
        <#local classAttr = "" />
    </#if>
    <#local text>
        <@spring.messageText "pagination.first", "« First" />
    </#local>
    <@page 0, text, classAttr/>
</#macro>

<#--
 * Outputs the last page link
-->
<#macro last>
    <#if (data.pageNumber >= data.pagesAvailable - 1)>
        <#local classAttr = "class=\"disabled\"" />
    <#else>
        <#local classAttr = "" />
    </#if>
    <#local text>
        <@spring.messageText "pagination.last", "Last »" />
    </#local>
    <@page data.pagesAvailable - 1, text, classAttr/>
</#macro>

<#--
 * Outputs the next page link
-->
<#macro next>
    <#if (data.pageNumber >= data.pagesAvailable - 1)>
        <#local pageNumber = data.pageNumber />
        <#local classAttr = "class=\"disabled\"" />
    <#else>
        <#local pageNumber = data.pageNumber + 1 />
        <#local classAttr = "" />
    </#if>
    <#local text>
        <@spring.messageText "pagination.next", "Next »" />
    </#local>
    <@page pageNumber, text, classAttr/>
</#macro>

<#--
 * Outputs the previous page link
-->
<#macro previous>
    <#if (data.pageNumber < 1)>
        <#local pageNumber = data.pageNumber />
        <#local classAttr = "class=\"disabled\"" />
    <#else>
        <#local pageNumber = data.pageNumber - 1 />
        <#local classAttr = "" />
    </#if>
    <#local text>
        <@spring.messageText "pagination.previous", "« Previous" />
    </#local>
    <@page pageNumber, text, classAttr/>
</#macro>
我已将控制器更换为:

@Controller
@RequestMapping("/search")
public class SearchController extends AbstractController {

    @RequestMapping(method=RequestMethod.GET)
    public String index(Model model)
    {
        System.out.println("#############************%%%%%%%%%%%%%%%%%%%");

        List<RouteAddress> routeAddressList = new ArrayList<RouteAddress>();
        PaginationData pagenationData = new PaginationData();

        for(int i = 0;i<=100;i++){

            RouteAddress routeAddress = new RouteAddress();
            routeAddress.setAm_pm("am");
            routeAddress.setCity1("city1");
            routeAddress.setCity2("city2");
//          routeAddress.setDaysOfWeek("daysOfWeek");
            routeAddress.setEmail("email");
            routeAddress.setMobile(00000123);
            routeAddress.setName("name");
            routeAddress.setState1("state1");
            routeAddress.setState2("state2");
            routeAddress.setStreet11("street11");
            routeAddress.setStreet12("street12");
            routeAddress.setStreet21("street21");
            routeAddress.setStreet22("street22");
            routeAddress.setZip1("zip1");
            routeAddress.setZip2("zip2");

            routeAddressList.add(routeAddress);


        }

        pagenationData.setRouteAddress(routeAddressList);
        pagenationData.setPageNumber(10);
        pagenationData.setPagesAvailable(true);
        pagenationData.setPageSize(3);
        pagenationData.setSortDirection("ascending");
        pagenationData.setSortField("city1");




        model.addAttribute(pagenationData);
        return "address/searchroute";

    }
和pagenation.ftl至:

<#import "spring.ftl" as spring/>

<#if paginationData??>
    <#assign data = paginationData />
</#if>

<#--
 * Bind pagination data to the current data set these macros are using.
-->
<#macro bind paginationData>
    <#assign data = paginationData />
</#macro>

<#--
 * Outputs the first page link
-->
<#macro first>
    <#if (data.pageNumber < 1)>
        <#local classAttr = "class=\"disabled\"" />
    <#else>
        <#local classAttr = "" />
    </#if>
    <#local text>
        <@spring.messageText "pagination.first", "« First" />
    </#local>
    <@page 0, text, classAttr/>
</#macro>

<#--
 * Outputs the last page link
-->
<#macro last>
    <#if (data.pageNumber >= data.pagesAvailable - 1)>
        <#local classAttr = "class=\"disabled\"" />
    <#else>
        <#local classAttr = "" />
    </#if>
    <#local text>
        <@spring.messageText "pagination.last", "Last »" />
    </#local>
    <@page data.pagesAvailable - 1, text, classAttr/>
</#macro>

<#--
 * Outputs the next page link
-->
<#macro next>
    <#if (data.pageNumber >= data.pagesAvailable - 1)>
        <#local pageNumber = data.pageNumber />
        <#local classAttr = "class=\"disabled\"" />
    <#else>
        <#local pageNumber = data.pageNumber + 1 />
        <#local classAttr = "" />
    </#if>
    <#local text>
        <@spring.messageText "pagination.next", "Next »" />
    </#local>
    <@page pageNumber, text, classAttr/>
</#macro>

<#--
 * Outputs the previous page link
-->
<#macro previous>
    <#if (data.pageNumber < 1)>
        <#local pageNumber = data.pageNumber />
        <#local classAttr = "class=\"disabled\"" />
    <#else>
        <#local pageNumber = data.pageNumber - 1 />
        <#local classAttr = "" />
    </#if>
    <#local text>
        <@spring.messageText "pagination.previous", "« Previous" />
    </#local>
    <@page pageNumber, text, classAttr/>
</#macro>

<#--
 * Outputs the page numbers and links
 *
 * @param maxPages (Optional) The maximum number of page links to show
 * @param separator (Optional) The seperator between page links
-->
<#macro numbers maxPages = 9 separator = " | ">
    <#local pagesBefore = (maxPages / 2)?floor />
    <#local pagesAfter = (maxPages / 2)?floor />
    <#if maxPages % 2 == 0>
        <#local pagesBefore = pagesBefore - 1 />
    </#if>
    <#local pageNumMin = data.pageNumber - pagesBefore />
    <#local pageNumMax = data.pageNumber + pagesBefore />
    <#if (pageNumMin < 0)>
        <#local pageNumMax = pageNumMax + (0 - pageNumMin) />
        <#local pageNumMin = 0 />
    </#if>
    <#if (pageNumMax >= data.pagesAvailable)>
        <#local pageNumMin = pageNumMin - (pageNumMax - data.pagesAvailable) />
        <#local pageNumMax = data.pagesAvailable - 1 />
        <#if (pageNumMin < 0)>
            <#local pageNumMin = 0 />
        </#if>
        <#if (pageNumMax < 0)>
            <#local pageNumMax = 0 />
        </#if>
    </#if>
    <#list pageNumMin..pageNumMax as pageNumber>
        <#if pageNumber == data.pageNumber>
            <#local classAttr = "class=\"selected\"" />
        <#else>
            <#local classAttr = "" />
        </#if>
        <@page pageNumber, "", classAttr/><#if pageNumber_has_next>${separator}</#if>
    </#list>
</#macro>

<#--
 * Outputs a link to a specific page.
 *
 * @param pageNumber To page number ot link to
 * @param text (Optional) The link text (Defaults to page number if not set)
 * @param attributes (Optional) Any HTML attributes to add to the element
-->
<#macro page pageNumber text = "" attributes = "">
    <#if text == "">
        <#local text = (pageNumber + 1)?string />
    </#if>
    <#if (attributes != "" && attributes?starts_with(" ") == false)>
        <#local attributes = " " + attributes />
    </#if>
    <a href="?field=${data.sortField?url}&amp;page=${pageNumber}&amp;size=${data.pageSize}&amp;direction=${data.sortDirection?url}"${attributes}>${text?html}</a>
</#macro>

<#--
 * Outputs the current page number and the total pages
-->
<#macro counter>
    <#if data.pagesAvailable == 0>
        <#local pagesAvailable = 1 />
    <#else>
        <#local pagesAvailable = data.pagesAvailable />
    </#if>
    <@spring.messageArgsText "pagination.counter", [data.pageNumber + 1, pagesAvailable], "{0} of {1}" />
</#macro>

<#--
 * Outputs a link to sort by a field.

 * @param field The field to sort by. If field is different to the current sort field, the link will change the sort
 * field but not the sort direction. If the field is the same as the current sort field, the link will change the sort
 * direction.
 * @param text (Optional) The link text. If no text is specified the field name is used with a upper case first letter.
 * @param attributes (Optional) Any HTML attributes to add to the element
 * @param directions (Optional) An array of two items. The words being used in data.sortDirection to describe
 * the sorting direction of ascending or descending. Default: ["Asc", "Desc"]. So we can compare the current sorting
 * direction and switch to the converse.
-->
<#macro sort field text = "" attributes = "" directions = ["Asc", "Desc"]>
    <#if field == data.sortField>
        <#-- Change sort direction -->
        <#if data.sortDirection?lower_case == directions[0]?lower_case>
            <#local direction = directions[1] />
        <#else>
            <#local direction = directions[0] />
        </#if>
    <#else>
        <#-- Change sort field (leave sort direction) -->
        <#local direction = data.sortDirection />
    </#if>
    <#if text == "">
        <#local text = field?cap_first />
    </#if>
    <#if (attributes != "" && attributes?starts_with(" ") == false)>
        <#local attributes = " " + attributes />
    </#if>
    <a href="?field=${field?url}&amp;page=${data.pageNumber}&amp;size=${data.pageSize}&amp;direction=${direction?url}"${attributes}>${text?html}</a>
</#macro>
我的错误消失了,但我仍然看不到任何页面

数据是一个列表,但您尝试使用它执行data.pageNumber之类的操作。当然,这是行不通的;您必须首先从列表中选择一条RouteAddress

顺便说一句,如果您使用的是最新的FreeMarker版本,则错误消息将更有帮助。即使是那些试图帮助你的人,因为它也会引用失败的表达