Struts2/Spring - execute is not being called even after passing validate - java

I'm having trouble with my setup, my login has passed the validation but execute function is not being called
LoginAction.java:
#Override
public String execute() throws Exception {
System.out.println("5");
String username = blogUser.getUsername();
String password = blogUser.getPassword();
blogUser = blogUserService.getUserByLogin(username, password);
System.out.println("6");
sessionMap.put(Constants.SESSION_USERNAME, blogUser.getUsername());
System.out.println("7");
sessionMap.put(Constants.SESSION_USERID, blogUser.getUserId());
System.out.println("return:success");
return SUCCESS;
}
#Override
public void validate() {
System.out.println("1");
String username = blogUser.getUsername();
String password = blogUser.getPassword();
System.out.println("username:"+username + ", password:"+password);
if (username == null & password == null) {
System.out.println("22");
addFieldError("blogUser.username","");
} else if (username == null || password == null) {
System.out.println("2");
addFieldError("blogUser.username","Invalid Login");
} else if (!blogUserService.checkLogin(username, password)) {
System.out.println("3");
addFieldError("blogUser.username","Invalid Login");
}
System.out.println("4");
}
public String postLogin() throws Exception {
System.out.println("77");
return LOGIN;
}
struts.xml:
<action name="login" class="loginActionBean" >
<result name="input" type="tiles">/login.tiles</result>
<result name="none" type="tiles">/login.tiles</result>
<result name="login" type="tiles">/login.tiles</result>
<result name="success" type="redirectAction">postPreviewAction</result>
<result name="error" type="tiles">/login.tiles</result>
</action>
<action name="doLogin" class="loginActionBean" method="postLogin">
<result name="login" type="tiles">/login.tiles</result>
<result name="input" type="redirectAction">login</result>
</action>
login.jsp:
<%# page contentType="text/html; charset=UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<div>
<h2>Users Login</h2>
<s:form action="login" method="post">
<s:textfield label="Username" name="blogUser.username" />
<s:password label="Password" name="blogUser.password" />
<s:submit value="Login" />
</s:form>
</div>
I can see only "4" being printed (meaning it passed the validation) but that's it, it doesn't go to "5"
EDIT:
added tiles.xml snippet
<definition name="/login.tiles" extends="baseLayout">
<put-attribute name="body" value="/login.jsp" />
</definition>

From the Struts2 Spring Plugin documentation:
Normally, in struts.xml you specify the class for each Action. When using the default SpringObjectFactory, the framework will ask Spring to create the Action and wire up dependencies as specified by the default auto-wire behavior.
Meaning you don't need to create Spring beans out of your actions.
However, sometimes you might want the bean to be completely managed by Spring. This is useful, for example, if you wish to apply more complex AOP or Spring-enabled technologies, such as Acegi, to your beans. To do this, all you have to do is configure the bean in your Spring applicationContext.xml and then change the class attribute from your`Action in the struts.xml to use the bean name defined in Spring instead of the class name.
Struts2 itself creates new instance of action for each request, so actions are not singletons. If you create a Spring bean out of action then give it a proper scope (e.g. scope="prototype"), because:
By default, a bean will be a singleton, unless the bean has a parent bean definition in which case it will inherit the parent's scope.
The loginActionBean example declaration:
<bean id="loginActionBean" class="some.package.LoginActionBean" scope="prototype" />

The action named doLogin (should have the proper name like showLogin) is the action that shows the login page. It shouldn't be validated because it will always fail. You have to remove this from the action config
<result name="input" type="redirectAction">login</result>
And the action method should be excluded from validation. You can configure validation interceptor to exclude this method but another way to do it just put #SkipValidation annotation on the method.
#SkipValidation
public String showLogin() throws Exception {
System.out.println("77");
return LOGIN;
}
The action named login has a few redundant results that could be removed
<result name="none" type="tiles">/login.tiles</result>
<result name="login" type="tiles">/login.tiles</result>
<result name="error" type="tiles">/login.tiles</result>
Note: that validation by default is called on every action method from the action class unless it excluded from validation or doesn't have validation interceptor configured.
The final configuration:
<action name="login" class="loginActionBean" >
<result name="input" type="tiles">/login.tiles</result>
<result type="redirectAction">postPreviewAction</result>
</action>
<action name="showLogin" class="loginActionBean" method="showLogin">
<result name="login" type="tiles">/login.tiles</result>
</action>

Related

How to invoke Action class creation in Struts2

I have login and calculation JSP pages. Calculation page contains list, which needs initialized action object. Here is login.xml
<struts>
<package name="default" extends="struts-default">
<action name="*Action" class="com.task.action.{1}Action">
<result name="success">/calculation.jsp</result>
<result name="input">/login.jsp</result>
</action>
</package>
</struts>
calculation.jsp:
<s:form action="CalculationAction">
<s:select label="Types"
list="calculationTypes"
name="calculationType" value="getDefaultCalculationType"/>
<s:submit />
</s:form>
After executing LoginAction class, i got "success" and move to calculation.jsp. Problem is CalculationAction is not created, and list in jsp can't initialize. If i call http://localhost:8082/Task/CalculationAction.action , jsp page is creating correctly.
I also tried to make references in login page and it works too.
<s:url id="calculationUrl" action="CalculationAction"> </s:url>
<div class="tab-wrapper">
Login Page
<s:a href="%{calculationUrl}">Calculation Page</s:a>
</div>
How to make the program working correctly after executing LoginAction?
Add one more result for LogingAction to redirect to CalculationAction, and return this result instead of "success" in the LogingAction.
<action name="*Action" class="com.task.action.{1}Action">
<result name="success">/calculation.jsp</result>
<result name="input">/login.jsp</result>
<result name="successfulLogin" type="redirectAction">CalculationAction</result>
</action>
The CalculationAction on "success" should return a calculation.jsp and calculation action will be in the value stack, so you can get calculationTypes initialized when the action was executed.

How to submit multipart/form-data with File and Text Fields using Struts2?

This registration form contains a file upload and textfields. Using Struts2 how do we submit the form parameters and also upload the file?
1. register.jsp:
<s:form action = "Register" enctype="multipart/form-data" method="post">
<s:textfield name="uname" label = "User Name"/>
<s:password name ="password" label = "Password"/>
<s:file name="fileUpload" label="Select a File to upload" size="40" />
<s:submit/>
</s:form>
2. RegisterAction:
package user.action;
import java.io.File;
public class RegisterAction
{
private String uname,password;
private File fileUpload;
private String fileUploadContentType;
private String fileUploadFileName;
//getter setters
public String execute() throws Exception
{
return "success";
}
}
3. struts.xml:
</action>
<action name="Register" class="user.action.RegisterAction">
<interceptor-ref name="fileUpload">
<param name="allowedTypes">text/plain</param>
<param name="maximumSize">10240</param>
</interceptor-ref>
<result name="success">registered.jsp</result>
</action>
4. registered.jsp:
User Name : <s:property value="uname"/>
File Name : <s:property value="fileUploadFileName"/>
Content Type : <s:property value="fileUploadContentType"/>
File : <s:property value="fileUpload"/>
User Name <s:property value="uname"/> is not giving any output in
registered.jsp. Should we use Apache file upload to parse the request to get the textfields value?
No, you shouldn't. The Apache file upload is part of Struts2. The fileUpload interceptor is already included to the defaultStack, so you don't need to reference it in the action configuration. If you want to override parameters of this interceptor then
<action name="Register" class="user.action.RegisterAction">
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedTypes">text/plain</param>
<param name="fileUpload.maximumSize">10240</param>
</interceptor-ref>
<result name="success">registered.jsp</result>
</action>
As long as the required libraries are added to your project you will be able to take advantage of of the Struts 2 fileUpload capability.
check you setter methods local variable and in registered.jsp try this
change
User Name <s:property value="uname"/>
with
<s:label name="xyz" value="%{uname}" />
Thanks Friends for looking into the problem.
I have got the answer. Actually I had done a mistake while adding the interceptor.
I had missed
<interceptor-ref name="defaultStack"></interceptor-ref>
so my new action after change should be
<action name="Register" class="user.action.RegisterAction">
<interceptor-ref name="fileUpload">
<param name="allowedTypes">text/plain</param>
<param name="maximumSize">10240</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success">registered.jsp</result>
</action>
Mr Roman is correct that we should add the file upload interceptor only if we need to override. If we don't still it will upload.

Error in Form Action attribute struts2

My login.jsp is in the web folder.
And action for this is specified as :
struts.xml
<package name="admin" extends="struts-default" namespace="/secure">
<action class="actions.LoginAction" name="authenticateUser">
<result name="success" type="redirect">index</result>
<result name="input">/login.jsp</result>
<result name="error">/login.jsp</result>
</action>
</package>
login.jsp
<s:form action="secure/authenticateUser" method="post">
</s:form>
========================
At first request it works.
but if validate() method of action returns errors then it creates url as:
"secure/secure/authenticateUser" for the Form action attribute.
I also tried <s:url> tag but still same problem can anybody help me.
or may provide alternate solution for this.
Your action attribute on the form tag possibly has a wrong name. Use
<s:form namespace="/secure" action="authenticateUser" method="post">

How to detect submit button clicked in multiple submit buttons scenario in single Action class? [duplicate]

This question already has an answer here:
Multiple submit buttons in Struts 2 form tag
(1 answer)
Closed 2 years ago.
I have a form in a jsp. There are two submit buttons: "Search" and "Add New" button.
<s:form name="searchForm" action="employeeAction" method="post">
<s:textfield name="id" label="Employee ID"/>
<s:textfield name="name" label="Employee Name"/>
<s:submit value="Search"/>
<s:submit value="Add New"/>
</s:form>
In 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.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<default-action-ref name="index" />
<global-results>
<result name="error">/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error"/>
</global-exception-mappings>
</package>
<package name="example" namespace="/example" extends="default">
<action name="employeeAction" class="example.EmployeeAction">
<result name="search">/example/search.jsp</result>
<result name="add" type="redirect">/example/add.jsp</result>
</action>
</package>
</struts>
In Struts Action class, we know that there is only one method that processing http request, that is execute() method.
In my expected case, when I clicked Search button, it will perform searching data and render data to /example/search.jsp, when I clicked Add New button, it will perform redirecting page to /example/add.jsp. However, both buttons when clicked will go into execute() method. So I need to know how to detect which button clicked in the execute() method.
The scenario looks like this
public class EmployeeAction extends ActionSupport {
public String execute() throws Exception {
//PSEUDOCODE
//IF (submitButton is searchButton)
// return doSearch();
//ELSE IF (submitButton is addNewButton)
// return doAddNew();
return SUCCESS;
}
public String doSearch() throws Exception {
//perform search logic here
return "search";
}
public String doAddNew() throws Exception {
return "add";
}
}
You can define two actions in struts.xml file and use action attribute of <s:submit> tag in order to submit to different actions http://struts.apache.org/docs/submit.html.
In JSP:
<s:submit value="Search" action="searchEmployeeAction"/>
<s:submit value="Add New" action="addEmployeeAction"/>
In struts.xml:
<action name="addEmployeeAction" method="add" class="example.EmployeeAction">
<result>/example/add.jsp</result>
</action>
<action name="searchEmployeeAction" method="search" class="example.EmployeeAction">
<result>/example/search.jsp</result>
</action>
And in your action create two public String methods add and search.
Read about Multiple Submit Buttons http://struts.apache.org/docs/multiple-submit-buttons.html.
Update
Starting from Struts2 version 2.3.15.3 you need to set struts.mapper.action.prefix.enabled constant to true in order to enable support for action: prefix.
Put that in your struts.xml file:
<constant name="struts.mapper.action.prefix.enabled" value="true" />
In your model layer, define a String property named 'button'. Now, for both your submit buttons, specify name or property attribute as 'button'. So, in your execute() method, in property 'button', you will get the corresponding value.

Struts2 submit button method call doesn't fire

I am having problems with the below code, can anyone explain why the method may not be being fired on the jobListAction? 'Setup' is being called twice upon submission of the form. In short, I can't seem to get the struts button to call multiple methods. Any pointers / things to check?
public class JobListAction {
public String execute() {
System.out.println("setup");
}
public String deactivate() {
System.out.println("called");
}
public String callonme()
{
}
}
JSP:
<s:form id="recordsListForm" method="post" action="jobList">
<s:submit type="button" action="deactivate" value="Deactivate Selected Jobs" method="deactivate" />
<s:submit type="button" action="callonme" value="CallonMe" method="callonme" />
</s:form>
Struts.xml
<!-- Job List -->
<action name="jobList" class="JobListAction">
<result name="input">/jsp/admin/jobList.jsp</result>
<result name="success">/jsp/admin/jobList.jsp</result>
</action>
<!-- Job List - Deactivate Job -->
<action name="deactivate" class="JobListAction" method="deactivate">
<result name="input">/jsp/admin/jobList.jsp</result>
<result name="success">/jsp/admin/jobList.jsp</result>
</action>
<action name="callonme" class="JobListAction" method="callonme">
<result name="input">/jsp/admin/jobList.jsp</result>
<result name="success">/jsp/admin/jobList.jsp</result>
</action>
I guess in struts 2 u need to tell the method name in Struts.xml file, try that out, I hope it works...
<action name="jobList" class="JobListAction" method = "deactivate">
<result name="input">/jsp/admin/jobList.jsp</result>
<result name="success">/jsp/admin/jobList.jsp</result>
</action>
If you want to have a single action declaration that can call multiple methods in the same action class, look into using wilcard mappings:
View
<s:form id="recordsListForm" method="post" action="jobList">
<s:submit type="button" action="jobList_deactivate" value="Deactivate Jobs" />
<s:submit type="button" action="jobList_callonme" value="CallonMe" />
</s:form>
struts.xml
<!-- Job List -->
<action name="jobList_*" method="{1}" class="JobListAction">
<result name="input">/jsp/admin/jobList.jsp</result>
<result name="success">/jsp/admin/jobList.jsp</result>
</action>
The above mapping will match any action that starts with jobList_ and then use the rest of the match as the method to call in the JobListAction class.
Works fine for me; what version? Is dynamic method invocation enabled (it is by default)?
What do you mean by "call multiple methods?" You can only call a single method per-request.
My stdout:
setup // On initial form display
called // Clicking submit
Cut-and-pasted your code (more or less) verbatim.

Categories