I am facing a problem in Struts2, In my sample application I have Array of objects (Say person name) , I need to display these names as a editable text fields , I am using Iterators for this , I am successful in diaplying, But When I cange the same value and submit the form. I am getting the entire array which holds null value.
Say for Exaple in my form bean I have a property
Name [] names;
In my JSP I have the iterator as
If there are 3 names then I can get these names on the UI if I can initialized them with some dummy value but when I edit and sumbit, then "names" array is not getting updated. Please help me in this regard
In Struts2, when you need to repopulate the list of bean items, you need to refer them through indices. Please refer the example below:
Bean class:
public class Person {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Action class:
public class PersonAction extends ActionSupport {
private List<Person> persons;
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
//Initial Load method
#Override
public String execute() {
persons = new ArrayList<Person>();
int alpha = 65;
for(int i = 0; i < 3 ; i++) {
Person person = new Person();
person.setId(i);
person.setName(String.valueOf((char)alpha++));
persons.add(person);
}
return SUCCESS;
}
//Function that handles the form submit
public String updatePerson() {
for(Person person : persons) {
System.out.println(person.getId() + ":" + person.getName());
}
return SUCCESS;
}
}
Page:
<s:form action="doUpdate">
<s:iterator value="persons" status="stat" var="person">
<s:textfield value="%{#person.name}" name="persons[%{#stat.count}].name"/><br/>
</s:iterator>
<s:submit value="Submit"/>
</s:form>
When you submit the above form, the url would look like doUpdate?persons[0].name=A1&persons[1].name=B1&persons[2].name=C1. Similarly if you need to update id of the first person object, you will append persons[0].id=3 to the url using form. In the <s:textfield value="%{#person.name}" name="persons[%{#stat.count}].name"/>, you tell that the predefined value is person's name, for each object. The name attribute is to set the rendered html input element; the name which will be referenced in the url when the form is submitted. You will get a clear idea if you look into the generated html.
Use the iterator tag of struts2, if list is not empty then use :
<s:iterator value="names" status="namesStatus">
<s:property/><br/>
</s:iterator>
Related
I have a legacy MongoDB database (collection) where there is single value stored as an array List . But its only a one value that must be, in UI selected with ComboBox. So I have a model bean
class Project {
List<Company> companies;
}
And I would like to bind it and edit with VAADIN ComboBox. Initialy I thought I can use some customer converter for ComboBox but can't get it to work. Combo should edit the first value in the List (Company bean) and store back into companies field as an array to remain compatible. Is it event possible to do it and if so can you give me some hint how to accomplish this?
EDIT: Enhanced explanation
MongoDB model:
class Project {
List<Company> companies;
}
Vaadin UI:
ComboBox companies;
... 'companies' ComboBox is attached to BeanItemContainer which is List ... selection is therefore the only one Company bean, but should be stored, for compatibility reasons, as List with only one item. So basicly ComboBox should be able to read existing List value as single Company, allow selection and store it as List with this one selecten Company.
After the last question update the answer below may not be correct. Waiting for OP to provide details so the answer can be corrected.
You can use a sort of a delegation approach using a ProjectDelegator wrapper. This will allow you to bind the form to the Project name (using the project field) as well as the Company name (using the getCompany() getter)
1. The UI class
#PreserveOnRefresh
#SpringUI
public class MyVaadinUI extends UI {
#Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
// add the form to the UI
layout.addComponent(new MyForm(new ProjectDelegator(new Project("myProject", new Company("myCompany")))));
}
}
2. The form
// "wrapping" the form in a custom component. not really needed but a nice touch
public class MyForm extends CustomComponent {
public MyForm(ProjectDelegator projectDelegator) {
FormLayout layout = new FormLayout();
// use a binder to create fields and bind the members using reflection
BeanFieldGroup<ProjectDelegator> binder = new BeanFieldGroup<>(ProjectDelegator.class);
// bind the project name using the "project" field
layout.addComponent(binder.buildAndBind("Project", "project.name"));
// bind the company name using the "getCompany" method
layout.addComponent(binder.buildAndBind("Company", "company.name"));
// add a "save" button
layout.addComponent(new Button("Save", new Button.ClickListener() {
#Override
public void buttonClick(Button.ClickEvent clickEvent) {
try {
// commit changes
binder.commit();
} catch (FieldGroup.CommitException e) {
// didn't expect this! what gives?!
System.out.println("Could not save data: [" + e.getMessage() + "]");
}
}
}));
// set the delegator as the binder data source
binder.setItemDataSource(projectDelegator);
setCompositionRoot(layout);
}
}
3. The "delegator"
// delegator class to adapt from/to list with only 1 item
public class ProjectDelegator {
// nice constant to express the intent as clearly as possible
private static final int MY_ONLY_COMPANY = 0;
// our delegate
private Project project;
public ProjectDelegator(Project project) {
this.project = project;
}
// BeanFieldGroup will use this by reflection to bind the "company.name" field
public Company getCompany() {
// delegate the accessing to the origina product
return project.getCompanies().get(MY_ONLY_COMPANY);
}
// accessor; can if not required at a later time
public Project getProject() {
return project;
}
}
4. The legacy model classes
// our problem class
public class Project {
private String name;
private List<Company> companies = new ArrayList<>();
public Project(String name, Company company) {
this.name = name;
companies.add(company);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Company> getCompanies() {
return companies;
}
public void setCompanies(List<Company> companies) {
this.companies = companies;
}
}
// the "indirect" problem :)
public class Company {
private String name;
public Company(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("Setting actual company name to [" + name + "]");
this.name = name;
}
}
5. Resulting UI
6. Pressing the save button
Setting actual company name to [myNewCompany]
I want to pass a session value as a hidden form value to an action class.
I have seen several examples but nothing worked for me; I get a null in the action.
Update.jsp:
<s:hidden name="name" value="%{#session.sname}" />
<s:property value="#session.sname"></s:property>//works fine and printing username
User name is stored in session. I want to send this name to action class but I am unable to send.
UpdateAction.java:
public class UpdateAction extends ActionSupport {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public string execute() {
System.out.println("Username"+name);//getting null value
}
}
You should try:
<s:hidden value="%{#session['sname']}" name="aName"></s:hidden>
I have a ui tag select
<s:select list="studentList" name="selectedstudent" listKey="studentID"
listValue="studentName" headerKey="0"
headerValue="--All Student--" theme="simple"></s:select>
in java code i have selectedstudent returns let say 4 how can I get the name of student in java.
You can get the name by id in selectedstudent. For this purpose if you don't have a students list in your action, you should load them from database. Otherwise searching a Student object by id would return a name if you provide a getter for the object. Keep in mind that you have already specified a listValue as studentName. This value should be taken from a Student and thus a list should be List<Student> as well.
If your studentList is in session you can retrieve student name as follow (your code may be different):
List<Student> studentList = (List<Student>)ActionContext.getContext().getSession().get("studentList");
//You should ovveride equals(and hashCode) to point the Student equality to studentID
//You should also check if studentList.indexOf(selectedstudent) != -1
Student student = studentList.get(studentList.indexOf(selectedstudent));
String studentName = student.getStudentName();
Business layer
Student.java (model)
public class Student {
//Getter and Setter Method.
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
}
struts.xml
<action name="list_action" class="controller.ListAction">
<result name="success">struts_select.jsp</result>
</action>
package controller;
ListAction.java
private List<Student> student_list = new ArrayList<Student>();//Getter and Setter
#Override
public String execute() throws Exception {
//do your stuff
//list collect from database.
student_list=(List<Student>) criteria.list();
}
struts_select.jsp
<s:select label="Student List"
listKey="id" //use your Student.java member variable of id signature
listValue="name" //use your Student.java member variable of name signature
headerKey="0" headerValue="Select student Name"
list="s"
name="student_info" />
Hey guys I'm having some problems with a project that I'm doing :/
I have this code
public class ListaAlumnoAction {
private List<Alumno> alumnos;
public String execute(){
String camino="success";
EntityManager em= Utilitario.getInstance().getEntityManager();
Query query=em.createQuery("Select o From Alumno o");
alumnos=query.getResultList();
return camino;
}
public List<Alumno> getAlumnos() {
return alumnos;
}
public void setAlumnos(List<Alumno> alumnos) {
this.alumnos = alumnos;
}
}
This method gives me a list of students. But in this case I just want 1 student, searching by code for example or by name and last name. The thing is I don't know what kind of tools use for this purpose.
Thanks in advanced.
For searching the student by specified input criteria, you are in need of passing the required input from the page to the action class. And need to modify the query which will search the student record by mentioned name or last name or desired input.
For example, assume student name is the input criteria
To pass the student name from the page:
<s:form>
......
<s:textfield name="studentName" label="Student Name"></s:textfield>
<s:submit value="Search" name="submit" action="ListaAlumnoAction"/>
......
</s:form>
Here the studentName will be the input for search operation and ListaAlumnoAction is action which will fired when Search button clicked.
To get the Student Name in the Action Class:
public class ListaAlumnoAction {
private List<Alumno> alumnos;
/* Please note both the text filed name in the page and attribute should be same "studentName" */
private String studentName;
public String execute(){
String camino="success";
EntityManager em= Utilitario.getInstance().getEntityManager();
// "name" variable will hold the studentName
String name = getStudentName();
// Modify the query, by passing the name if it is not null
Query query=em.createQuery("Select o From Alumno o");
alumnos=query.getResultList();
return camino;
}
public List<Alumno> getAlumnos() {
return alumnos;
}
public void setAlumnos(List<Alumno> alumnos) {
this.alumnos = alumnos;
}
// getter and setter for the studentName
public String getStudentName(){
return studentName;
}
public void setStudentName(String studentName){
this.studentName = studentName;
}
}
I use Struts 2 Framework and i want to pass a parameter in my action like this localhost:8080/MyApp/ModifierMessage.action?id=9. In my jsp page i have the following text with the action:
Modifier
Someone could help me to add dynamic id to my action ?
Use <s:url> and <s:a> tags. For example is your dynamic id is called dynamic_id:
<s:url var="myUrl" action="ModifierMessage.action" namespace="/OCC">
<s:param name="id">%{dynamic_id}</s:param>
</s:url>
<%-- The link --%>
<s:a href=%{#myUrl}>Modifier</s:a>
public class MyAction extends ActionSupport {
private int id;
public String execute() {
...
this.id = 123;
return SUCCESS;
}
public int getId() { return this.id; }
public void setId(int id) { this.id = id; }
...
}
In the above code if it returns SUCCESS then the browser will be forwarded to
/<app-prefix>/myNamespace/otherAction.action?id=123