spring MVC database display - spring

I have created a mySQL table: student.studentInfo with:-
Int id autofill PK,
String name,
int age,
String email.
User fills up a StudentRegForm and The values of name, age and email are shown on a RegisteredStudent jsp.
I want to display contents [data elements] of the mySQL table on a jsp page.
My StudentDaoImpl:
public class StudentDaoImpl implements StudentDao {
DataSource datasource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource datasource) {
this.datasource = datasource;
this.jdbcTemplate = new JdbcTemplate(datasource);
}
#Override
public List<Student> getStudentList() {
List<Student> studentList = new ArrayList<Student>();
String sql = "select * from student.studentInfo";
JdbcTemplate jdbcTemplate = new JdbcTemplate(datasource);
studentList = jdbcTemplate.query(sql, new StudentMapper());
return studentList;
}
}
The above StudentMapper method is:
public class StudentMapper implements RowMapper<Student>{
#Override
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setId( rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
student.setEmail(rs.getString("email"));
return student;
}
}
View Resolver is set on MvcConfiguration and DataSource props are declared as #Bean:
#Configuration
#ComponentScan(basePackages = "com.anand")
#EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
"/resources/");
}
#Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/student");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
}
Students fill up this Studentform.jsp:
<form action="StudentAddSuccess.htm" method=post>
${formHeading}
<p>
id <input type="text" name="id" />
</p>
<p>
Name <input type="text" name="name"/>
</p>
<p>
Age <input type="text" name="age" />
</p>
<p>
Email <input type="text" name="email" />
</p>
<p>
<input type="submit" name="submit" value="save">
</p>
</form>
Controller class is:
#Controller
public class StudentController {
#Autowired
StudentDao stdDao;
#RequestMapping(value = "/studentForm.htm", method = RequestMethod.GET)
public ModelAndView sendStudentForm() {
ModelAndView mav = new ModelAndView("studentForm");
mav.addObject("formHeading", "Student Registration Form");
mav.setViewName("studentForm");
System.out.println("student Form");
return mav;
}
//**********************************************************
#RequestMapping(value = "RegdSuccess", method = RequestMethod.POST)
public ModelAndView addStudent(#ModelAttribute("student1") Student student1) {
ModelAndView mav = new ModelAndView();
//mav.addObject("studentId", "id is:-" + student1.getId());
mav.addObject("studentName", " name is:- " + student1.getName());
mav.addObject("studentAge", " age is:-" + student1.getAge());
mav.addObject("studentEmail", "student email is:-" + student1.getEmail());
// mav.addObject("student", "student list is"+ student1);
System.out.println(" hello from RegdSuccess");
mav.setViewName("RegdSuccess");
return mav;
}
//********************************************************************
#RequestMapping( value = "RegdStudent", method = RequestMethod.GET)
public ModelAndView showStudent(#ModelAttribute("std")Student std) throws IOException{
ModelAndView mav = new ModelAndView();
List<Student> listStudent= stdDao.getStudentList();
mav.addObject("msg", "hello from Regd jsp");
//mav.addObject("listStudent", listStudent);
mav.addObject("msg",""+listStudent);
System.out.println(" hello from Regd Students controller"+std.getName());
mav.setViewName("RegdStudent");
return mav;
}
StudentDao is:
public interface StudentDao {
// create
public void createStudent(Student student);
// read
public Student getStudent(Integer id);
// Update
public void updateStudent(Student student);
// delete
public void deleteStudent(Integer id);
// List
public List<Student> getStudentList();
// save
public void save(Student student);
}
And StudentImplDao is:
public class StudentDaoImpl implements StudentDao {
StudentDaoImpl StudentDao;
DataSource datasource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource datasource) {
this.datasource = datasource;
this.jdbcTemplate = new JdbcTemplate(datasource);
}
public void doExecute() {
String sql = "SELECT * FROM STUDENT.StudentInfo";
SqlRowSet srs = jdbcTemplate.queryForRowSet(sql);
int rowCount = 0;
while (srs.next()) {
System.out.println(srs.getString("id") + "-"
+ srs.getString("name") + "-" + srs.getString("age") + "-"
+ srs.getString("email"));
}
rowCount++;
System.out.println("Number of records" + rowCount);
}
// -------------List----------------------------------------
#Override
public List<Student> getStudentList() {
List<Student> studentList = new ArrayList<Student>();
String sql = "select * from student.studentInfo";
JdbcTemplate jdbcTemplate = new JdbcTemplate(datasource);
studentList = jdbcTemplate.query(sql, new StudentMapper());
return studentList;
}
// other remaining methods of StudentDao go here for the implementations
//………………………………
}
I can input name, age, email on the Studentform.jsp and those inputs are displayed on RegdSuccess.jsp, but my RegdStudent.jsp page is not displaying list records from my database as I want it to. RegdStudent.jsp is:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<head>
<title>Regd. Students</title>
</head>
<body>
hello from Regd Students jsp
<form:form>
<table>
<c:forEach items="${msg}" var="employee">
<tr>
<td><c:out value="${employee.id}" /></td>
<td><c:out value="${employee.name}" /></td>
<td><c:out value="${employee.age}" /></td>
<td><c:out value="${employee.email}" /></td>
</tr>
</c:forEach>
</table>
</form:form>
</body>
</html>
I would like to have this JSP age show all the records from the mysql database.

By doing
mav.addObject("msg",""+listStudent);
you're coercing the listStudent List to a string, making it impossible to iterate over it later in your JSP. If you change the line to:
mav.addObject("msg", listStudent);
the ${msg} object will be an iterable list.
It seems that you have no idea what works and what doesn't in your application since you dumped code for all layers. You should familiarise yourself with your IDE's debugger and learn to follow request's path to see what's going on. Narrowing down the problem drastically reduces time needed to find and fix bugs.

Related

Add student without avatar

I created a project where you can add a student with an avatar and without an avatar. The problem is that when I add a student without an avatar, there is still a tag. How can I remove the tag. Now I will add an image and a couple of classes. I kind of wrote everything correctly, I don’t know where the error might be
#Controller
public class AvatarController {
#Value("${storage.location}")
private String storageLocation;
private StudentService studentService;
#Autowired
private ServletContext servletContext;
// Constructor based Dependency Injection
#Autowired
public AvatarController(StudentService studentService) {
this.studentService = studentService;
}
#GetMapping(value = "/avatar")
public void getAvatar(HttpServletResponse response, #Param("avatar") String avatar) {
if (avatar == null || avatar.isEmpty()) {
return;
}
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
try (FileInputStream input = new FileInputStream(studentService.loadAvatarByFileName(avatar))){
IOUtils.copy(input, response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
#RequestMapping(value = "/image", method = RequestMethod.GET)
public void image(#RequestParam String url, HttpServletResponse response) throws IOException {
InputStream in = new FileInputStream(url);
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
IOUtils.copy(in, response.getOutputStream());
}
}
Student Service Impl
#Service
#Transactional
public class StudentServiceImpl implements StudentService {
#Value("${storage.location}")
private String storageLocation;
private StudentRepository repository;
public StudentServiceImpl() {
}
#Autowired
public StudentServiceImpl(StudentRepository repository) {
super();
this.repository = repository;
}
#Override
public List<Student> getAllStudents() {
List<Student> list = new ArrayList<Student>();
repository.findAll().forEach(e -> list.add(e));
return list;
}
#Override
public Student getStudentById(Long id) {
Student student = repository.findById(id).get();
return student;
}
#Override
public boolean saveStudent(Student student) {
try {
repository.save(student);
return true;
} catch (Exception ex) {
return false;
}
}
#Override
public boolean deleteStudentById(Long id) {
try {
repository.deleteById(id);
return true;
} catch (Exception ex) {
return false;
}
}
#Override
public File loadAvatarByFileName(String filename) {
return new File(storageLocation + "/" + filename);
}
#Override
public File saveAvatarImage(MultipartFile avatarImage) throws IOException {
File newFile = File.createTempFile(
avatarImage.getName(),
"." + avatarImage.getOriginalFilename().split("\\.")[1],
new File(storageLocation));
avatarImage.transferTo(newFile);
return newFile;
}
#Override
public Student updateStudent(String name, String surname, MultipartFile avatar, Student targetStudent)
throws IOException {
if (name != null && !name.equals(targetStudent.getName())) {
targetStudent.setName(name);
}
if (surname != null && !surname.equals(targetStudent.getSurname())) {
targetStudent.setSurname(surname);
}
File newAvatar;
if (!avatar.getOriginalFilename().isEmpty()) {
if (targetStudent.getAvatar() != null) {
Files.deleteIfExists(Paths.get(storageLocation + File.separator + targetStudent.getAvatar()));
}
newAvatar = saveAvatarImage(avatar);
assert newAvatar != null;
targetStudent.setAvatar(newAvatar.getName());
}
boolean isSaved = saveStudent(targetStudent);
if (!isSaved) {
throw new IOException();
}
return targetStudent;
}
}
Student Controller
#Controller
public class StudentController {
#Autowired
private ServletContext servletContext;
// Constructor based Dependency Injection
private StudentService studentService;
public StudentController() {
}
#Autowired
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
#RequestMapping(value = "/allStudents", method = {RequestMethod.GET, RequestMethod.POST})
public ModelAndView displayAllUser() {
System.out.println("User Page Requested : All Students");
ModelAndView mv = new ModelAndView();
List<Student> studentList = studentService.getAllStudents();
mv.addObject("studentList", studentList);
mv.setViewName("allStudents");
return mv;
}
#Secured("ROLE_ADMIN")
#RequestMapping(value = "/allStudentsAdmin", method = {RequestMethod.GET, RequestMethod.POST})
public ModelAndView displayAllUsers() {
System.out.println("User Page Requested : All Students");
ModelAndView mv = new ModelAndView();
List<Student> studentList = studentService.getAllStudents();
mv.addObject("studentList", studentList);
mv.setViewName("allStudentsUser");
return mv;
}
#Secured("ROLE_USER")
#RequestMapping(value = "/allStudentsUser", method = {RequestMethod.GET, RequestMethod.POST})
public ModelAndView displayAllUsers() {
System.out.println("User Page Requested : All Students");
ModelAndView mv = new ModelAndView();
List<Student> studentList = studentService.getAllStudents();
mv.addObject("studentList", studentList);
mv.setViewName("allStudentsUser");
return mv;
}
#RequestMapping(value = "/addStudent", method = RequestMethod.GET)
public ModelAndView displayNewUserForm() {
ModelAndView mv = new ModelAndView("addStudent");
mv.addObject("headerMessage", "Add Student Details");
mv.addObject("student", new Student());
return mv;
}
#PostMapping(value = "/addStudent")
public String saveNewStudent(#RequestParam("name") #NonNull String name,
#RequestParam("surname") #NonNull String surname,
#RequestParam("avatar") MultipartFile file)
throws IOException {
Student student = new Student();
student.setSurname(surname);
student.setName(name);
if (file != null && !file.isEmpty()) {
student.setAvatar(studentService.saveAvatarImage(file).getName());
}
studentService.saveStudent(student);
return "redirect:/allStudents";
}
#GetMapping(value = "/editStudent/{id}")
public ModelAndView displayEditUserForm(#PathVariable Long id) {
ModelAndView mv = new ModelAndView("editStudent");
Student student = studentService.getStudentById(id);
mv.addObject("headerMessage", "Редактирование студента");
mv.addObject("student", student);
return mv;
}
#PostMapping(value = "/editStudent")
public String saveEditedUser(
#RequestParam("id") Long id,
#RequestParam("name") String name,
#RequestParam("surname") String surname,
#RequestParam("avatar") MultipartFile file) {
try {
studentService.updateStudent(name, surname, file, studentService.getStudentById(id));
} catch (FileSystemException ex) {
ex.printStackTrace();
} catch (IOException e) {
return "redirect:/error";
}
return "redirect:/allStudents";
}
#GetMapping(value = "/deleteStudent/{id}")
public ModelAndView deleteUserById(#PathVariable Long id) {
studentService.deleteStudentById(id);
ModelAndView mv = new ModelAndView("redirect:/allStudents");
return mv;
}
}
AllStudent JSP
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<link href="../css/style.css" rel="stylesheet" type="text/css">
<style><%#include file="/css/style.css"%></style>
<title>Все студенты</title>
</head>
<body>
<br>
<br>
<br>
<br>
<div class="it">
<h3>Список всех студентов</h3>
${message}
<br>
<br>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Surname</th>
<th scope="col">Avatar</th>
</tr>
</thead>
<tbody>
<c:forEach var="student" items="${studentList}">
<tr>
<th scope="row">1</th>
<td>${student.name}</td>
<td>${student.surname}</td>
<td><c:choose>
<c:when test="${student.avatar ne null}">
<td>
<img src="${pageContext.request.contextPath}/avatar?avatar=${student.avatar}"
style="max-height: 200px; max-width: 200px;" />
</td>
</c:when>
</c:choose></td>
<td>
<sec:authorize access="hasRole('ADMIN')">
<a href="${pageContext.request.contextPath}/editStudent/${student.id}">
<button type="button" class="btn btn-primary">Edit</button>
</a>
</sec:authorize>
</td>
<td>
<sec:authorize access="hasRole('ADMIN')">
<a href="${pageContext.request.contextPath}/deleteStudent/${student.id}">
<button type="button" class="btn btn-primary">Delete</button>
</a>
</sec:authorize>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</body>
</html>
#user404 answer ok but need some change
<c:choose>
<c:when test="${student.avatar ne null}">
<td>
<img src="${pageContext.request.contextPath}/avatar?avatar=${student.avatar}"
style="max-height: 200px; max-width: 200px;" />
</td>
</c:when>
<c:otherwise>
<td></td>
</c:otherwise>
</c:choose>
despription : When avater is null or empty then add a empty cell on
our html table other wise add image with full src path
You have to check the condition if your student.avatar holds avatar or null and based on that, show your image or not. Coz, that image tag for empty avatar your see because of img tag. You can use if-else condition in jstl or like this.
try this:
<c:choose>
<c:when test="${student.avatar ne null}">
<td>
<img src="${pageContext.request.contextPath}/avatar?avatar=${student.avatar}"
style="max-height: 200px; max-width: 200px;" />
</td>
</c:when>
<c:otherwise>
<td></td>
</c:otherwise>
</c:choose>

Spring + Thymeleaf type Converter in a form

I'm trying to use a type converter in a Spring boot app and using Thymeleaf but I can't get it working. I've put some code on Github so you can see exactly what I'm trying to do. This is Spring 1.5.1 and Thymeleaf 3.0.3. https://github.com/matthewsommer/spring-thymeleaf-simple-converter
Basically this code is just trying to add a person to a comment object. The person object is null when it gets posted and I don't understand why.
Something that's odd is that the ID of the person isn't being added to the value attribute but it is if th:field="*{body}" is removed. I think it has to do with this: https://github.com/thymeleaf/thymeleaf/issues/495 but I'm currently trying to add BindingResult and it's not working...
My HTML is:
<body>
<div th:if="${personObject != null}" th:text="${personObject.name}"></div>
<form th:action="#{/}" th:object="${comment}" method="post">
<input type="hidden" th:if="${personObject != null}" th:value="${personObject.id}" th:field="*{person}" />
<textarea id="comment" placeholder="Comment..." th:field="*{body}"></textarea>
<button id="comment_submit" type="submit">Comment</button>
</form>
<div th:text="${comment.body}"></div>
</body>
My controller:
#Controller
public class HomeWebController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String getHome(final HttpServletRequest request, final Map<String, Object> model, #ModelAttribute(value = "comment") Comment comment) {
model.put("personObject", new Person(1, "John Smith"));
return "Home";
}
#RequestMapping(value = "/", method = RequestMethod.POST)
public String postHome(final HttpServletRequest request, final Map<String, Object> model, #ModelAttribute(value = "comment") Comment comment) {
model.put("commentBody", comment.getBody());
model.put("person", comment.getPerson());
return "Home";
}
}
And the converter:
#Component
public class StringToPersonConverter implements Converter<String, Person> {
#Autowired
public StringToPersonConverter() { }
#Override
public Person convert(String id) {
if(id == "1") {
Person person = new Person(1, "John Smith");
return person;
}
return null;
}
}
Hi finally I had to do some changes to make it work, but this is the result class by class.
ConvertorApplication:
#SpringBootApplication
#Configuration
#EnableWebMvc
public class ConvertorApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(ConvertorApplication.class, args);
}
//Add converter and configuration annotation
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToPersonConverter());
}
}
StringToPersonConverter:
#Override
public Person convert(String id) {
//Never compare String with == use equals, the "==" compares memory space not the values
if(id.equals("1")) {
Person person = new Person(1, "John Smith");
return person;
}
return null;
}
HomeWebController
#Controller
public class HomeWebController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String getHome(final Map<String, Object> model, #ModelAttribute(value = "comment") Comment comment) {
//Initialize the comment with the person inside, no need of personObject object
model.put("comment", new Comment(new Person(1, "John Smith")));
return "Home";
}
#RequestMapping(value = "/", method = RequestMethod.POST)
public String postHome(final Map<String, Object> model,
#ModelAttribute(value = "comment") Comment comment,
#RequestParam(value = "person.id") Person person) {
//from the view retrieve the value person.id which will be used by the converter to build the Person entity
comment.setPerson(person);
model.put("comment", comment);
return "Home";
}
}
Comment (Add empty constructor)
public Comment(){}
Person (Add empty constructor)
public Person(){}
Home.jsp (Basically remove personObject, not need)
<!DOCTYPE html>
<html xmlns:th="//www.thymeleaf.org">
<body>
<div th:text="${comment.person.name}"></div>
<form th:action="#{/}" th:object="${comment}" method="post">
<input type="hidden" th:field="*{person.id}" />
<textarea id="comment" placeholder="Comment..." th:field="*{body}"></textarea>
<button id="comment_submit" type="submit">Comment</button>
</form>
<div th:text="${comment.body}"></div>
</body>
</html>
That's would be everything to make it work.

JSTL Items not getting displayed

have a very simple question on JSTL tags.
I am using spring to fetch data from back-end and display in the JSP.
Have the following code. I am getting the items of the for each tag printed in the console. But the same items are not getting printed/displayed inside the table rows.
<table id="table_id" class="display">
<thead>
<tr>
<th>Movie Name</th>
<th>Movie Rating</th>
</tr>
</thead>
<tbody>
<c:forEach items="${model.movieslist}" var="movie">
<tr>
<td>${movie.name}</td>
<td>${movie.rating}</td>
</tr>
</c:forEach>
</tbody>
My spring controller class
public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// TODO Auto-generated method stub
logger.info("returning hello view");
List<Movie> moviesList = DbManager.getInstance().getMovies();
ModelMap modelMap = new ModelMap();
modelMap.addAttribute("movieslist", moviesList);
return new ModelAndView("hello.jsp",modelMap);
}
Movie domain class
package springapp.domain;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "movie")
public class Movie {
#Id
public String _id;
public String name;
public String getId() {
return _id;
}
public void setId(String _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getRating() {
return rating;
}
public void setRating(float rating) {
this.rating = rating;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public float rating;
public String date;
#Override
public String toString() {
// TODO Auto-generated method stub
return name;
}
}
First, your jsp should contain the following taglib
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Second, you don't need to get it using ${model.moviesList}, modify it as follows:
<c:forEach items="${movieslist}" var="movie">

What is the purpose of spring model addObject(Object attributeName)?

In spring mvc, when creating a ModelAndView there's a method called addObject(Object attributeName) single parameter, and I don't understand how to make use of it. I also see model.addAllObjects(Map<String, ?> object).
How can I get that map in jsp? Or what is the purpose of those methods? I only know how to make use of model.addObject("car", new Car()) because is like defining servlet parameters. I found this information in spring but I don't really understand it.
Spring addObject and addAllObjects
please check the example below. i have shed how to use addObject(Object attributeValue) as well as addAllObjects(Map<String, ?> modelMap).
Car.java
public class Car {
private String regNo;
private String model;
private String year;
public String getRegNo() {
return regNo;
}
public void setRegNo(String regNo) {
this.regNo = regNo;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
}
PageContent.java
public class PageContent {
private String headerName;
public String getHeaderName() {
return headerName;
}
public void setHeaderName(String headerName) {
this.headerName = headerName;
}
}
Controller Method
#RequestMapping(value = "/showCars", method = RequestMethod.GET)
public ModelAndView showApp() {
ModelAndView modelAndView = new ModelAndView();
//adding a single attribute for the modelMap
PageContent pageContent = new PageContent();
pageContent.setHeaderName("All Cars - From Controller");
modelAndView.addObject(pageContent);
List<Car> carList = new ArrayList<>();
Car car1 = new Car();
car1.setModel("Toyota");
car1.setRegNo("223456");
car1.setYear("2005");
Car car2 = new Car();
car2.setModel("Mazda");
car2.setRegNo("24244");
car2.setYear("2015");
Car car3 = new Car();
car3.setModel("Nissan");
car3.setRegNo("4465757");
car3.setYear("2013");
carList.add(car1);
carList.add(car2);
carList.add(car3);
Map<String,Object> allObjectsMap = new HashMap<String,Object>();
allObjectsMap.put("allCarObjects", carList);
//adding a set of objects for the model map
modelAndView.addAllObjects(allObjectsMap);
modelAndView.setViewName("CarView");
return modelAndView;
}
CarView.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<title>ModelAttribute Example</title>
</head>
<body>
<h1>${pageContent.headerName}</h1>
<table>
<tr>
<th>Model</th>
<th>Registration No</th>
<th>Year of Manufacture</th>
</tr>
<c:forEach var="car" items="${allCarObjects}">
<tr>
<td><c:out value="${car.model}" /></td>
<td><c:out value="${car.regNo}" /></td>
<td><c:out value="${car.year}" /></td>
</tr>
</c:forEach>
</table>
</body>
</html>
Hope this will helpful for you!
well,the first method addObject which would invoked when forward happend and brings the data to jsp.Then you can iterate the data in your jsp with jstl or something else.The method addAllObjects is just a multiple type of addObject,just like map's method put and putAll.

Spring MVC test failure

I'm writing simple integration tests for my app using the Spring MVC Test framework. I have two basic test cases:
The Add link form is filled in correctly (the URL and optional description input fields are entered) and a link is added to a database via POST and then the client is redirected to the /link URL.
The Add link form is empty, so the /links/create view is rendered and form errors from BindingResult are presented.
The testAddLink() test passes successfully, but the problem occurs with the testAddEmptyLink() test method.
In this test, the 'links/create' view should be rendered and I should get a 200 status code once the expression
result.hasErrors()
is true.
However, I'm getting a 302 response, which should be sent when there are no errors in the form (the URL has been set correctly)
It seems the test method testAddEmptyLink() cannot deal with form errors with BindingResult.
Do you have any ideas what could be the cause it cannot deal with form errors?
Thanks in advance.
Link Entity
#Entity
#Table(name = "links")
public class Link {
#Id #GeneratedValue
private Integer ID;
#Column(name = "url") #NotNull #NotEmpty #URL
private String URL;
private String description;
#Column(name="created_at", nullable = false)
#Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime createdAt;
#Column(name="updated_at", nullable = true)
#Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime updatedAt;
#ManyToOne
#JoinColumn(name = "category_id")
private Category category;
public Integer getID() {
return ID;
}
public void setID(Integer ID) {
this.ID = ID;
}
public String getURL() {
return URL;
}
public void setURL(String URL) {
this.URL = URL;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdateddAt() {
return updatedAt;
}
public void setUpdateddAt(LocalDateTime updateddAt) {
this.updatedAt = updateddAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}
LinkController
#Controller
public class LinkController {
#Autowired(required = true) #Qualifier(value = "linkService")
private LinkService linkService;
#Autowired
private CategoryService categoryService;
#RequestMapping(value = "/links")
public String getLinks(Model model) {
model.addAttribute("results", linkService.getLinks());
return "links/index";
}
#RequestMapping(value = "/links/create", method = RequestMethod.GET)
public ModelAndView showLinkForm() {
ModelAndView model = new ModelAndView("links/create");
model.addObject("link", new Link());
model.addObject("categories", categoryService.getCategories());
return model;
}
#RequestMapping(value = "/links/create", method = RequestMethod.POST)
public String addLink(#Valid #ModelAttribute("link") Link link, BindingResult result, Model model) {
if (result.hasErrors()) {
model.addAttribute("categories", categoryService.getCategories());
return "links/create";
}
linkService.addLink(link);
return "redirect:/links";
}
}
LinkControllerTest
#ContextConfiguration(classes = {AppInitializer.class})
#RunWith(SpringJUnit4ClassRunner.class)
public class LinkControllerTest {
#Mock
private LinkService linkService;
#InjectMocks
private LinkController linkController;
private MockMvc mockMvc;
#Before
public void setUp() {
// Process mock annotations
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(linkController).build();
}
#Test
public void testAddLink() throws Exception {
mockMvc.perform(post("/links/create")
.param("URL", "http://test.com")
.param("description", "Lorem Ipsum")
.param("category.ID", "1"))
.andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/links"));
}
#Test
public void testAddEmptyLink() throws Exception {
mockMvc.perform(post("/links/create")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.sessionAttr("link", new Link())
)
.andExpect(status().isOk())
.andExpect(view().name("links/create"))
.andExpect(forwardedUrl("/WEB-INF/views/links/create.jsp"))
.andExpect(model().attributeHasFieldErrors("link", "URL", "description"))
.andExpect(model().attribute("link", hasProperty("URL", isEmptyOrNullString())))
.andExpect(model().attribute("link", hasProperty("description", isEmptyOrNullString())));
}
}
create.jsp (View)
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Create Category</title>
</head>
<body>
<form:form action="" modelAttribute="category">
<div>
<form:label path="name">Name</form:label>
<form:input path="name" />
<form:errors path="name" cssClass="error"></form:errors>
</div>
<div>
<form:label path="description">Description</form:label>
<form:input path="description" />
<form:errors path="description" cssClass="error"></form:errors>
</div>
<div>
<input type="submit" value="Create Category">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</div>
</form:form>
</body>
</html>

Resources