Search method in Struts with MySQL - struts2

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;
}
}

Related

access [NotMapped] property with a custom getter/setter

I have a database with folders where I store the whole path to a folder as a folder_name so sth. like: //MainFolder/subFolder/folderName. Im my application I have a Model called Folder, which represents the folders from db.
Model:
public class Folder
{
[Key]
public string folder_name { get; set; }
[NotMapped]
public string folder_name_short
{
get
{
string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/")); //System.NullReferenceException here
return shortname;
}
set
{
string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/"));
this.folder_name = folder_name.Replace(shortname, value);
}
}
}
folder_name_short isn't mapped because it is only a substring from the whole path, so I don't want to store it twice. Example want I mean:
Console.WriteLine(folder_name) output://MainFolder/subFolder/folderName
Console.WriteLine(folder_name_short) output:/folderName
In my View the user can rename the folder. So I would like to replace the old folder_name_short to the new one and store the new String in folder_name
View:
.
.
using (Html.BeginForm("Rename", "Folders", FormMethod.Post))
{
#Html.EditorFor(model => model.folder_name_short)
<input type="submit" value="rename folder" id="submit" class="btn btn-default" />
}
.
.
Problem:
The Inputtextbox renders and shows the current Value of folder_name_short in it. When I change it and click the submit button, I get a System.NullReferenceException in the Model (as marked in the source code, please scroll to right). I don't understand what is wrong and what changes are needed.
Edit:
when the setter is commented out, the Exception disappear. So maybe the setter is causing the error?
Solution:
use the standard setter and getter for storing the folder_name_shortvalue, but implement a public get/set method to set the folder_name in the db and call this method in the controller. So:
[NotMapped]
public string folder_name_short { get; set; }
public string getfolder_name_short()
{
string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/"));
return shortname;
}
public void setfolder_name_short(string newname)
{
string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/"));
folder_name = folder_name.Replace(shortname, newname);
}
If the value that is edited on the form is the short name folder_name_short then the model class could contain its string property:
public string folder_name_short { get; set; }
This property does not contain any logic. Any other code that contains some logic could be in the controller in an action method.
It seems you are using the same class for DB access and as a model class for the MVC view, which is the source of the problem.
[HttpPost]
[("Rename")]
public async Task<IHttpActionResult> ChangeFolderPath(Folder folder)
{
//Put a breakpoint here and make sure the folder has a value
}
probably that the setter method overwrite the value of folder_name.
I would recommand this thread to help understand custom setters
C# properties: how to use custom set property without private field?
EDIT
public class Folder
{
[Key]
public string folder_name { get; set; }
/*Model Logic shouldn't be in the Poco*/
/*You may put that in your model or best thing would be to implement a repository pattern*/
public string ShortName()
{
string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/")); //System.NullReferenceException here
return shortname;
}
public void SetUsingShortName(string value)
{
string shortname = folder_name.Substring(folder_name.LastIndexOf("/"), folder_name.Length - folder_name.LastIndexOf("/"));
this.folder_name = folder_name.Replace(shortname, value);
}
}

How to pass the sesssion value as hidden value in struts2?

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>

Getting the selected item text in struts 2

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" />

MVC Model Binding subclass object property filled with a string array

I have a base view model with an Id property of type object (so I can have it be an int or a Guid) like so:
public abstract class BaseViewModel
{
public virtual object Id { get; set; }
}
And the view models thus derive from this
public class UserViewModel : BaseViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
My HTML then is rendered as:
<input id="Id" name="Id" type="hidden" value="240" />
<input id="FirstName" name="FirstName" type="text" value="John" />
<input id="LastName " name="LastName " type="text" value="Smith" />
And when submitted to the MVC action:
[HttpPost]
public ActionResult EditUser(UserViewModel model)
{
...code omitted...
}
The values for the model properties are:
Id: string[0] = "240"
FirstName: string = "John"
LastName: string = "Smith"
My question is, why am I getting a one item string array as the value for Id, rather than just a string? And is there a way to change this behavior? It causes problems when I try to parse it into the expected type.
I ended up solving this with a custom model binder that handles the "Id" object property as a special case:
public class CustomModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
{
// apply the default model binding first to leverage the build in mapping logic
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
// since "Id" is a special property on BaseViewModel of type object,
// we need to figure out what it should be and parse it appropriately
if (propertyDescriptor.Name == "Id" && propertyDescriptor.PropertyType == typeof(object))
{
// get the value that the default binder applied
var defaultValue = propertyDescriptor.GetValue(bindingContext.Model);
// this should be a one element string array
if (defaultValue is string[])
{
var defaultArray = defaultValue as string[];
// extract the first element of the array (the actual value of "Id")
var propertyString = defaultArray[0];
object value = propertyString;
// try to convert the ID value to an integer (the most common scenario)
int intResult;
if (int.TryParse(propertyString, out intResult))
{
value = intResult;
}
else
{
// try to convert the ID value to an Guid
Guid guidResult;
if (Guid.TryParse(propertyString, out guidResult)) value = guidResult;
}
// set the model value
propertyDescriptor.SetValue(bindingContext.Model, value);
}
}
}
}
The issue is with typing your id property as object -- not sure how the default binding is supposed to work here, but since an object is potentially anything -- like a complex object with multiple properties itself -- perhaps it attempts to dump all of the properties it finds there into an array?
If the Id is not always going to be an integer, I'd suggest typing this as string, since the model-binding mechanism should have no problem mapping virtually anything sent over HTTP as string, so:
public abstract class BaseViewModel
{
public virtual string Id { get; set; }
}

update a list of value in textfield in struts2

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>

Resources