noShowP
noShowP

Reputation: 830

Struts 2 Tile and REST plugin

I'm trying to get my Struts2 project running with Tiles and REST Plugin but I just can't get it working.

I've looked at the documentation for both and I think i'm doing it right. here are my files:

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app metadata-complete="true" 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">

    <!-- listeners -->

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
    </listener>

    <!-- context params -->
    <context-param>
        <param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
        <param-value>/WEB-INF/tiles-tradesman.xml</param-value>
    </context-param>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring-tradesman.xml</param-value>
    </context-param>


    <!-- filters -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>

    <!-- filter mappings -->
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

struts.xml

<?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" />

    <!-- RESTful plugin setup -->
    <constant name="struts.mapper.class" value="rest" />
    <constant name="struts.convention.action.suffix" value="Controller"/>
    <constant name="struts.convention.action.mapAllMatches" value="true"/>
    <constant name="struts.convention.default.parent.package" value="rest-default"/>
    <constant name="struts.convention.package.locators" value="tp"/>

    <package name="tradesman" namespace="/beta/tradesman" extends="default">

        <result-types>
            <result-type name="json" class="org.apache.struts2.json.JSONResult"/>
            <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
        </result-types>
        <interceptors>
            <interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/>
        </interceptors>

    </package>
</struts>

JobAlertsController.java

package uk.co.ratedpeople.tp;

import com.opensymphony.xwork2.ActionSupport;
import java.util.logging.Logger;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;

public class JobAlertsController extends ActionSupport {

    private static final Logger LOGGER = Logger.getLogger(JobAlertsController.class.getName());

    @Action(results={
        @Result(name = SUCCESS, location = "tradesman.page.jobalerts", type = "tiles")
    })
    public String index() {
        LOGGER.info("executing index action...");
        LOGGER.info("leaving index action...");
        return SUCCESS;
    }
}

When i try to run the project I get this error:

SEVERE: Exception starting filter struts2
Unable to load configuration. - [unknown location]
    at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:437)
    at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:195)
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:273)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:254)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:372)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:98)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4542)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5220)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5215)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
Caused by: Unable to load configuration. - [unknown location]
    at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:69)
    at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:380)
    at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:424)
    ... 13 more
Caused by: The Result type [tiles] which is defined in the Result annotation on the class [class uk.co.ratedpeople.tp.JobAlertsController] or determined by the file extension or is the default result type for the PackageConfig of the action, could not be found as a result-type defined for the Struts/XWork package [uk.co.ratedpeople.tp#rest-default#] - [unknown location]
    at org.apache.struts2.convention.DefaultResultMapBuilder.createResultConfig(DefaultResultMapBuilder.java:427)
    at org.apache.struts2.convention.DefaultResultMapBuilder.createFromAnnotations(DefaultResultMapBuilder.java:399)
    at org.apache.struts2.convention.DefaultResultMapBuilder.build(DefaultResultMapBuilder.java:200)
    at org.apache.struts2.convention.PackageBasedActionConfigBuilder.createActionConfig(PackageBasedActionConfigBuilder.java:864)
    at org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildConfiguration(PackageBasedActionConfigBuilder.java:650)
    at org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildActionConfigs(PackageBasedActionConfigBuilder.java:335)
    at org.apache.struts2.convention.ClasspathPackageProvider.loadPackages(ClasspathPackageProvider.java:53)
    at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:215)
    at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
    ... 15 more
27-Jul-2011 17:07:07 org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext

I'm sure i'm doing something really stupid but I can't see it myself. Anyone?

Upvotes: 4

Views: 6411

Answers (1)

Russell Shingleton
Russell Shingleton

Reputation: 3196

First, I would suggest putting your struts actions in a package simply called struts, I've had much less configuration issues when using standard conventions plugin architecture. Move your actions to a package like:

uk.co.ratedpeople.struts

instead of

uk.co.ratedpeople.tp;

The less out of the box configuration, the better off you typically are. This also eliminates the need for this:

<constant name="struts.convention.package.locators" value="tp"/>

Second, part of your problem is with your xml configuration:

<struts>
    <constant name="struts.devMode" value="true" />

    <!-- RESTful plugin setup -->
    <constant name="struts.mapper.class" value="rest" />
    <constant name="struts.convention.action.suffix" value="Controller"/>
    <constant name="struts.convention.action.mapAllMatches" value="true"/>
    <constant name="struts.convention.default.parent.package" value="rest-default"/>
    <constant name="struts.convention.package.locators" value="tp"/>

    <package name="tradesman" namespace="/beta/tradesman" extends="default">

        <result-types>
            <result-type name="json" class="org.apache.struts2.json.JSONResult"/>
            <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
        </result-types>
        <interceptors>
            <interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/>
        </interceptors>
</package>

Try something like this instead (providing you moved your actions as previously suggested):

<struts>
    <constant name="struts.devMode" value="true" />

    <!-- RESTful plugin setup -->
    <constant name="struts.mapper.class" value="rest" />
    <constant name="struts.convention.action.suffix" value="Controller"/>
    <constant name="struts.convention.action.mapAllMatches" value="true"/>
    <constant name="struts.convention.default.parent.package" value="tradesman"/>

    <package name="tradesman" namespace="/beta/tradesman" extends="rest-default">
        <result-types>
            <result-type name="json" class="org.apache.struts2.json.JSONResult"/>
            <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
        </result-types>
    </package>
</struts>

Notice the constant name="struts.convention.default.parent.package" value="tradesman" which is referring to the package below it which defines your result types and extends rest-default. This should eliminate your tiles result definition errors.

I've also run into issues using the struts filter you have in your web.xml, I would change from:

<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

to:

<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

Upvotes: 5

Related Questions