%{control.current + #displayRows}
is ultimately the statement I need executed. I have it in an s:if tag and I use test to see if this value lies within a certain range.
Ultimately, I get string concatenation and not addition because both side of the addition are not regarded as numeric types by OGNL. Doing a little tinkering, I see that
%{control.current + control.current}
does result in numerical addition, so indeed the displayRows value which was set in an s:set tag earlier is regarded an the non-numeric value. Here is my s:set tag:
<s:set name="displayRows" value="%{#application['app_settings'].settings['MAX ACCESS FIELD TITLES ROWS']}" />
The settings represents a Map in Java. Whereas the key is always a String ... well ... the value is not always an Integer because assorted application settings are being stored. So the best we can do for value type is Object. And I believe this is the problem. OGNL does not regard this as something which can be converted automatically to a numeric type.
I have gone through the langauge guide at http://incubator.apache.org/ognl/language-guide.html which explains some of these concepts, but I do not see a way to tell OGNL "Yes this displayRows which contains the value of 15 REALLY is an integer". Is there a way to make this happen. I need to be able to do addition on the fly so I cannot create additional attributes in Javaland to assist me. I have looked at the OGNL, the s:set tag and the Java level and I do not see a proper place where I can make this happen.
Struts thinks #displayRows is a String when we need it as an Integer (I'll assume integer you'll be able to apply the following to any built in type).
First turn on static method access in struts.xml.
For reference here is my struts.xml, the last constant tag is what you'll need to add to yours:
<?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>
<constant name="struts.devMode" value="true" />
<constant name="struts.ui.theme" value="simple" />
<constant name="struts.date.format" value="0,date,dd.MM.yyyy"/>
<constant name="format.date" value="{0,date,dd.MM.yyyy}"/>
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
</struts>
Then in your jsp you'll do something like:
<s:property value='#java.lang.Integer#valueOf("123") + #java.lang.Integer#valueOf("123")' />
Which displays: 246
It would probably be better to do the conversion in the set tag:
<s:set name="displayRows" value="#java.lang.Integer#valueOf(#application['app_settings'].settings['MAX ACCESS FIELD TITLES ROWS'])" />
then,
<s:property value="control.current + #displayRows"/>
will behave as expected.
Related
In struts2, I took advantage of built-in OGNL in struts2, naming my inputs like <input name='bag["item"].property'>
Which went to getters/setters getBag().get("item").setProperty(value)
I've upgraded to struts 2.2.1, and suddently those no longer work: the getter never gets called.
The internet is utterly silent on using OGNL in parameters, as if nobody ever made complex forms.
How do I get my map-parameters back?
It turns out that they hardened restrictions on parameter names to boost security.
So I had to add to my struts.xml:
<interceptor-stack name="defaultStack">
<interceptor-ref name="params">
<!-- For maps to work -->
<param name="acceptParamNames">
[a-zA-Z0-9\.\]\[\(\)_'\s"/]+
</param>
</interceptor-ref>
</interceptor-stack>
(I had "s and /s in my parameter names)
File upload ceased working after that (interceptor stacks are madness), so I had to add it explicity either.
Update: These days I strongly suggest using JSON to pass complex structures instead of rich OGNL forms. Of course you would need some JS.
In VSTF 2012 I have a custom template. I have a field which uses the WHEN field element to determine if it is required based on the input from a different field - in this example the Ops Approver field is required when the Ops Required field = Operations.
<FieldDefinition name="Operations Approver" refname="Microsoft.VSTS.Common.OperationsApprover" type="String" reportable="dimension">
<VALIDUSER />
<WHEN field="Microsoft.VSTS.Common.OpsRequired" value="Operations">
<REQUIRED />
</WHEN>
</FieldDefinition>
This works perfectly. I now need to make this field required based on the WHEN from 2 different fields e.g. When Ops Required = Operations and Priority = 2
I have tried adding another WHEN element but they act as an OR function rather than an AND function.
I have searched on the web, on this site in MSDN and found nothing. What am I missing? Is this even possible?
Any help greatly appreciated.
In Struts2 tutorial for s:select tag I've seen:
<s:select label="Pets"
name="petIds"
list="petDao.pets"
listKey="id"
listValue="name"
multiple="true"
size="3"
required="true"
value="%{petDao.pets.{id}}"
/> ^ ^
and my question: why value="%{petDao.pets.{id}}"? why not simply value="%{petDao.pets.id}"? what do those trailing curly braces mean?
This is an OGNL list projection to get all the id values as a list from petDao.pets, meaning all values in this <s:select> will be pre-selected.
It isn't necessary; I suspect it was the result of an error in the tag's source file.
It works with it, but isn't needed, will fail IDE validation (if the IDE supports S2 and/or OGNL, e.g., IntelliJ), and I've made a note to update.
The principal reason is because %{} syntax is used to force OGNL evaluation where Struts would otherwise be treating the value as a String literal.
For example,
<s:property value="name" />
will look for a name property in the value stack i.e. is a value retrieved by calling getName().
If you wanted to force it to use literal value "name", you will need to use the %{} syntax -
<s:property value="%{'name'}" />
Source:
http://www.coderanch.com/t/420711/Struts/Struts
I'm new to Struts 2 and facing this problem in keeping the layout of my page:
<s:form action="abc.action"><br>
<s:textfield key="name" label="Name" /><%--here I need to display errormessage for `name`--%>
<br>
<s:textfield key="email" label="Email" /><%--here I need to display errormessage for `email`--%>
<br>
<s:submit>
</s:form>
I'm using xml-validator for my action class, this works fine. but the validation-error messages appear over the fieldname and text-box. but i want it to come afterwards respective text-box (inside another html-container). Kindly advise.
If you're used to writing HTML, switch to the simple theme.
In struts.xml is probably the best place:
<struts>
<constant name="struts.ui.theme" value="simple" />
</struts>
Then just use the fielderror tag to put the error for the field where you want it.
It's a good to be familiar with the Struts2 tags: http://struts.apache.org/release/2.3.x/docs/tag-reference.html
That is the default according to Struts2 default templating. To change it, see http://www.mkyong.com/struts2/working-with-struts-2-theme-template/
You Can also Use Struts2 validation Framework
Validation framework comes with set of useful routines to handle form validation automatically and it can handle both server side as well as client side form validation. If certain validation is not present, you can create your own validation logic by implementing java interface.
com.opensymphony.xwork2.Validator
Validator uses XML configuration files to determine which validation routines should be installed and how they should be applied for a given application. validators.xml file contains all common validators declaration. If validators.xml file is not present in classpath, a default validation file is loaded from path
com/opensymphony/xwork2/validator/validators/default.xml
Validators Scope
There are two types of Validators in Struts2 Validation Framework.
Field Validators
Non-field validators
Field validators, as the name indicate, act on single fields accessible through an action. A validator, in contrast, is more generic and can do validations in the full action context, involving more than one field (or even no field at all) in validation rule. Most validations can be defined on per field basis. This should be preferred over non-field validation wherever possible, as field validator messages are bound to the related field and will be presented next to the corresponding input element in the respecting view.
<validators>
<field name="bar">
<field-validator type="required">
<message>You must enter a value for bar.</message>
</field-validator>
</field>
</validators>
Non-field validators only add action level messages. Non-field validators are mostly domain specific and therefore offer custom implementations. The most important standard non-field validator provided by XWork is ExpressionValidator.
<validators>
<validator type="expression">
<param name="expression">foo lt bar</param>
<message>Foo must be greater than Bar.</message>
</validator>
</validators>
For whole detail example visit this link link to struts2 validation
I need to supply the key dynamically from the action to the text tag
<s:text name="<%=talkToUsInfo.messageKey%>" />
but the name attribute on text tag is declared as false ( not sure why ? )
How do i get something like this working without changing the tld in the jar file ?
Take a look at OGNL
It might look like this
<s:text name="%{talkToUsInfo.messageKey}" />
Struts documentation says:
Instead, you should use the getText() method that you inherit when your Action extends XWork's ActionSupport:
<s:textfield name="lastName" label="getText('person.lastName')" />
So I used e.g.
<s:property value="getText('status' + #someObject.currentStatus)" />
instead of "s:text" and it worked.
I prefer to use OGNL and s:text and do not make a call to getText manually.
You usually define a fixed prefix while add the dynamic part to it, so some thing like this could be used:
<s:text name="%{'student.types.'+currencyType}" />
The only time which I used getText inside the s:property was something like this (which needs some if/else if you wanted to use s:text ):
<s:property value="shouldCancelIt.equals(\"0\") ?
getText('label.yes'):getText('label.no')" />