in struts 2 execute method is not called by default.
I have HelloWorld.java as controller and HelloWorld.jsp this is my struts.xml
<struts>
<package name="example" namespace="/example" extends="struts-default">
<action name="add" class="example.HelloWorld" method="add">
<result name="SUCCESS" type="redirect">HelloWorld</result>
</action>
<action name="HelloWorld"
class="example.HelloWorld">
<result name="input">/example/HelloWorld.jsp</result>
</action>
</package>
package example;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;
import java.util.List;
/**
* <code>Set welcome message.</code>
*/
public class HelloWorld extends ActionSupport {
private static final long serialVersionUID = 9149826260758390091L;
private Contacts Contacts;
private ContactManager linkController;
private List<Contacts> ContactsList;
public HelloWorld() {
linkController = new ContactManager();
}
#Override
public String execute() {
if (null != Contacts) {
linkController.add(getContacts());
}
this.ContactsList = linkController.list();
System.out.println(ContactsList);
System.out.println(ContactsList.size());
return SUCCESS;
}
public String add() {
System.out.println(getContacts());
getContacts().setBirthdate(new Date());
try {
linkController.add(getContacts());
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
public Contacts getContacts() {
return Contacts;
}
public void setContacts(Contacts Contacts) {
this.Contacts = Contacts;
}
public List<Contacts> getContactsList() {
return ContactsList;
}
public void setContactsList(List<Contacts> ContactsList) {
this.ContactsList = ContactsList;
}
}
You have only input result in struts.xml and returning success in execute().
<package name="example" namespace="/example" extends="struts-default">
<action name="add" class="example.HelloWorld" method="add">
<result name="SUCCESS" type="redirect">HelloWorld</result>
</action>
<action name="HelloWorld"
class="example.HelloWorld">
<result name="input">/example/HelloWorld.jsp</result>
<!-- FOLLOWING LINE IS MISSING -->
<result name="SUCCESS">/example/HelloWorld.jsp</result>
</action>
</package>
I Faced same issue and found solution for this.
Your validation.xml should handle the attributes which are in ActionClass only.
For each ActionClass should maintain unique Action-Validation file.
Dont mingle all actions in different J
<package name="example" namespace="/example" extends="struts-default">
<action name="add" class="example.HelloWorld" method="add">
<result name="SUCCESS" type="redirect">HelloWorld</result>
<result name="input" type="redirect">HelloWorld</result>
</action>
<action name="HelloWorld" class="example.HelloWorld">
<result name="input">/example/HelloWorld.jsp</result>
<result name="SUCCESS">/example/HelloWorld.jsp</result>
</action>`
Try this. This may help you.
Related
Within in same action class, struts2 supports multiple action methods.
One sample of struts.xml - How to convert it to annotation ?
<action name="import"
class="com.action.MainAction" method="importFiles">
<result name="success">main.jsp</result>
<result name="error">error.jsp</result>
</action>
<action name="resourceRowAction"
class="com.action.MainAction" method="resourceRowAction">
<result name="success">main.jsp</result>
<result name="error">erro.jsp</result>
</action>
Annotation solution for above Dynamic Method Invocation can be found here :
http://struts.apache.org/release/2.1.x/docs/convention-plugin.html#ConventionPlugin-Actionannotation
In Action:
#Action(value="default")
#Override
public String execute()
{
return SUCCESS;
}
#Action(value="import")
public String importFiles()
{
return SUCCESS;
}
#Action(value="resourceRowAction")
public String resourceRowAction()
{
return SUCCESS;
}
i am calling a struts2 action by passing parameter from a dynamic image url
<img src="<s:url action='ImageAction?imageId=logo.jpg' />"/>
With this my action is calling properly but the parameter imageId=logo.jpg is not passing to my action class.
But if i manully pass parameter from the browser url then, parameter is correctly showing into my java page eg. http://localhost:8080/mypoject/jspHomepage/bookstransaction/secure/ImageAction?imageId=logo.jpg
What could be reason for this?
Please help me.
struts.xml
`
`<package name="Image" extends="struts-default,json-default">
<result-types>
<result-type name="imageResult"
class="v.esoft.actions.changetheme.CustomImageBytesResult" />
</result-types>
<action name="updatethemeimageform" class="v.esoft.actions.changetheme.ThemedetailsEditAction" method="updateThemesImage">
<result name="success" type="json"/>
<result name="input" type="json"/>
</action>
<action name="Display" class="v.esoft.actions.changetheme.DisplayAction">
<result name="success" type="json"/>
</action>
<action name="ImageAction" class="v.esoft.actions.changetheme.ImageAction">
<result name="success" type="imageResult">
</result>
</action>
</package>`
ImageAction.java
public class ImageAction extends ActionSupport implements ServletRequestAware {
byte[] imageInByte = null;
String imageId;
private HttpServletRequest servletRequest;
public String getImageId() {
return imageId;
}
public void setImageId(String imageId) {
this.imageId = imageId;
}
public ImageAction() {
System.out.println("ImageAction");
}
public String execute() {
return SUCCESS;
}
public byte[] getCustomImageInBytes() {
System.out.println("imageId" + imageId);
}
}
Following is untested.
Use param tags to add parameters.
<s:url package="Image" action="ImageAction" var="myUrl">
<s:parm name="imageId" value="'logo.jpg'"/>
</s:url>
<img src="<s:property value="#myUrl"/>"/>
Note: I suspect in the final line myUrl should be sufficient (without the #) but don't remember at the moment.
I have written an interceptor to prevent caching but the pages still cache.
Interceptor:
public class ClearCacheInterceptor implements Interceptor {
public String intercept(ActionInvocation invocation)throws Exception{
String result = invocation.invoke();
ActionContext context = (ActionContext) invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);
HttpServletResponse response=(HttpServletResponse) context.get(StrutsStatics.HTTP_RESPONSE);
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
return result;
}
public void destroy() {}
public void init() {}
}
Struts.xml
<struts>
<constant name="struts.devMode" value="true"/>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="caching" class="com.struts.device.interceptor.ClearCacheInterceptor"/>
<interceptor-stack name="cachingStack">
<interceptor-ref name="caching" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<action name="Login" class="struts.device.example.LogIn">
<interceptor-ref name="cachingStack"/>
<result>example/Add.jsp</result>
<result name="error">example/Login.jsp</result>
</action>
</package>
</struts>
Application works fine; it executes interceptor but it doesn't prevent caching.
I have solved my problem. Thanks to developer tools for helping me to trace out.
A slight sequence change in my code helped me out: as per the Struts 2 interceptor docs the result is rendered before invocation.invoke() returns. Setting the headers before the result is rendered back to the client sets the headers in the returned result.
i.e.,
public String intercept(ActionInvocation invocation)throws Exception{
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
return invocation.invoke();
}
I'm a beginner in Struts2. I am used in PHP, while logging to save authentification in a session variable, which I can destroy after logging out. I wonder how I can do the same process in Struts2 : to set a session variable while logging in and to destroy it while logging out. Thank you a lot.
Update ( An additional solution )
In addition to the useful answers and comments, we can use :
session.remove("session_var_name"); // instead of session.clear();
to remove one exact session variable instead of removing all the session variables. Thank you all.
You can do one of the following
public class MyAction extends ActionSupport implements ServletRequestAware
{
private HttpServletRequest httpServletRequest;
public void setServletRequest(HttpServletRequest request)
{
this.httpServletRequest = request;
}
public String login()
{
httpServletRequest.getSession(false).setAttribute("key", your_session_object);
return SUCCESS;
}
public String logout()
{
httpServletRequest.getSession(false).removeAttribute("key");
return SUCCESS;
}
}
public class MyAction extends ActionSupport implements SessionAware
{
private Map sessionMap;
public void setSession(Map map)
{
this.sessionMap = map;
}
public String login()
{
sessionMap.put(key, your_session_object);
return SUCCESS;
}
public String logout()
{
sessionMap.remove(key);
return SUCCESS;
}
}
The second alternative i.e. implementing SessionAware is preferred since it shields you from Servlet APIs.
You can use Scope Interceptor when you call logout, and with "end" type in your struts xml configuration, Interceptor set null to your session object:
<action name="scopea" class="com.mevipro.test.action.ScopeActionA">
<result name="success" type="dispatcher">/jsp/test.jsp</result>
<interceptor-ref name="basicStack"/>
<interceptor-ref name="scope">
<param name="key">funky</param>
<param name="session">person</param>
<param name="type">start</param>
</interceptor-ref>
</action>
<action name="scopeb" class="com.mevipro.test.action.ScopeActionB">
<result name="success" type="dispatcher">/jsp/test.jsp</result>
<interceptor-ref name="scope">
<param name="key">funky</param>
<param name="session">person</param>
<param name="type">end</param>
</interceptor-ref>
<interceptor-ref name="basicStack"/>
</action>
you must define "start" and "end" the start is when you initialise your object in session and the "end" for destroy your object
For more detail : https://struts.apache.org/docs/scope-interceptor.html
I am working on Struts2 Interceptors .
I have read that Struts2 Interceptors are just like Filters , which execute before the Action class is executed and one more time after processing the result ( Please correct me if i am wrong ) , that is two times
But when i ran the below code , the interceptors are executed only once .
Please correct me if i made any mistake .
Please see my code below :
This is My Struts.xml file
<struts>
<constant name="struts.devMode" value="true" />
<package name="test" extends="struts-default">
<interceptors>
<interceptor name="loginkiran" class="vaannila.MyLoginInterCeptor" />
</interceptors>
<action name="HelloWorld" class="vaannila.HelloWorld" method="kiran">
<interceptor-ref name="loginkiran" />
<result name="SUCCESS">/success.jsp</result>
</action>
</package>
</struts>
This is my Action class
public class HelloWorld
{
public HelloWorld() {
}
public String kiran() {
System.out.println("iNSIDE THE aCTION CLASS");
return "SUCCESS";
}
}
This is my Interceptor class
public class MyLoginInterCeptor implements Interceptor {
#Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("Destroying Interceptor");
}
#Override
public void init() {
}
#Override
public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = (HttpServletRequest) ActionContext
.getContext().get(ServletActionContext.HTTP_REQUEST);
System.out.println("iNSIDE THE iNTERCEPTOR");
return invocation.invoke();
}
}
This is my JSP File :
<html>
<body>
<%
System.out.println("iNSIde THE jsp");
%>
</body>
</html>
The Output for the above code is this :
iNSIDE THE iNTERCEPTOR
iNSIDE THE aCTION CLASS
iNSIde THE jsp
Interceptors are not executed twice (nor are filters): interceptors (and filters) wrap the action (or servlet/etc.)
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("Before action invocation...");
return invocation.invoke();
System.out.println("After action invocation...");
}