简体   繁体   中英

Spring 4 + Tiles (3 || 2.2.2) - Any way to access beans in view context?

I am trying to access Beans in Tiles view.

Tried solutions:

Solution 1 that i tried

The solution Accessing Spring beans from a Tiles view (JSP) that francarl posted (ServletContextAttributeExporter) is working fine on first view (hello.jsp, not theme.jsp).

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
        "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
        "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
    <definition name="defaultTheme" template="/WEB-INF/views/theme.jsp" />
</tiles-definitions>

I can access that bean in hello.jsp but not in /WEB-INF/views/theme.jsp


Solution 2 that i tried

Tried to skaffman solution, 'TilesExposingBeansViewResolver', is executing and buildview and it's code view.setExposeContextBeansAsAttributes(this.exposeContextBeansAsAttributes); is executed too. But renderMergedOutputModel is view class is not executed. Tried a lot of way to doing this. (tried with these orders -1, 1, 10, 100, 99999). I don't sure whatever i can access these beans at theme.jsp even it would work. (i don't know why this one doesn't fire up)


Solution 3 that i tried

Tried to create a ViewPreparer, execute is working and SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); is sucessfully injects the bean into ViewPreparer. But i am unabled to transfer anything from ViewPreparer to theme and hello.jsp

public class ViewPiewPreparer implements ViewPreparer {

    @Autowired
    private MainBean kmpv;

    public void execute(TilesRequestContext tilesRequest, AttributeContext attributeContext)
            throws PreparerException {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

        System.out.println(kmpv.getTwits().size()); // working

        // i cant access any of these in hello and template
        tilesRequest.getRequestScope().put("deneme", "deneme");
        tilesRequest.getSessionScope().put("deneme", "deneme");
        tilesRequest.getApplicationContext().getApplicationScope().put("deneme", "deneme")

    }
}

Is there any solution to this? I just need to access news and tweets from my theme.jsp.

public class MainBean {

    @Autowired
    KampTanimFacade kampTanimFacade;

    @Autowired
    KategoriFacade kategoriFacade;

    public List<Kategori> getKamplar() {
        return kategoriFacade.getMenuList();
    }

    public List<Status> getTwits() {
        return MainServlet.twitter.statuses;
    }

    public String getDeneme() {
        return "deneme";
    }
}

If you set your TilesConfigurer to resolve preparers for bean names:

@Bean
public TilesConfigurer getTilesConfigurer() {
    TilesConfigurer configurer = new TilesConfigurer();
    configurer.setDefinitions(new String[] { "/WEB-INF/tiles.xml" });
    ...
    configurer.setPreparerFactoryClass(SpringBeanPreparerFactory.class);
    return configurer;
}

And configure your tiles definition to use an specific view preparer (spring bean name) in tiles.xml:

<definition name="viewName" template="/WEB-INF/.../view.jsp" preparer="aViewPreparer">
    <put-attribute .... />
</definition>

You always can define a bean (inside your @ComponentScan) like:

@Component
public class AViewPreparer implements ViewPreparer {

    @Autowired
    private AutowiredBean autowiredBean;

    @Override
    public void execute(Request tilesRequest, 
        AttributeContext attributeContext) throws PreparerException {
        attributeContext.putAttribute("tilesAttributeName", 
            new Attribute("tilesAttributeValue"));
    }
}

This way you can print the attribute (String) using this in your jsp:

<tiles:insertAttribute name="tilesAttributeName"/>

If you need to use a complex object as an attribute, like your bean or a list, you can use the following in the jsp:

<tiles:importAttribute name="tilesAttributeName"/>

And then, you have the object in page scope and can work with it (in the case of a list):

<c:forEach items="${tilesAttributeName}" var="item">
    ${item}
</c:forEach>

You can also use SimpleSpringPreparerFactory instead of SpringBeanPreparerFactory in your TilesConfigurer, but in this case you should use the complete class name of the view preparer in tiles.xml:

<definition name="viewName" template="/WEB-INF/.../view.jsp" preparer="package.name.of.view.preparer.AViewPreparer">
    <put-attribute .... />
</definition>

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