How do I convert a JSP variable to a Struts2 variable? - java

How do I convert a JSP variable to a Struts2 variable?
I've tried the following:
<%=scoredDocument%>
<s:push value="scoredDocument"/>
<s:push value="#scoredDocument"/>
<s:push value="%{scoredDocument}"/>
<s:push value="${scoredDocument}"/>
<s:push value="#page.scoredDocument"/>
<s:push value="%{#page.scoredDocument}"/>
<display:column title="Study Code" sortable="true">
<s:property value="id"/>
The most frequent error is
Caused by: tag 'push', field 'value': You must specify a value to push on the stack. Example: person - [unknown location]

<s:push> must enclose the <s:property> tag. Also
<s:push value="#attr.scoredDocument">
<display:column title="Study Code" sortable="true">
<s:property value="id"/>
</display:column>
</s:push>
#attr? WTF Struts? It's not even documented! https://struts.apache.org/release/2.0.x/docs/jsp.html

The push tag requires the value attribute and it has to be initialized, otherwise it shows the JSP error. Unlike other tags where the value could be preinitialized with empty string, the JSP doesn't complain.
The OGNL expression is evaluated in this attribute, like in many other attributes of Struts tags, and if can't resolve the value it returns null. This value is unacceptable for the push tag and it throws exception. The error mislead to make a different tries to access the scriptlet variable value via the OGNL expression, unfortunately none of that methods worked.
Scriptlet expressions has a one pitfall when used with the Struts tags that you can use only in the body of the tag and it's converted to string. Like in this example
<s:set var="scoredDocument"><%=scoredDocument%></s:set>
you can't do the same with the push tag. After that you can use the stringified version of #scoredDocument in OGNL expressions.

Related

Assign Thymeleaf dialect expression return value to Thymeleaf variable in th:with

I'm desperately trying to assign a Thymeleaf dialect expression return value to Thymeleaf variable in the th:with attribute.
I want to achieve something like:
<th:block th:with="foo=${#lists.contains(modelList, modelVariable)}" />
Note: I'm completely sure that my #lists.contains expression works since I've printed the return value in an h1 tag and returns true as text:
<h1 th:text="${#lists.contains(modelList, modelVariable)}"></h1>
So far I've tried the following syntaxes, all of them giving me a parsing error in some way or another...
Without the external ${}:
<th:block th:with="foo=#lists.contains(modelList, modelVariable)" />
With preprocessing:
<th:block th:with="foo=${__#lists.contains(modelList, modelVariable)__}" />
With preprocessing and wrapping it in ${}:
<th:block th:with="foo=${__${#lists.contains(modelList, modelVariable)}__}" />
Why any of these expressions work?
Am I doing something wrong or is this a bug/impossibility of Thymeleaf th:with expression?
Thanks.
There is nothing wrong with the th:with expression itself. However, variables created using th:with only apply to children tags. Your th:block is immediately closed, therefore foo is immediately out of scope and nothing can access it. For example, this would work:
<th:block th:with="foo=${#lists.contains(modelList, modelVariable)}">
<div th:text="${foo}" />
</th:block>
But this doesn't:
<th:block th:with="foo=${#lists.contains(modelList, modelVariable)}" />
<div th:text="${foo}" />
There is no way to define a global variable like that (except putting in on the <html /> tag I suppose).

Struts2 - OGNL parameterized name

I have a generic jsp which is in charge of printing some values, the values depends on a parameter.
For example, I have an object car with and attribute color and a object house with the same attribute, I want to use the same jsp receiveng the name of the object as a parameter.
<jsp:include page="/jsp/prv/generic/PaintColor.jsp" >
<jsp:param name="element" value="car" />
</jsp:include>
So, I want to print the value of car color. I try to do it like this:
<s:set var="propertyName">${param.element}.color<s:set/>
<s:property value="%{#attr.propertyName}" />
It doesnt work, but if I do
<s:textfield name="%{#attr.propertyName}"/>
it works perfect.
How can I use the parametrized name in avalue?
I finally solve it accesing the value from a java scriptlet

Append a query string with action in Struts 2

I am appending the parameters with action but I am getting an exception of on my Struts 2 page.
PWC6212: equal symbol expected
Below is my action with appended parameters code which is to be submitted.
action="MyAction.action?id=<%=request.getParameter("id")%>&name=<%=request.getParameter("name")%>&age=<%=request.getParameter("age")%>&num=<%=request.getParameter("num")%>"
Is the above is the syntax problem? If not then how can we set the parameters as a query string with action?
You should not use Scriptlets (<%= %>)
And, if action is an attribute of a Struts tag (like <s:form>), you can't use scriptlets, you should use OGNL.
Please refer to this question: Struts 2 s:select tag dynamic id for more details
Assumed the action attribute is used with the <form tag. Then the construction
<form name="MyAction.action" action="upload?id=<%=request.getParameter("id")%>&name=<%=request.getParameter("name")%>&age=<%=request.getParameter("age")%>&num=<%=request.getParameter("num")%>" method="POST">
should work with the current context. But in your case given error message (Exception Name: org.apache.jasper.JasperException: equal symbol expected is occurred when <s:form tag is used. So, you cannot use this url in the action attribute. This attribute should contain the plain action name that would be used to find your action.
"How we set parameters as a querystring?"
Actually we do it with <s:param tag. For example, when using hyperlinks
<s:a action="MyAction">
<s:param name="id" value="%{id}"/>
<s:param name="name" value="%{name}"/>
</s:a>
But this construction doesn't work with <s:form tag, unless you applying a special syntax as described in this answer and you definitely want to get these parameters if you do in the action
String quesyString = request.getQueryString();
and this string should not be empty.
However, this usecase is rarely applied, If you don't have a reason to get parameters in such way then as alternative you always can use <s:hidden fields to contain the values of the parameters. For example
<s:form action="MyAction" method="POST">
<s:hidden name="id" value="%{id}"/>
<s:hidden name="name" value="%{name}"/>
</s:form>
These values are passed as a parameters and initialize the action attributes after params interceptor worked. You could also get this parameters directly from the request as
Map<String, String[]> params = (Map<String, String[]>)request.getParameterMap();
However, the more convenient way to do this in your action is to implement ParameterAware.
Just like #AndreaLigios mentioned, you should use Struts2 specified EL, check out the Document here.
If you are using <s:url/>, check out Document please for more information.
Your code should look something like this:
<s:url value="MyAction.action">
<s:param name="id" value="%{#parameters.id}" />
<s:param name="name" value="%{#parameters.name}" />
<s:param name="age" value="%{#parameters.age}" />
<s:param name="num" value="%{#parameters.num}" />
</s:url>

Scriptlet variable doesn't get evaluated inside an attribute of a custom JSP tag

I am trying to have a JavaScript function called when I click a link. This JavaScript function is definied in an attribute of a JSP tag and I am trying to pass a scriptlet variable to the function. However, it doesn't get evaluated. The relevant part of the code is:
<span>
<mysecurity:secure_link id='<%="editButton_"+commentUUID%>' entitlement=""
actionOnClick="editComment('<%= commentUUID %>');return false;"
isSurroundedByBrackets="true" enableTitle="" disableLink="<%=disableLink%>">
<span style="color:#0033BB; font:8pt arial;">
<bean:message key="button.edit" />
</span>
</mysecurity:secure_link>
</span>
IE8 mentions a JavaScript error in the bottom left corner. When I right click and view source, the generated HTML is:
onclick="editComment('<%= commentUUID %>');return false;"
So, the <%=commentUUID%> is not been evaluated in the actionOnClick attribute, but it's successfully been evaluated in id attribute.
How is this caused and how can I fix it?
I'm not sure whether the <mysecurity:secure_link> is a custom or an existing 3rd party JSP tag library. Modern JSP tags usually do not evaluate legacy scriptlet expressions. You should rather be using EL (Expression Language) instead.
First ensure that commentUUID variable is been stored as an attribute of the page or request scope so that it's available to EL, like as the following example in a preprocessing servlet:
request.setAttribute("commentUUID", commentUUID);
or using another scriptlet in JSP:
<% request.setAttribute("commentUUID", commentUUID); %>
or using JSTL's <c:set> in JSP:
<c:set var="commentUUID"><%=commentUUID%></c:set>
then you can access it as follows in EL:
<mysecurity:secure_link actionOnClick="editComment('${commentUUID}');return false;" />
What finally worked for me, with the #BalusC 's advice was to use editcomment(this.id.split('_')[1]). The correct working code is as follows:
<span>
<mysecurity:secure_link id='<%="editButton_"+commentUUID%>' entitlement=""
actionOnClick="javascript:editComment(this.id.split('_')[1]);return false;"
isSurroundedByBrackets="true" enableTitle="" disableLink="<%=disableLink%>">
<span style="color:#0033BB; font:8pt arial;">
<bean:message key="button.edit" />
</span>
</mysecurity:secure_link>
</span>

Struts Nested Tag with Dynamic Parameters

I have a legacy Struts 1 application which uses the nested tag. Can I inject a dynamic parameter into the nested tag? For example,
<nested:select disabled="<c:out value='${requestScope.disableSelectBox}' />" />
I also tried doing:
<nested:select disabled="${requestScope.disableSelectBox}" />
In both of the above examples, the disabled attribute was not properly set and it was ignored. If I printout the value with a c:out, the correct value of disableSelectBox is displayed:
<c:out value="${requestScope.disableSelectBox}" />
A colleague suggested that I should use:
<nested:select disabled="<%=request.getAttribute("disableSelectBox"); %>" />
The trouble is that it is considered bad practice to use java scriplets in a JSP page. Is there any way to embed a dynamic variable into a Struts 1 nested tag? Switching to Struts 2 is not an option.
Thanks!
Struts 1 (as far as I can remember) cannot allow you to do:
<nested:select disabled="<c:out value='${requestScope.disableSelectBox}' />" />
As it can't process JSP tags inside any of their attribute declarations, Check what nested:select disabled attribute required needs.
But Struts do support EL and JSP Scriplets (so your colleague is correct). JSP Scriptlet will "render" the value of the <%=request.getAttribute("disableSelectBox"); %> and assign it to the <nested:select disabled="<%=request.getAttribute("disableSelectBox"); %>" />
So (if I assume that the values returns a true or false,
<nested:select disabled="${requestScope.disableSelectBox}" />
and
<nested:select disabled="<%=request.getAttribute("disableSelectBox"); %>" />
will be rendered as (if results returns true)
<nested:select disabled="true" />
before it is sent to Struts to render the nested tag (sorry for using the word "render", you can use translate if you want).

Categories