How to integrate Struts 2 with Tiles 3

前端 未结 3 766
面向向阳花
面向向阳花 2020-11-28 15:42

How do we integrate Struts 2 with Tiles 3? The struts2-tiles-plugin currently (2.3.4.1) works with an older version of tiles (version 2.0.6) this can be a bit of a nuisance.

相关标签:
3条回答
  • 2020-11-28 16:02
    <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
    

    use mentioned doctype in your tiles.xml

    0 讨论(0)
  • 2020-11-28 16:04

    The solution is to add the required dependencies, load tiles with an appropriate listener and create a custom result type. Fortunately these steps are quite easy, once done you can follow normal tiles 2 examples for a how to define templates.

    1) Dependencies (start with basic struts project but in this example I'll use conventions so it might just be best to add struts2-conventions-plugin, it will include struts2-core et al):

    • DO NOT INCLUDE struts2-tiles-plugin
    • groupId: org.apache.tiles, artifiactId: tiles-extras, version: 3.0.1
    • groupId: org.slf4j, artifiactId: jcl-over-slf4j, version: 1.5.8
    • groupId: org.slf4j, artifiactId: slf4j-jdk14, version: 1.5.8

    Note: A higher version of the slf4j dependencies may work I have not tested this.

    2) load tiles with an appropriate listener

    This example includes the full web.xml, lines 3-5 are the only thing that should be new to someone familiar with struts2.

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 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-app_2_5.xsd">
        <listener>
            <listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
        </listener>
        <filter>
            <filter-name>struts2</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>struts2</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    </web-app>
    

    3) create a custom result type

    We need to define a custom result type for use with our actions:

    package com.quaternion.result;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.struts2.ServletActionContext;
    import org.apache.struts2.dispatcher.ServletDispatcherResult;
    import org.apache.tiles.TilesContainer;
    import org.apache.tiles.access.TilesAccess;
    import org.apache.tiles.request.ApplicationContext;
    import org.apache.tiles.request.servlet.ServletRequest;
    import org.apache.tiles.request.servlet.ServletUtil;
    
    public class TilesResult extends ServletDispatcherResult {
    
        public TilesResult() {
            super();
        }
    
        public TilesResult(String location) {
            super(location);
        }
    
        @Override
        public void doExecute(String location, ActionInvocation invocation) throws Exception {
            //location = "test.definition"; //for test
            setLocation(location);
            ServletContext context = ServletActionContext.getServletContext();
            ApplicationContext applicationContext = ServletUtil.getApplicationContext(context);
            TilesContainer container = TilesAccess.getContainer(applicationContext);
            HttpServletRequest request = ServletActionContext.getRequest();
            HttpServletResponse response = ServletActionContext.getResponse();
            ServletRequest servletRequest = new ServletRequest(applicationContext, request, response);
            container.render(location, servletRequest);
        }
    }
    

    4) We also need to tell struts2 about our result type:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    <struts>
        <constant name="struts.devMode" value="true" />
        <constant name="struts.ui.theme" value="simple" />
        <package  name="tiles-package"  namespace="" extends="struts-default">
            <result-types>
                <result-type default="true" name="tiles-result" class="com.quaternion.result.TilesResult"/>
            </result-types>
        </package>   
    </struts>
    

    With that out of the way we can now use tiles in our projects, assume we have created a tiles definition called "test.definition" we can tell our action to use that definition by doing the following:

    package com.quaternion.demo.action.test;
    
    import com.opensymphony.xwork2.ActionSupport;
    import org.apache.struts2.convention.annotation.ParentPackage;
    import org.apache.struts2.convention.annotation.Result;
    
    @ParentPackage("tiles-package")
    @Result(type="tiles-result", location="test.definition")
    public class QuaternionResultTest extends ActionSupport{}
    

    That's it, this will let you configure any version of struts2 with tiles 3+, please see http://tiles.apache.org/framework/index.html for further configuration details.

    0 讨论(0)
  • 2020-11-28 16:14

    Thanks to Ken a new plugin was added to Struts 2 to support Tiles 3 result type, it should be available with upcoming new release - Struts 2.3.9

    https://cwiki.apache.org/confluence/display/WW/Tiles+3+Plugin

    0 讨论(0)
提交回复
热议问题