How to evaluate a dynamic/nested Spring property placeholder expression? - spring

I'm working on a JSP tag. Here is the old line that starts looping through items in a model:
<c:forEach var="toc" items="${requestScope[formKey].model.sharingTocs}">
But the code has been refactored so the model path (model.sharingTocs above) is now dynamic rather than fixed. It is now passed into the tag via a JSP #attribute:
<%#attribute name="path" required="true"%>
So ${path} now evaluates to "model.sharingTocs".
How can items now be assigned?

Well. Good question.
This is a solution: writing a custom jstl tag to Evaluate a property expression of a bean:
<mytag:eval bean="${requestScope['formKey']}" propertyExpression = "${path}" var="items" />
And ForEach:
<c:forEach var="toc" items="${items}">
</c:forEach>
Sample code of mytag:eval JSTL tag ( Classic model )
public class EvalTag extends TagSupport
{
private Object bean;
private String propertyExpression; //Ex: 'model.sharingTocs'
private String var;
//............
#Override
public int doEndTag() throws JspException {
try {
// Use reflection to eval propertyExpression ('model.sharingTocs') on the given bean
Object propObject = SomeLibs.eval ( this.bean, this.propertyExpression);
this.pageContext.getRequest().setAttribute(this.var, propObject);
// You can add propObject into Other scopes too.
} catch (Exception ex) {
throw new JspTagException(ex.getMessage(), ex);
}
return EVAL_PAGE;
}
//............
// SETTERS here
}
A lib you can use to eval propertyExpression of a bean is Apache bean utils.
http://commons.apache.org/proper/commons-beanutils/apidocs/org/apache/commons/beanutils/package-summary.html#standard.nested

If you are using spring you can utilise the spring tag library, it also assumes you are inside a form:form tag.
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# attribute name="path" required="false" %>
<spring:bind path="${path}">
<c:forEach var="item" items="${status.value}">
${item}
</c:forEach>
</spring:bind>

It's been quite a while since I asked this question but (with new knowledge gained since) I think this ought to work:
<c:set var="itemsPath" value="requestScope[formKey].${path}"/>
<c:forEach var="toc" items="${itemsPath}">
i.e. set up an intermediary JSTL variable with the full path to the items and evaluate that one instead.

Related

Extend JSF 2.2 application by adding xhtml files from external directory

I tried to extend a JSF application by including xhtml files from a directory which is not in the context root:
Point of inclusion:
<form>
<ui:repeat value="#{calcBean.resolveIncludes()}" var="curInc">
<ui:include src="#{curInc}" />
</ui:repeat>
</h:form>
CalcBean delivers:
public List<String> resolveIncludes()
{
final List<String> ret = new ArrayList<>();
ret.add("D:/extensionDir/inc1.xhtml");
ret.add("D:/extensionDir/inc2.xhtml");
return ret;
}
The content of the xhtml files is not included because the path must be relative the origin xhtml according documentation. Is there a way to achieve this? The aim is to extend a JSF application by adding a set of files to a defined extension directory without redeploy.
Ok it works. But unfortunately the path is validated before the ResourceHandler is invoked. To identify the resource as "external dynamic" I had to prefix it for instance with "extension_". In the origin example:
public List<String> resolveIncludes()
{
final List<String> ret = new ArrayList<>();
ret.add("/extension_inc1.xhtml");
ret.add("/extension_inc2.xhtml");
return ret;
}
And I had to use c:forEach instead of ui:repeat:
<c:forEach items="#{calcBean.resolveIncludes()}" var="curInc">
<ui:include src="#{curInc}" />
</c:forEach>

Spring MVC: two identical forms on page using one bean, same parameters

So I have a page with layout:
<form:form id='form1'>
<form:hidden path="order" />
<form:form id='form2'>
<form:hidden path="order" />
Constructor:
public ModelAndView showListView(Model model,
#ModelAttribute("form1") FormSearch form1,
#ModelAttribute("form2") FormSearch form2){
When I press button on form1 to receive 'order' value, I see that browser sends values correctly form1:order is newValue and form2:order is oldValue. But in constructor I receive form1:order newValue and form2:order newValue. So I think Spring is searching for first param value for both forms, which is incorrect.
What should I do to fix that?
Answer from different thread fixed the issue:
#InitBinder("form2")
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("*");
}
Have you tried:
<form:form id='form1' modelAttribute="form1">
<form:form id='form2' modelAttribute="form2">

How to get static method value in jsp without creation bean in Spring?

Below code for bytes to kb conversion code its for Static return type.So how can i get a value in many jsp without creation bean.
public static double bytesToKB(int bytes){
return (double)bytes/1024;
}
how about this?
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<spring:eval expression="T(com.abc.xyz.YourClassName).bytesToKB(2560)" var="result"></spring:eval>
Spring Eval result: <c:out value="${result }"/>

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'newReward' available as request attribute

I'am new to Spring MVC, following the "Spring in Action" book, creating my own project from scratch. I get the following exception when trying to reach 'reward.jsp':
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'reward' available as request attribute
Contents of my classes:
reward.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>
<html>
<head>
<title>Rewards</title>
</head>
<body>
<h1>Rewards module</h1>
<h2>Add reward</h2>
<sf:form action="add" method="post" modelAttribute="reward">
Reward name:<sf:input path="name" />
Point value:<sf:input path="pointValue" />
<input type="submit" value="Add">
</sf:form>
<br />
<h2>Reward list</h2>
<table>
<c:forEach var="reward" items="${rewardList}">
<tr>
<td>${reward.name}</td>
<td>${reward.pointValue}</td>
<td>delete</td>
</tr>
</c:forEach>
</table>
It works just fine when I delete form inputs.
RewardController.java
#Controller
public class RewardController {
#Autowired
private RewardService rewardService;
#RequestMapping("/reward")
public String listRewards(Map<String, Object> model) {
model.put("rewardList", rewardService.listReward());
return "reward";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addReward(#ModelAttribute("reward") Reward reward,
BindingResult result) {
rewardService.addReward(reward);
return "redirect:/reward";
}
#RequestMapping("/delete/{rewardId}")
public String deleteContact(#PathVariable("rewardId") long rewardId) {
rewardService.removeReward(rewardId);
return "redirect:/reward";
}
}
Change your listRewards method, so that it add the form backing object to the model map model.put("reward", new Reward()).
#RequestMapping("/reward")
public String listRewards(Map<String, Object> model) {
model.put("rewardList", rewardService.listReward());
model.put("reward", new Reward())
return "reward";
}

Can't "render/not render" a4joutputpanel rendered="" "true/false" parameter by managed bean at JBoss Seam and Richfaces

I'm new on seam and richfaces. I want to hide/show a4joutputpanel by rendered="" "true/false" parameter by giving Managed Bean.But ı'm taking this exception:
com.sun.facelets.tag.TagAttributeException: /testscreen.xhtml
action="#{testBean.renderActive(true)}" Not a Valid Method Expression: #{testBean.renderActive(true)}
Can anyone help me about that?
Here's my xhtml and managedbean codes:
<a4j:commandButton action="#{testBean.renderActive(true)}" reRender="MyPanel" value="Start" />
<a4j:outputPanel id="MyPanel">
<s:div rendered="#{testBean.renderProperty}">
........
</s:div>
</a4j:outputPanel>
ManagedBean
public void renderActive(Boolean rendeBoolean){
this.renderProperty=rendeBoolean; }
private Boolean renderProperty;
public Boolean getRenderProperty() {
return renderProperty;
}
public void setRenderProperty(Boolean renderProperty) {
this.renderProperty = renderProperty;
}
#{testBean.renderActive(true)} is actually not a valid method expression in plain JSF EL because method expressions cannot have parameters.
It's valid with EL extension provided by jboss-el.jar, though.
Check if this jar is present in the application classpath, that is in the EAR or in WEB-INF/lib if you don't package the application as war. (see § 30.3.1 Packaging in the reference documentation).

Resources