I'm trying to validate a form using the Struts2 validator tool but it doesn't seem to work since, apparently, the xml validator is never acknowledged.
Here is my code:
struts.xml:
<interceptors>
<interceptor name="login_interceptor" class="org.apache.struts.gesprod.produccion.BLLogin">
</interceptor>
<interceptor-stack name="login_stack">
<interceptor-ref name="login_interceptor" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="login_stack"></default-interceptor-ref>
<global-results>
<result name="input">/errores/error_input.jsp</result>
<result name="error_sql">/errores/error_sql.jsp</result>
<result name="no_logged">/login.jsp</result>
</global-results>
...
<action name="login" class="org.apache.struts.gesprod.produccion.BLUsuario" method="loginUsuario">
<result name="success" type="redirect">/welcome.jsp</result>
<result name="incorrecto_login">/login.jsp</result>
<result name="input">/login.jsp</result>
</action>
login.jsp:
<div id="login">
<s:fielderror />
<s:form id="login_form" action="login" validate="true">
<s:hidden name="intento_log" value="true" />
<s:textfield name="usuario.username_usuario" label="Usuario"/>
<s:password name="usuario.password_usuario" label="Password"/>
<s:submit value="Ingresar"/>
</s:form>
</div>
And the xml validator, placed in the same package as the Action class.
BLUsuario-login-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="usuario.username_usuario">
<field-validator type="requiredstring">
<message>Show error!</message>
</field-validator>
</field>
</validators>
Can somebody help and notice if there's something wrong with my code?
I think that the problem is in the name of the xml validator. You have to rename the validator with login-validation.xml. The name that you can put to your xml validator files are:
Validation rules can be specified:
Per Action class: in a file named ActionName-validation.xml
Per Action alias: in a file named ActionName-alias-validation.xml
Inheritance hierarchy and interfaces implemented by Action class: XWork searches up the inheritance tree of the action to find default validations for parent classes of the Action and interfaces implemented
You can see more here:
http://struts.apache.org/2.0.12/docs/validation.html#Validation-DefiningValidationRules
P.D: You said that "the "input" result is never returned even if the fields are wrong". The input result is returned if there are any field error (unless you specify other thing).
Related
I have a namespace in struts.xml
<package name="mobile" namespace="/mobile" extends="mainApp">
<action name="abc" class="x.y.Abc"
method="abc">
<result name="input">/blank.html</result>
<result name="success">/blank.html</result>
</action>
</package>
I want to map localhost/myApp/mobile/ with the action abc
I don't mind localhost/myApp/mobile/* getting mapped with the action abc
is there any way to meet this requirement?
I want to fire an action on localhost:8080/appname/namespace/ i.e. namespace slash
After slash should be action name and if it's empty you should configure empty action name.
<package name="mobile" namespace="/mobile" extends="mainApp">
<action name="" class="x.y.Abc"
method="abc">
<result name="input">/blank.html</result>
<result name="success">/blank.html</result>
</action>
</package>
try <default-action-ref/>:
<package name="mobile" namespace="/mobile" extends="mainApp">
<default-action-ref name="abc"/> <!-- I added this -->
<action name="abc" class="x.y.Abc"
method="abc">
<result name="input">/blank.html</result>
<result name="success">/blank.html</result>
</action>
</package>
<interceptor-stack name="DefaultTEST">
<interceptor-ref name="exception" />
<!-- some more interceptors go in here -->
<interceptor-ref name="debugging" />
</interceptor-stack>
<default-interceptor-ref name="DefaultTEST" />
<action name="welcome">
<result type="tiles">WELCOME_PAGE</result>
</action>
<action name="">
<result ...>...</result>
</action>
... <!-- more actions -->
So my question is how to override the default interceptor stack so that for welcome action some other interceptors (or interceptor stack) can be loaded while the default one is not.
You can override the interceptors config if you reference an interceptor or interceptors stack in the action config explicitly.
<action name="welcome">
<interceptor-ref name="defaultStack" />
<result type="tiles">WELCOME_PAGE</result>
</action>
Only defaultStack will be executed for welcome action. Other actions that don't override the interceptors config in this package will use DefaultTEST because it's configured as default.
I have been attempting to get the tokenSession interceptor to work (Struts 2.0.14) but always get the warnings:
2013-03-13 08:32:09,395 [17] DEBUG Intercepting invocation to check for valid transaction token. | org.apache.struts2.interceptor.TokenSessionStoreInterceptor.doIntercept(128)
2013-03-13 08:32:09,395 [17] WARN Could not find token name in params. | org.apache.struts2.util.TokenHelper.getTokenName(124)
2013-03-13 08:32:09,396 [17] DEBUG no token name found -> Invalid token | org.apache.struts2.util.TokenHelper.validToken(154)
2013-03-13 08:32:09,397 [17] WARN Could not find token name in params. | org.apache.struts2.util.TokenHelper.getTokenName(124)
2013-03-13 08:32:09,397 [17] WARN Could not find token mapped to token name null | org.apache.struts2.util.TokenHelper.getToken(105)
2013-03-13 08:32:09,398 [17] DEBUG Forwarding to location /WEB-INF/view/support/TokenError.jsp | org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(113)
The struts.xml has the following interceptor configuration:
<package name="survey" extends="struts-default">
<result-types>
<result-type name="csv"
class="webapp.CsvResultType"/>
</result-types>
<interceptors>
<interceptor name="log"
class="struts.LoggingInterceptor"/>
<interceptor name="formAuthentication"
class="security.FormAuthenticationInterceptor"/>
<interceptor-stack name="default">
<interceptor-ref name="log"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="formAuthentication"/>
<!--interceptor-ref name="chain"/>-->
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="params"/>
</interceptor-stack>
<interceptor-stack name="defaultTokenStack">
<interceptor-ref name="tokenSession"/>
<interceptor-ref name="default"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="default"/>
<!-- -->
<global-results>
<result name="blank">/WEB-INF/view/support/Blank.jsp</result>
<result name="error">/WEB-INF/view/support/Error.jsp</result>
<result name="insufficientPrivileges">/WEB-INF/view/support/InsufficientPrivileges.jsp</result>
<!--result name="file" type="file"></result-->
</global-results>
</package>
With the action definitions:
<package name="respondent" namespace="/respondent" extends="survey">
<action name="*" class="controller.respondent.{1}Action">
<interceptor-ref name="defaultTokenStack"/>
<result name="list">/WEB-INF/view/respondent/{1}List.jsp</result>
<result name="edit">/WEB-INF/view/respondent/{1}Edit.jsp</result>
<result name="view">/WEB-INF/view/respondent/{1}View.jsp</result>
<result name="success">/WEB-INF/view/respondent/{1}.jsp</result>
<result name="invalid.token">/WEB-INF/view/support/TokenError.jsp</result>
</action>
</package>
The jsp has the token tag:
<s:form action="FunctionSummary.action" method="post">
<s:token/>
<table class="buttons">
<tr>
<s:if test="surveyStarted">
<td><s:submit value="Resume Survey"/></td>
</s:if>
<s:else>
<td><s:submit value="Start Survey"/></td>
</s:else>
</tr>
</table>
</s:form>
Any access to this page always results in redirection to the invalid.token result and the warnings above.
I have validated that without the interceptor configured, the page source does have the token but I cannot get the sessionToken interceptor to see it.
Any help would be most appreciated...
Thanks
Try to put your <s:token/> tag into your <table> tags.
I got the same problem just like you. And after I put <s:token/> into <table> tag problem solved.
<s:form action="" id = "" theme="simple" method = "post">
<table id = "" border="1" width="200">
<s:token/> <!-- In the table tag -->
</table>
</s:form>
In struts.xml:
<package namespace="/" extends="struts-default" ...>
<action name="home" ... >
</action>
</package>
Accessing the action will be /home. What is it that the action can also be accessed in /user/home? How to restrict it?
Thanks
im doing a modification on an existing app. my problem is even tho the validation fails for the form submit, its still executing the execute method.
my struts file
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- <include file="com/paritysys/util/struts.xml" /> -->
<constant name="struts.url.includeParams" value="none" />
<constant name="struts.action.extension" value="html,action" />
<package name="public" extends="struts-default">
<interceptors>
<interceptor name="websiteOnline"
class="parity.action.website.OnlineInterceptor" />
<interceptor name="websiteLogin"
class="parity.action.website.LoginInterceptor" />
<interceptor-stack name="appStack">
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<!-- <interceptor-ref name="paritySessionStack"/> -->
<interceptor-ref name="websiteOnline" />
<interceptor-ref name="websiteLogin" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="appStack" />
<global-results>
<result name="login" type="redirectAction">
<param name="actionName">index</param>
</result>
<result name="exception" type="freemarker">/public/error.html.ftl</result>
<result name="error" type="freemarker">/public/error.html.ftl</result>
<result type="freemarker" name="maintenance">/public/maintenance.html
</result>
<result type="freemarker" name="pre-offline">/public/pre-offline.html
</result>
<result type="freemarker" name="post-offline">/public/post-offline.html
</result>
</global-results>
<action name="index" class="parity.action.website.LoginAction">
<result type="freemarker" name="success">/public/index.html.ftl</result>
</action>
<action name="login" class="parity.action.website.SubmitLoginAction">
<result type="freemarker" name="success">/public/questionnaire.html.ftl
</result>
<result type="freemarker" name="input">/public/index.html.ftl</result>
</action>
<action name="submit" class="parity.action.website.SubmitQuestionnaireAction">
<result type="freemarker" name="success">/public/thanks.html.ftl
</result>
<result type="freemarker" name="input">/public/questionnaire.html.ftl
</result>
</action>
<action name="whereIsMyId" class="parity.action.website.LoginAction">
<result type="freemarker" name="success">/public/whereIsMyId.html.ftl
</result>
</action>
<action name="loadCollegeFinder" class="parity.action.website.LoadCollegeFinderAction">
<result type="freemarker" name="success">/public/college_finder.html.ftl
</result>
</action>
<action name="findCollege" class="parity.action.website.FindCollegeAction">
<result type="freemarker" name="success">/public/college_finder.html.ftl
</result>
<result type="freemarker" name="input">/public/college_finder.html.ftl
</result>
</action>
</package>
my action class code
public void validate() {
logger.debug("validate fired");
Bla bla bla
addFieldError("username","error");
if (hasFieldErrors()) {
logger.debug("Field errors is true");
}
}
public String execute() throws Exception {
logger.debug("execute firing");
return result;
}
any ideas why this would happen? for some reason even tho the login.action is failing, its still sending down the success return and moving forward.
You interceptor stack doesn't include the "workflow" interceptor stack, which is what determines what to do on a validation failure.
For that matter, it doesn't include the "params" interceptor, which is how parameters are set on the action, so it will never work anyway. You can't just arbitrarily remove interceptors--it's where S2 gets the bulk of its functionality. See the interceptor docs.
Also, you can set a default result type--you may want to do that if most everything is a FreeMarker result rather than type it over and over.