Calling ActionClass in tiles.xml using Struts 2.0 - struts2

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.

Related

index.html change to index.xhtml

When trying to logout my application I'm having the following error message :
com.sun.faces.context.FacesFileNotFoundException: /index.xhtml Not Found in ExternalContext as a Resource
To logout I'm going though the following steps inside PhaseListener.beforePhase(PhaseEvent phaseEvent) :
// Redirect to index.html
NavigationHandler nh = fctx.getApplication().getNavigationHandler();
String action_outcome = "/index.html";
nh.handleNavigation(fctx, null, action_outcome);
My web.xml is as follow :
<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_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID"
version="3.0">
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<filter-mapping>
<filter-name>Seam Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>trinidad</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.seam</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>Restrict raw XHTML Documents</display-name>
<web-resource-collection>
<web-resource-name>XHTML</web-resource-name>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
I do not have index.xhtml in my app, but I do have and want to keep it index.html file.
Why is my outcome_action given to NavigationHandler rename to index.xhtml ?
How could I avoid it ?
The NavigationHandler expects a JSF page, not a non-JSF page. Moreover, you're there actually not sending a real redirect at all, on the contrary to what the code comment says there. You're just performing a forward here.
Performing a real redirect would be the solution to your problem. It's to be done as below:
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "/index.html");
See also:
What is the difference between redirect and navigation/forward and when to use what?
How to navigate in JSF? How to make URL reflect current page (and not previous one)
Unrelated to the concrete problem, doing authorization job in a phase listener stinks. Have you considered a servlet filter?
See also:
Limitations of using a PhaseListener instead of a Servlet Filter for authorization
Failing to redirect from JSF phaselistener
How to invalidate session in JSF 2.0?

Primefaces 4, Omnifaces 1.7 JSF handle session timeout fail

faces-config.xml
<factory>
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>
web.xml
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/Login/login.xhtml</location>
</error-page>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
<filter>
<filter-name>facesExceptionFilter</filter-name>
<filter-class>org.omnifaces.filter.FacesExceptionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>facesExceptionFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
After a session timeout i want to be redirectet to the login page. I use Form based authentication. When i login wait one minute and then hit a button i often get the following page:
error page:
<partial-response id="j_id1">
<redirect url="/CuViS/Manager/show.xhtml"/>
<changes>
<update id="j_id1:javax.faces.ViewState:0">-2290296337409893276:-7107311277476366039</update>
</changes>
</partial-response>
Where the url is the current page where i clicked the button.
When i remove the omnifaces configuration the same behavior appears. What I am doing wrong?

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.

Tiles Integration with Struts 2 Annotation

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>

How to extend an XML File using ant xmltask by copying tags from a source-file to the dest-file in specific positions

Im trying to create a special web.xml for local development.
I have some tags stored in a separate xml-file which need to be selected and pasted to specific positions inside the final web.xml.
To achieve this I am using the copy and the paste action in the following manner:
<xmltask source="templates.xml">
<copy path="//data/init-param" buffer="initParamBuffer"/>
</xmltask>
<xmltask source="web.xml" dest="web.xml">
<paste path="//web-app/filter[contains(./filter-name,'MyFilter')]
/init-param[contains(./param-name,
'MyInitParameter')]"
position="after" buffer="initParamBuffer"/>
</xmltask>
My intention is to gather ALL init-param Tags from the source File and paste them after the Tag selected in the paste operation.
Also the Part where Im selecting a Tag which contains a tag with a specified content using the contains() function is not working smoothly either.
Maybe there is a better way to form this xpath expression...
update:
As I have written before, I do not know the best approach to this problem. I have read about the possibility to transform using stylesheets, but since the ant-xmltask promised to be a more sleak sollution I have tried this first.
As far as I have come with this approach, it is possible to insert/write tags into the web.xml using this approach. I have succeeded in inserting single init-param tags at locations that where sligtly off, with a less complex expression:
<paste path="//web-app/filter[1]/init-param"
position="after" buffer="initParamBuffer"/>
So my Problem was:
A: I want to select more than one tag into the buffer
B: I want to insert the content of that buffer after a tag specified by a name (not index).
Here is an example for the sources (templates.xml) to insert into the web.xml:
<data>
<init-param>
<param-name>newparam1</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>newparam2</param-name>
<param-value>2</param-value>
</init-param>
</data>
Here is part of an web.xml where the above section is to be pasted:
<web-app>
<filter-mapping>
<filter-name>SomeFilter</filter-name>
<url-pattern>/somePath/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/myPath/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SomeFilter</filter-name>
<filter-class>foo.bar.SomeFilter</filter-class>
<init-param>
<param-name>SomeInitParameter</param-name>
<param-value>4711</param-value>
</init-param>
</filter>
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>foo.bar.MyFilter</filter-class>
<init-param>
<param-name>MyInitParameter</param-name>
<param-value>0815</param-value>
</init-param>
</filter>
</web-app>
And here is the result I would hope to achieve:
<web-app>
<filter-mapping>
<filter-name>SomeFilter</filter-name>
<url-pattern>/somePath/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/myPath/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SomeFilter</filter-name>
<filter-class>foo.bar.SomeFilter</filter-class>
<init-param>
<param-name>SomeInitParameter</param-name>
<param-value>4711</param-value>
</init-param>
</filter>
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>foo.bar.MyFilter</filter-class>
<init-param>
<param-name>MyInitParameter</param-name>
<param-value>0815</param-value>
</init-param>
<init-param>
<param-name>newparam1</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>newparam2</param-name>
<param-value>2</param-value>
</init-param>
</filter>
</web-app>
Use XPath Or:
Path|Path
From:
<paste path="//web-app/filter[1]/init-param" position="after" buffer="initParamBuffer"/>
To:
<paste path="//web-app/filter[1]/init-param|//web-app/filter[2]/init-param" position="after" buffer="initParamBuffer"/>
XPath is a Query language operating on the XML Infoset of XML documents. It can only return results or select nodes, but it cannot change the structure of the source XML document or modify it in any way.
A suitable language, designed especially for processing XML documentsand producing new XML documents, is XSLT.
The task specified in your question can be done in a very easy way using XSLT.
Please, provide a complete (but minimal) source XML document, the complete wanted result and specify any rules that the transformation should follow. Then many people will be able to give you correct and useful solutions.

Resources