Avoiding duplication in parameter name - java

Inside a POST in a .jsp file, I'd like to do something like this:
<input type="text" name="...">
And inside the servlet I'd like to do:
request.getParameter(...)
Now where should and how should I declare "..." so that I can avoid duplication and reuse the same String.
Should this go in an interface like this:
public interface SO {
String POST_PARAM = "userinput";
}
Or in a property file? Or ...?
In any case, how do I then access this from the .jsp and from the .java file?

You can define constants like final String POST_PARAM = "userinput"; and then use them in markup: <input type="text" name="<%=POST_PARAM%>">.
Moving fields names to properties file does not sound as a beneficial unless you have reasons to do this.
To get parameter value from HTTP request caused by form submit say request.getParameter(POST_PARAM).
I hope this helps.

You might get the ... from a bean using EL. However, it is not usual for me.

You can use standard actions: jsp:useBean, jsp:setProperty and JavaBean technology:
Example:
A.jsp should call HTTP POST to B.jsp. B.jsp should automatically map all fields and redirect to your servlet.
// model.MyBean.java
class MyBean {
private int age;
// getters&setters
}
// A.jsp:
<form method="POST" action="B.jsp">
<input type="text" name="age">
</form>
// B.jsp
<jsp:useBean id="form" class="model.MyBean" scope="request" />
<jsp:setProperty name="form" property="*" />
<jsp:include page="/servletURL" />
Small description:
MyBean class will be created. This bean should has exactly the same
fields name like name in your form: for <input type="text"
name="age"> in bean should exists int age field and getter/setter.
jsp:setProperty with wildcard map all values from form A.jsp into your bean automatically.
if you want to call your servlet you can simple include appropriate url. Then in the servlet you will have access to request attribute "form" which will has MyBean with entered values.

Related

Is it possible to set a struts token with a GUID as a token name?

I'm trying to set a struts token in a form with a unique name for each form. Is there way to set up the token in a way like <s:token name="<some random generated characters>". I was planning to use the TokenHelper.generateGUID() to generate the token name, if possible. I've tried setting a variable using <s:set var="tokenName" value="<%=TokenHelper.generateUID()%>"/>, then setting the token using <s:token name="${tokenName}"/>. I'm getting tld error about setting the in the tag. Here is the general code flow of the form.
here are the things that i've tried, but got the same result.
<%# page import="org.apache.struts2.util.TokenHelper" %>
<s:form action="actionName_method" name="actionName" method="post">
<s:token name="<%=TokenHelper.generateGUID()%>"/>
<s:hidden ....
.... rest of the fields go here ....
<s:submit value="save" name="submit"/>
</s:form>
Another one I tried is,
<%# page import="org.apache.struts2.util.TokenHelper" %>
<s:set var="tokenName" value="${f:generateGUID()}"/>
<!-- I defined generateTokenName as a tld function using the TokenHelper class -->
<s:form action="actionName_method" name="actionName" method="post">
<s:token name="${tokenName}"/>
<s:hidden ....
.... rest of the fields go here ....
<s:submit value="save" name="submit"/>
</s:form>
Here is the my definition of the function f:generateGUID() in the tld file.
<function>
<description>This will generate the a unique tokenName</description>
<name>generateGUID</name>
<function-class>org.apache.struts2.util.TokenHelper</function-class>
<function-signature>java.lang.String generateGUID()</function-signature>
</function>
Thank you in advance.
Yes, it's possible to set a token name with
<s:token name="%{tokenName}"/>
It will generate two hidden fields one for the token name and another for the token value. Make sure the value of the first field corresponds to the name of the second field.
The action property tokenName is initialized like
tokenName = TokenHelper.generateGUID();
or
tokenName = UUID.randomUUID().toString();
Also make sure the form is using POST method.

Struts2: values from action are not seen in jsp, but they are seen in the javascript code from jsp

In action I have a variable which has getter on it.
private String myActionVariable = "predefined....";
public String getMyActionVariable () {
return myActionVariable;
}
In jsp, I try to use my variable in this way:
<input type="button" class="styledButton"
onclick="javascript: doAjax('myActionName',false);"
value="${myActionVariable}"
But it is not shown. However, if I output this variable from the javascript code included within the same jsp file:
alert (${myActionVariable})
I will get the value of it....
Any idea please ? ...
You can use a Standard <input/> HTML Tag with an <s:property /> Struts2 Tag for the value, like this:
<input type="button" class="styledButton"
onclick="javascript:doAjax('myActionName',false);"
value="<s:property value="%{myActionVariable}"/>"/>
or a Struts2 Tag directly like this:
<s:submit type="button" cssClass="styledButton"
onclick="javascript: doAjax('myActionName',false);"
value="%{myActionVariable}" />
Note that with Struts2 Tag, class attribute becomes cssClass (and style becomes cssStyle), and that %{} is the right OGNL syntax, instead of ${} (that is JSTL syntax)
EDIT: when using Struts2, forget about JSTL, you won't need them anymore.
You should be using struts2 tag.
<input type="button" class="styledButton" onclick="javascript: doAjax('myActionName',false);" value="${myActionVariable}">
Instead of this, use
<s:submit type="button" cssClass="styledButton" onClick="javascript: doAjax('myActionName',false);" value= "myActionVariable" />

How to bind a comma separated string to a Java collection (List) in Spring form?

I'm stuck in a situation where I've an input element in a JSP where user enters tags. E.g. java, foo, bar, anotherTag..etc
<c:url var="saveUrl" value="/create" />
<form:form modelAttribute="myAttribute" method="POST"
action="${saveUrl}">
<form:input path="myTitle" />
<form:textarea path="myPost" />
<form:input type="text" id="tagInput"path="???" />
<input type="submit" value="create" />
</form:form>
Now in my domain model corresponding to this input is a
private List<Tag> listOfTags
How to bind a csv to a List. If I enter listOfTags in the path(which is wrong for obvious reasons), I get incorrect binding exception.
How do I convert(or bind) a csv to a List so that the Spring form is submitted properly and the listOfTags get the tags entered in the JSP.
What is the best way to achieve it?
Please help.
I'm not sure but try this. Do a simple html input :
<input type="text" id="tagInput" name="myTags" />
And then in your controller do something like :
#RequestMapping(value="/create", method=RequestMethod.POST)
public void create(..., #ModelAttribute("myAttribute") MyClass myAttribute,
#RequestParam("myTags") String myTags, ...) {
...
myAttribute.setListOfTags(Arrays.asList(myTags.split(",")));
...
}
Note : for more generic ways to bind and convert objects, you may want to take a look at PropertyEditors and Converters.
I suggest try to bind it directly to listOfTags property. And to make it work just add contructor with one argument of String type (or define static method valueOf(String)) to Tag class.
Pretty sure you could do something like this:
<c:forEach var="i" begin="1" end="10">
<form:input type="text" path="listOfTags" />
</c:forEach>
Where you get the user to enter each tag into a separate text input. This is because Spring will automagically bind multiple inputs with the same form name to a List, when it does its binding.
You could use some jQuery sugar to only show one or two and then provide a widget to show more tag inputs. Or even write some cool JS to populate the inputs from a single text input just like StackOverflow does when you add tags.

Inconsistent Expression Language behaviour, same expression different values

The same EL expression ${taskId} gives two different values in different places.
I am using the Stripes framework, along with MongoDB and Morphia for Object-Mapping (and of course Java/JSP/etc).
Using the following JSP/Expression Language code:
<c:forEach items="${actionBean.tasks}" var="listTask">
<c:set var="taskId" scope="page" value="${listTask.id}"/>
<s:form method="post" beanclass="action.TaskActionBean">
${taskId}<s:hidden name="task.id" value="${taskId}"/>
<s:submit name="promoteTask" value="Up" />
</s:form>
</c:forEach>
Gives the following generated code:
<form method="post" action="/scrumyogi/">
4ef99b730364de7ec70dbd68
<input type="hidden" value="4ef99b6c0364de7ec70dbd67" name="task.id">
<input type="submit" value="Up" name="promoteTask">
<div style="display: none;">
<input type="hidden" value="NPNEJw6tUWfRBXf-vVOLTw==" name="_sourcePage">
<input type="hidden" value="XbfUDiSHGrU=" name="__fp">
</div>
</form>
As you can see ${taskId} is printing out 4ef99b730364de7ec70dbd68 and then 4ef99b6c0364de7ec70dbd67, which makes no sense to me, I need ${taskId} to print out the same value 4ef99b730364de7ec70dbd68 is the correct one.
Is there some known issue that could cause this.
EDIT: the real problem is that the ${taskId} within the hidden form tag is incorrect, I printed the other value to see what the expression contains, and then found that it's different in the different locations - which make things seriously confusing.
ActionBean code:
#UrlBinding("/")
public class TaskActionBean extends BaseActionBean{
String taskId;
Task task = new Task();
List<Task> tasks;
public final static String DISPLAY = "/index.jsp";
#DefaultHandler
public Resolution listTasks(){
tasks = Dao.datastore().find(Task.class).order("rank").asList();
return new ForwardResolution(DISPLAY);
}
public Resolution promoteTask(){
task.promoteTask();
tasks = Dao.datastore().find(Task.class).order("rank").asList();
return new ForwardResolution(DISPLAY);
}
// ... getters and setters
You have a taskId field in you action bean, and according to stripes taglib documentation:
The hidden tag assigns the value attribute by scanning in the following order:
for one or more values with the same name in the HttpServletRequest
for a field on the ActionBean with the same name (if a bean instance is present)
by collapsing the body content to a String, if a body is present
referring to the result of the EL expression contained in the value attribute of the tag.
So it probably finds the field in your action bean and takes the value from there.
The other (jsp el) ${taskId} is assigned from task list element.
Change the taskId to some name that doesn't coincide with your action bean field and it should work.

keeping track of multiple related input boxes using spring mvc

we have a list of domain objects needing to be edited on an html page. For example, the command & domain objects:
class MyCommand {
List<Person> persons;
}
class Person {
String fname;
String lname;
}
Then, the HTML I expect to have the Spring MVC tag libraries generate is like this:
<form>
<input name="persons[0].fname"> <input name="persons[0].lname"><br/>
<input name="persons[1].fname"> <input name="persons[1].lname"><br/>
<input name="persons[2].fname"> <input name="persons[2].lname"><br/>
...
<input name="persons[n].fname"> <input name="persons[n].lname"><br/>
</form>
But can't see how to express this using the Spring Form Tag Libraries (using Spring 2.5.6.). I want to use the tag libraries so that it takes care of binding existing values to the tags for editing (when they're there).
Any tips?
There isn't a way to simply have the Spring Form Tags generate the whole list based on the collection (it will do this for the options in a select box, but that's the only collection-based expansion I'm aware of). However, you can still use the Spring Form Tags within a loop like so:
<c:forEach var="person" varStatus="loopStatus" items="myCommand.persons">
<form:input path="persons[${loopStatus.index}].fname" /> <form:input path="persons[${loopStatus.index}].lname" /><br />
</c:forEach>

Categories