Tiles Integration with Struts 2 Annotation - struts2

I have been trying to integrate Tiles with Struts 2 annotation based action but it's not working correctly.
As I don't have struts-config.xml and in every tutorial available at web they are referencing it with struts-config.xml.
First is it possible to integrate annotation based struts action with tiles. If yes then how?
#Action(value="/login",results={#Result(name="success",location="/home",type=TilesResult.class),
#Result(name="login",location="/jsp/userLogin.jsp")})
public String execute() {
This is what my code is but it always gives me error in MyEclipse at TilesResult.class that
Type mismatch: cannot convert from Class<TilesResult> to String
I have dependency in my pom:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-tiles-plugin</artifactId>
<version>2.1.8</version>
</dependency>
Can anyone help me how to add tiles in annotation based actions
I used type="tiles" instead of type=TilesResult.class then it has given me below exception
Caused by: The Result type [tiles] which is defined in the Result annotation on the class [class com.actions.LoginAction] 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 [com.actions#convention-default#] - [unknown location]
at org.apache.struts2.convention.DefaultResultMapBuilder.createResultConfig(DefaultResultMapBuilder.java:422)
at org.apache.struts2.convention.DefaultResultMapBuilder.createFromAnnotations(DefaultResultMapBuilder.java:394)
at org.apache.struts2.convention.DefaultResultMapBuilder.build(DefaultResultMapBuilder.java:202)
at org.apache.struts2.convention.PackageBasedActionConfigBuilder.createActionConfig(PackageBasedActionConfigBuilder.java:800)
at org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildConfiguration(PackageBasedActionConfigBuilder.java:586)
at org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildActionConfigs(PackageBasedActionConfigBuilder.java:318)
at org.apache.struts2.convention.ClasspathPackageProvider.loadPackages(ClasspathPackageProvider.java:53)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:204)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:55)

Try these :
Use type="tiles" instead of type="TilesResult.class"
Use your target tile definition, location="tiles-definition-name", instead of JSP page, location="/jsp/userLogin.jsp", in your result location
Have following in your web.xml:
<context-param>
<param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
<param-value>/WEB-INF/tiles.xml</param-value>
</context-param>
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
Have following in your struts.xml (If you are using annotations alone and no struts.xml, then you have to create a minimal one for this because there's no annotation available to define a custom result type)
<struts>
<constant name="struts.convention.default.parent.package" value="codeoftheday.blogspot.com"/>
<package name="codeoftheday.blogspot.com" extends="struts-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
</result-types>
</package>
</struts>
NOTE: I've written a detailed blog post here on this issue - Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebehind / Zero Config plugin using Eclipse IDE

"org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG" this definition is not available with Strut 2.5.10.1
I have used following jars in my project.
struts2-core-2.5.10.1
struts2-convention-plugin-2.5.10.1
struts2-tiles-plugin-2.5.10.1
javax.servlet-api-3.0.1
Please once you compare your web.xml with following code.
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.demo.action</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<!-- <param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name> -->
<param-name>org.apache.tiles.definition.DefinitionsFactory.DEFINITIONS_CONFIG</param-name>
<param-value>/WEB-INF/config/tiles.xml</param-value>
</context-param>
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>

Related

Tuckey UrlRewriteFilter and Struts2 gives 404 on first request

About 30 of my rewritten links work fine but I have a couple that don't work the first time they are called but they do work the second time!
This is the web.xml snippets:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>uk.co.prodia.prosoc.struts2.action</param-value>
</init-param>
</filter>
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
and here is the urlrewrite.xml that gives a 404 the first time it is called:
<rule>
<from>^/forgotten-password$</from>
<to>/unsecured/forgotten-password!input.action</to>
</rule>
and the struts2 config for that action:
<package name="unsecured" extends="struts-default" namespace="/unsecured">
<action name="forgotten-password" class="actionForgottenPassword">
<result name="input">/WEB-INF/view/unsecured/forgotten-password.jsp</result>
<result name="passwordNotFound">/WEB-INF/view/unsecured/forgotten-password.jsp</result>
</action>
</package>
However if I make the urlrewrite.xml pass through the unsecured package which contains the forgotten-password action then it works:
<rule>
<from>^/unsecured/forgotten-password$</from><!--works through /unsecured -->
<to>/unsecured/forgotten-password!input.action</to>
</rule>
It seems that missing of the Struts2 package name from the urlrewrite causes the 404 the first time the URI is used.
Does this make any sense to anyone or shall I just stay in crazy town?
The problem seems to be caused by the jsessionid in the URL on the first page load of the context. I am a bit useless with regexp but this seems to work:
<rule>
<from>^/forgotten-password(;jsessionid=.*)?$</from>
<to>/unsecured/forgotten-password!input.action</to>
</rule>
I added the (;jsessionid=.*)? to the end of each of the rules and it seems to work.

how use primefaces and prettyfaces together?

Primefaces doesn't work when primefaces and pretty face use together.
I add flowing jar:
prettyfaces-jsf2-3.3.3.jar
primefaces-4.0-20130605.174828-3.jar
My web.xml code:
<filter>
<filter-name>Pretty Filter</filter-name>
<filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Pretty Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
My pretty-config.xml code:
<rewrite match="^[^(/primefaces_resource/)|^(javascript)]" trailingSlash="append" toCase="lowercase" redirect="301"/>
<url-mapping id="home">
<pattern value="/" />
<view-id value="/" />
</url-mapping>
This image is whithou prittyface( jar and configure):
when I add pretty face jar .then flowing view:
I want to change the url.
example:
(http://localhost:8084/AntSchoolMS/faces/index.xhtml)
I want it to be changed as
(http://localhost:8084/AntSchoolMS/)
please help me .
I use primefaces 3.5 with pretty faces 3.3.3 and works ok. The configuration in your web.xml seems to be ok. Make sure you place pretty-config.xml also in WEB-INF.
About the pretty-config you posted: it doesn't make any sense to have a url-mapping where the pattern and the view-id are the same, so remove it.
Also I don't have that rewrite rule, I have several mappings like the folowing:
<url-mapping id="login">
<pattern value="/login/">
<view-id value="/login.jsf" />
</url-mapping>
Did you try removing that rewrite rule to see what happens?
I've been using these two for some time and they are working as expected. My project used the 3.5 version of primefaces and PrettyFaces 3.3.3.
In my web.xml I did not need to register any filter like you did.
I would also try to remove the rewrite rule as Damian suggests.
Additionally, I would recommend upgrading to the latest version of PrettyFaces - see http://ocpsoft.org/prettyfaces/

Struts 2 Portlet - redirectAction not working, doView() not called

I'm trying to create a simple Struts 2 JSR 286 Portlet, running on WebSphere Portal 7. I'm able to display a simple JSP that contains a link which calls an action and displays another JSP which accepts input. That works fine.
I start to run into problems, however, when I try to use a redirectAction. I don't see any error messages, but the redirect doesn't seem to work. The Portlet just shows a blank page.
In debugging this I noticed that the doView method of my Portlet class is never called, which seems very suspicious.
If anyone has experience developing Struts 2 Portlets on WebSphere Portal, I would appreciate some help in checking that my config files are correct. Have I missed something?
Here are the details:
WebSphere Portal 7.0.0.2
WebSphere Application Server 7.0.0.25
RAD 8.0.4
Struts 2.3.14.2
Windows 7
portlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app id="com.ibm.demo.jsr286.TopUpPortlet.72594d5fe3"
version="2.0"
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
<portlet>
<description xml:lang="EN">Demo JSR 286 Struts Portlet</description>
<portlet-name>Demo Portlet</portlet-name>
<display-name>Demo Portlet</display-name>
<!-- DemoPortlet extends org.apache.struts2.portlet.dispatcher.Jsr286Dispatcher -->
<portlet-class>com.demo.jsr286.DemoPortlet</portlet-class>
<init-param>
<name>viewNamespace</name>
<value>/view</value>
</init-param>
<init-param>
<name>defaultViewAction</name>
<value>index</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<portlet-info>
<title>Demo Portlet</title>
<short-title>DemoPortlet</short-title>
<keywords>Demo Portlet</keywords>
</portlet-info>
</portlet>
<default-namespace>http://JSR286StrutsDemo/</default-namespace>
</portlet-app>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" 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">
<display-name>JSR 286 Struts Demo</display-name>
<servlet id="Struts2PortletDispatcherServlet">
<servlet-name>Struts2PortletDispatcherServlet</servlet-name>
<servlet-class>org.apache.struts2.portlet.dispatcher.DispatcherServlet</servlet-class>
</servlet>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</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>
<include file="struts-plugin.xml"/>
<package name="view" extends="struts-portlet-default" namespace="/view">
<!-- This action works -->
<action name="index">
<result>/html/view/index.jsp</result>
</action>
<!-- This action works -->
<action name="startDemo">
<result>/html/view/demo.jsp</result>
</action>
<!-- This action does not work -->
<action name="redirectToIndex">
<result type="redirectAction">
<param name="actionName">index</param>
<param name="namespace">/view</param>
<param name="portletMode">view</param>
</result>
</action>
</package>
</struts>
* Update *
I've narrowed the problem down slightly. It looks like the action is being interpreted as a file location rather than a struts action. So, when I call action "redirectToIndex" it tries to display a page called "/view/index.action". I verified this by creating a file with that path and sure enough, the contents of that file are displayed in the portlet.
I feel that I'm probably missing some configuration option, but I'm not sure what. Servlet filter maybe? Can anyone help?
Actually you don't need doView method, because Jsr286Dispatcher is just a dispatcher. You can use actions like in ordinary Struts2 application.
From the documentation:
The portlet-class element is always org.apache.struts2.portlet.dispatcher.Jsr168Dispatcher (or a subclass, if you have added some custom functionality). This is the portlet that acts as the dispatcher for the Struts 2 framework, and translates incoming user interaction to action requests that Struts 2 understands.
For jsr286 specification <portlet-class> should be org.apache.struts2.portlet.dispatcher.Jsr286Dispatcher and defaultViewAction init-param will call Struts2 action. And in struts.xml file, like usually, you can define action class + method to call.
So you need to define Jsr286Dispatcher as <portlet-class> and create action which you will use in struts.xml action definitions.
Also see this two links: http://struts.apache.org/development/2.x/docs/struts-2-portlet-tutorial.html and http://struts.apache.org/development/2.x/docs/portlet-plugin.html.

Hide the .jsp url extension in struts2 project

I am working in the struts2 web application.I want to do the mapping of my url such that the extensions like ".jsp" should be eliminated from the url.
So below is the snippet code of my web.xml.I want to do that my url show /login instead of /login.jsp.
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>URLFilter</filter-name>
<filter-class>example.MyFilter</filter-class>
<init-param>
<param-name>onError</param-name>
<param-value>/login.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>URLFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Just access all your JSPs through Actions (and put them somewhere below WEB-INF to enforce this policy). It's easy to do with the "default action" of Struts2:
<action name="login">
<result>/WEB-INF/pages/login.jsp</result>
</action>
I don't know how well this integrates with ServletFilter, maybe you'll have to turn the one mentioned in your web.xml into a Struts2 Interceptor.
You can change url extension using property file as shown in below link :
http://www.aoiblog.com/change-url-extension-in-struts2/

Calling ActionClass in tiles.xml using Struts 2.0

I reviewed the example of tiles with struts2.0 and found that in tiles.xml jsp pages are called like:
<definition name="welcome" extends="baseLayout">
<put-attribute name="title" value="Welcome"/>
<put-attribute name="body" value="/welcome.jsp"/>
BUT my question is if I want to call the action class instead of .jsp pages than how to call it like
<definition name="friends" extends="baseLayout">
<put-attribute name="title" value="Friends"/>
<put-attribute name="body" value="/checkActionLink.action"/>
when I am trying to write to execute the above code than its showing the error that checkActionLink.action is not found....thanks in advance for the help.....
Following is the web.xml file
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Struts2Example15</display-name>
<servlet>
<servlet-name>tiles</servlet-name>
<servlet-class>org.apache.tiles.web.startup.TilesServlet</servlet-class>
<init-param>
<param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
<param-value>/WEB-INF/tiles.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</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>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
After so much research I found out that adding the following tag:
<dispatcher>FORWARD</dispatcher> in the web.xml the issue gets resolved.
Now the question arises why?
As per my understanding when we add any action as the value of value attribute of the <put-attribute/> tag the request is forwarded to the mentioned action so the action is executed successfully.
Previously <dispatcher>FORWARD</dispatcher> tag was missing so this issue was caused.
I would really appreciate if any correction is there in my understanding.
Thanks. Happy Coding :).
I don't think you can. You'll need to create a jsp and use the struts2 action tag in it. That can call an action and render part of it's page. If you make a jsp only using the action tag, you'll probably get the effect you want. Have never tried this, but you can probably insert the name of the action and namespace from tiles into the action tag before the jsp is invoked.
I would be very interested to hear how this works out for you.

Resources