I'm trying to configure sitemesh to only take effect for a certain subset of action mappings in my Struts 2 application.
Say for example, I have the following struts.xml snippet:
<package name="default" namespace="/" extends="struts-default">
<action name="showForm">
<result>/view/form.jsp</result>
</action>
</package>
<package name="widgets" namespace="/widgets" extends="struts-default">
<action name="showForm">
<result>/view/form.jsp</result>
</action>
</package>
I would like the output of "/showForm.action" to be decorated by SiteMesh but for "/widgets/showForm.action" to be returned empty instead. The critical part here is that I want the JSP file to be reused by both action mappings.
But try as I might, I can't seem to get SiteMesh's tag to recognize a mapping. I have to specify the file "/view/form.jsp" to be excluded instead and that means I won't be able to reuse the JSP file.
Is there any way I can get around this?
I'm using Struts 2.0.14.
Thanks,
Wong
Same answer as for Using SiteMesh with RequestDispatcher's forward(). You can change the way the sitemesh filter is mapped to incoming requests.
I think you'd want:
<filter-mapping>
<filter-name>sitemesh</filter-name>
<servlet-name>MyServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
Related
I am working on a project using Struts 1.3 from what I can tell, given that this is at the top of the struts-config-default.xml file:
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">
Is there any way to go about mapping a wildcard for an action forward to a jsp file? I have tried all sorts of wildcard variations:
<action path="/hello/candy" type="com.officedepot.globalweb.framework.action.ForwardDisplayAction">
<forward name="success" path="/WEB-INF/jsp/candyStore.jsp" />
</action>
I have a single page application that gets loaded in the 'candyStore.jsp' so i would like all and any URIs after /hello/candy to route to the same JSP. (eg. www.site.com/hello/candy/pageOne, www.site.com/hello/candy/33/jellybean, www.site.com/hello/candy/test all should forward to the jsp candyStore)
Is this at all possible using Struts 1.3 or should I be writing all the possible routes :(
Thanks!
In your action file
public ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request , HttpServletResponse response)
throws Exception{
//Perform any code here like error 404.
return mapping.findForward("unspecified");
}
In your struts action path in config file
<forward name="unspecified" path="/candyStore.jsp"/>
About 30 seconds on Google:
https://dzone.com/tutorials/java/struts/struts-example/struts-wildcards-in-action-mapping-example.html
<action-mappings>
<action path="/*Action" type="com.vaannila.reports.{1}Action" name="{1}Form">
<forward name="success" path="/{1}.jsp" />
</action>
</action-mappings>
You would not require the wildcard in the forward's path.
I use struts in my Java EE project:
In my loading.jsp if I use the below src, I will get 404 error:
<IFRAME src="${pageContext.request.contextPath}/WEB-INF/page/menu/alermDevice.jsp" name="dev" id="dev" frameBorder="0" width="500" scrolling="auto" height="400">
</IFRAME>
But if I use below src:
<IFRAME src="elecMenuAction_alermDevice.do" name="dev" id="dev" frameBorder="0" width="500" scrolling="auto" height="400">
</IFRAME>
I will get the correct information.
This is my struts.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true"></constant>
<constant name="struts.ui.theme" value="simple"></constant>
<constant name="struts.action.extension" value="do"></constant>
<package name="system" namespace="/system" extends="struts-default">
<action name="elecTextAction_*" class="elecTextAction" method="{1}">
<result name="save">/system/textAdd.jsp</result>
</action>
<action name="elecMenuAction_*" class="elecMenuAction" method="{1}">
<result name="menuHome">/WEB-INF/page/menu/home.jsp</result>
<result name="title">/WEB-INF/page/menu/title.jsp</result>
<result name="left">/WEB-INF/page/menu/left.jsp</result>
<result name="change">/WEB-INF/page/menu/change.jsp</result>
<result name="loading">/WEB-INF/page/menu/loading.jsp</result>
<result name="logout" type="redirect">index.jsp</result>
<result name="alermStation">/WEB-INF/page/menu/alermStation.jsp</result>
<result name="alermDevice">/WEB-INF/page/menu/alermDevice.jsp</result>
</action>
</package>
</struts>
Why I use the path can not access the JSP? only use the action I can get it yet?
The web server cannot get resources from and below WEB-INF folder. When action is invoked it returns a response as an execution of the result. It's used a result type dispatcher which is used by default to forward request to the specified URL (the requested JSP page).
Dispatcher Result
Includes or forwards to a view (usually a jsp). Behind the scenes
Struts will use a RequestDispatcher, where the target servlet/JSP
receives the same request/response objects as the original
servlet/JSP. Therefore, you can pass data between them using
request.setAttribute() - the Struts action is available.
There are three possible ways the result can be executed:
If we are in the scope of a JSP (a PageContext is available), PageContext's PageContext#include(String) method is
called.
If there is no PageContext and we're not in any sort of include (there is no "javax.servlet.include.servlet_path" in the request
attributes), then a call to
RequestDispatcher#forward(javax.servlet.ServletRequest,
javax.servlet.ServletResponse) is made.
Otherwise, RequestDispatcher#include(javax.servlet.ServletRequest,
javax.servlet.ServletResponse) is called.
When servlet dispatcher is invoked it has not such restriction and can return resource with the same response that was originally requested.
I am using Struts2. Below is my Action Class (TutorialAction).
public class TutorialAction {
public String execute() {
System.out.println("Hello from Execute!");
return "failure";
}
}
I am returning "failure" in execute method of this Action class.
Below are my 2 struts config files :
======================== 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>
<package name="default" namespace="/tutorials" extends="struts-default">
<action name="getTutorial" class="com.tushar.action.TutorialAction">
<result name="failure">/ErrorPage.jsp</result>
</action>
</package>
<include file="struts2.xml"></include>
</struts>
In above config file I am including another struts config file(struts2.xml) for same namespace :
======================== struts2.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>
<package name="default" namespace="/tutorials" extends="struts-default">
<action name="getTutorial" class="com.tushar.action.TutorialAction">
<result name="failure">/SuccessPage.jsp</result>
</action>
</package>
</struts>
My project is running fine. I am just curious to know if included file in struts.xml (which is struts2.xml) is run after main struts.xml or before ?
Or what would be the output: /SuccessPage.jsp or /ErrorPage.jsp?
Struts configuration is built after xml documents has been parsed on the start up of your application. Then it uses configuration properties to map actions under their namespaces. This mapping is created via iterating all packages which is also a map. If you have the same namespace in other packages then the last will override the previous mapping. You should know that iterating a map doesn't guarantee the order of the retrieved elements. See HashMap.
So, the order in which the namespace mapping is created is not guaranteed and that namespace will only contain those actions put by the iterator at last time. The namespace to actions mapping is used when Struts2 is getting action config from the action mapping (at the time it's creating an action proxy) created after parsing an URL. Then it continues if such action config is found. The results are mapped to an action, and you don't have results with the same name.
Hope it's easy to understand. If you have the same namespace and the same action name, and the same package name which I doubt impossible, such configuration can't be used and might lead to unpredictable results. And this is not important in which order the packages are created. Note the order is important if you have dependency between packages that are absent in your case.
If you have struts2 config like this.
<struts>
<package name="default" namespace="/tutorials" extends="struts-default">
<action name="getTutorial" class="com.tushar.action.TutorialAction">
<result name="failure">/ErrorPage.jsp</result>
</action>
</package>
<include file="struts-module2.xml"></include>
</struts>
or
<struts>
<include file="struts-module1.xml">
<include file="struts-module2.xml"></include>
</struts>
and according to Practical Apache Struts 2 Web 2.0 Projects.
When including files, the order is very important. Dependencies between include files are not automatically determined
and resolved, so if struts-module1.xml is dependent on the
configuration provided in struts-module2.xml (and struts-module2.xml
is configured after struts-module1.xml), an exception thrown. The
solution is to change the file that the dependent configuration is
contained within or to change the order of the include files.
But since you have same url which is /getTutorial the last one you've configured always win because you're overwriting your definitions. So the the first one will be useless, you should give another name if you want to use both.
If a request is made to a HTML page, how to return it directly from struts.xml without going to an action?
Create an action that has a result in the struts.xml but doesn't have a class, i.e.
<package name="default" extends="struts-default">
<action name="index">
<result name="myPage">/path/to/page.html</result>
</action>
You could also create a global result, that could be found from any action, i.e
<global-results>
<result name="myPage">/path/to/page.html</result>
</global-results>
<action name="index"/>
You could create an interceptor that returns a result while intercepting and action. These are essential elements of the configuration that invoke a dispatcher to forward to requested page.
I'm using Struts2. I run a action named hello1.
I input the url: http://localhost:8081/MyStruts2/hello1, it works.
And I tried another url:http://localhost:8081/MyStruts2/hello1.action, it also works?
I don't think we need the ".action".
So why do some people add the suffix ".action"? Is it necessary?
And can we config the ".action" as another suffix such as ".go"?
.action is the default suffix added by Struts. To change it from '.action' to '.go'. Use the below in XML to change the suffix.
<struts>
<constant name="struts.action.extension" value="go"/>
<package name="default" namespace="/" extends="struts-default">
<action name="SayStruts2">
<result>pages/printStruts2.jsp</result>
</action>
</package>
</struts>