I am working on Spring. I am unable to display the list items in JSP. It says: Property not found on type java.lang.String.
I have a POJO class Student:
public class Student {
private Integer age;
private String name;
private Integer id;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
In my controller class I fetch list of students and assign it to a List and add the list to the model attribute. Which is as follows.
#RequestMapping("/getstuds")
public String getstudents(#ModelAttribute Student student, ModelMap model){
StudentDAO studentDAO = (StudentJDBCTemplate)applicationContext.getBean("studentJDBCTemplate");
List<Student> students = studentDAO.listStudents();
model.addAttribute("studlist",students);
System.out.println(students.iterator().next().getName());
return "showstuds";
}
showstuds.jsp
<table>
<c:forEach var="stud" items="${studlist} }">
<tr><td>${stud.Name}</td></tr>
</c:forEach>
</table>
I get the following exception:
javax.el.PropertyNotFoundException: Property 'Name' not found on type com.spring.mvc.Student
your variable name is name not Name
<tr><td>${stud.name}</td></tr>
instead of
<tr><td>${stud.Name}</td></tr>
And also remove the brace
items="${studlist}"
instead of
items="${studlist} }"
Related
I am developing a simple application by spring boot. I need to restrict the user to be able to only update the name, not all the filed that related to user data but unfortunately, my code has a problem that if someone sends a data in Json format and changes the age or any other field it will be updated but as I told I need the user to be able to change the only name not any other field. I have to mention I am using JPA repository and spring data
my controller
#RestController
#RequestMapping("/student")
public class StudentController {
#Autowired
StudentRepository repository;
// method i user to only update the name field
#PatchMapping("/pattt/{id}")
public ResponseEntity partialUpdateName(
#RequestBody Student partialUpdate,
#PathVariable("id") String id
){
Student.save(partialUpdate, id);
return ResponseEntity.ok(repository.save(partialUpdate));
};
}
JPA repository
#Repository
public interface StudentRepository extends JpaRepository<Student, Integer> {}
Student class
#Entity
#Table(name = "student")
public class Student {
#Id
#GeneratedValue
private int id;
private String name;
private int age;
private String emailAddress;
public Student() { }
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public Student(int id, String name, int age, String emailAddress) {
this.id = id;
this.name = name;
this.age = age;
this.emailAddress = emailAddress;
}
public static void save(Student partialUpdate, String id) {
partialUpdate.setName(id);
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getEmailAddress() {
return emailAddress;
}
}
The best solution for the future is to add a DTO layer to your application and use it to map to your object. See example below.
public class StudentDto {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Then you can map this to your model by Mapstruct:
#Mapper
public abstract class StudentMapper {
public static final StudentMapper INSTANCE =
Mappers.getMapper(StudentMapper.class);
#Mapping
Student studentDtoToStudent(StudentDto studentDto);
}
Mapstruct dependencies:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.0.Final</version>
</dependency>
You will be able to hide your internal structure from outside world.
In your conroller:
public ResponseEntity partialUpdateName(
#RequestBody StudentDto partialUpdate,
#PathVariable("id") String id)
{
Student student =
StudentMapper.INSTANCE.studentDtoToStudent(partialUpdate);
}
The last line will give you a safe student model which you can then save
Quick solution
In your controller:
public ResponseEntity partialUpdateName(
#RequestBody Student partialUpdate,
#PathVariable("id") String id)
{
Optional<Student> optionalStudent = repository.findById(id);
if(optionalStudent.isPresent() && partialUpdate!=null) {
Student current=optional.get();
current.setName(partialUpdate.getName());
return ResponseEntity.ok(repository.save(current));
}
/* return an error */
}
import java.util.Date;
public class Emp {
public Emp() {
}
private int Id;
private String name;
private Date date_of_join;
private String city;
private int age;
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate_of_join() {
return date_of_join;
}
public void setDate_of_join(Date date_of_join) {
this.date_of_join = date_of_join;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
I have a bean with 5 fields. I want to sort all the five field according to 1 than 2 than 3rd than 4 and than 5
It consists of
String
String,
Date,
String ,
Int.
What could i do to sort the list<Emp> inside the list according to id, name, date of join, city, age
You create a custom Comparator:
myList.sort(Comparator.comparingInt(Emp::getId)
.thenComparing(Emp::getName)
.thenComparing(Emp::getDate_of_join)
.thenComparing(Emp::getCity)
.thenComparingInt(Emp::getAge));
EDIT:
To address the requirement in the comments, you could sort the items accoring to the length of the city's string before sorting by it:
myList.sort(Comparator.comparingInt(Emp::getId)
.thenComparing(Emp::getName)
.thenComparing(Emp::getDate_of_join)
.thenComparingInt(e -> e.getCity().length())
.thenComparing(Emp::getCity)
.thenComparingInt(Emp::getAge));
I'm new to the Hibernate world, and I have a problem that I couldn't solve myself. And please be nice.
What I have :
Netbeans IDE 8.0.2
Mysql database (easyPHP) with some tables
What I want :
Select categories (table) which has 3 records with id,name, and description and show them (name and description) in jsp using EL.
My Category Class:
public class Category implements java.io.Serializable {
private Integer id;
private String name;
private String description;
public Category() {
}
public Category(String name, String description) {
this.name = name;
this.description = description;
}
public Category(String name, String description) {
this.name = name;
this.description = description;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
}
My getCategories method :
public static List getAllCategories(){
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
List results = session.createCriteria(Category.class, "category")
.list();
tx.commit();
return results;
}
My Controller:
List categories = CategoriesManagement.getAllCategories();
map.addAttribute("categories", categories);
My view (jsp):
<c:forEach var="cat" items="${categories} ">
${cat.name}
</c:forEach>
I'm getting nothing.
And when I show ${cat.class} it says :
java.lang.String
java.lang.String
java.lang.String
And when I show ${cat} it says :
com.company.Category#7136faa
com.company.Category#25636faa
com.company.Category#83baeaa
Update :
When I redefine toString() method in Category like this :
public toString(){
return "foo";
}
I get :
[foo
foo
foo]
Thanks in advance.
Use this: <c:out value="${cat.name}" />
I know it's wierd and after 9 hours I found that the space in
<c:forEach var="cat" items="${categories} "> was the error,
I should do as :
<c:forEach var="cat" items="${categories}">
Currently, I want to get list of selected checkbox from a table.
and I tried to have a sample code as below :
public class Student {
public List<String> listSubject;
public List<String> getListSubject() {
return listSubject;
}
public void setListSubject(List<String> listSubject) {
this.listSubject = listSubject;
}
private int id;
private String name;
private int age;
public boolean single;
public boolean isSingle() {
return single;
}
public void setSingle(boolean single) {
this.single = single;
}
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(List<String> listSubject, int id, String name, int age,
boolean single) {
super();
this.listSubject = listSubject;
this.id = id;
this.name = name;
this.age = age;
this.single = single;
}
}
And the blow is controller
and StudentForm to add information
after selected checkbox from form, I want to display all result to a view :
But until now, I still can't controller adding selected value into a listofSubject which I created for a student.
THe blow is the link of sample code which I am implementing :
https://dl.dropboxusercontent.com/u/11576807/spring-mvc-example.zip
Besides, I want to use a tag instead of submit button to redirect to result page.
And the system only allow user to select two options, at that time, the remain checkbox will be disabled.
Can you please share with me your solution in this case ?
Please tell me know the way to do it with the sample above.
Thanks
You already found the answer. Check stu.getListSubject(). All the checked items will populated to List by Spring MVC.
Your controller should look like this.
#RequestMapping(value = "/student/add", method = RequestMethod.POST)
public String addStudent(Student stu, ModelMap model){
for (String s: stu.getListSubject()) {
//You can see values populated
System.out.println("string: " + s);
}
model.addAttribute("name",stu.getName());
model.addAttribute("age", stu.getAge());
model.addAttribute("single", stu.isSingle());
model.addAttribute("listSubject", stu.getListSubject());
return "studentView";
}
And you have error in your studentView.jsp file.
Instead of this
<c:forEach items="listSubject" var="subject">
<td>${subject}</td>
</c:forEach>
use this:
<c:forEach items="${listSubject}" var="subject">
<td>${subject}</td>
</c:forEach>
You missed ${} .
I have a method which creates a new object Student and adds it to an array list studentRegister:
public void addStudent(String name, String age)
{
studentRegister.add(new Student(name, age));
}
it calls the Student class constructor here:
public Student(String name, String age)
{
this.name = name;
this.age = age;
}
This works but it is bad for maintainability as i have to change any additional parameters in both the Student class and the addStudent method. How do I input the parameters at the addStudent stage without having them harcoded in the addStudent method?
just do this:
public void addStudent(Student s)
{
studentRegister.add(s);
}
And in constructer/ other methods you can call the above method as below:
public Student(String name, String age)
{
this.name = name;
this.age = age;
addStudent(this); //here is the call to the above method
}
You should pass a student object - Instead of the two values.
public void addStudent(Student student)
{
studentRegister.add(student);
}
Using
public void addStudent(final Student student) {
studentRegister.add(student);
}
is the better aproach.
Maybe you're looking for a simpler way to build the object. e.g. using chain setters:
public class Student {
private String name;
private String age;
private String address;
public String getName() {
return name;
}
public Student setName(String name) {
this.name = name;
return this;
}
public String getAge() {
return age;
}
public Student setAge(String age) {
this.age = age;
return this;
}
public String getAddress() {
return address;
}
public Student setAddress(String address) {
this.address = address;
return this;
}
}
So, would then:
Student student = new Student().setName("User")
.setAge("30")
.setAddress("New York");
Another way for build the object with normal setters:
Student student = new Student(){{
setName("User");
setAge("30");
setAddress("30");
}};