Thymeleaf iterating through list of objects shows blank - java

I am trying to iterate through objects passed through ModelMap using Spring MVC. However, the text shows up blank when tested on browser. For example :
test.jsp :
<!DOCTYPE html>
<html>
<body>
Hello ${test}
<tr th:each="user,iterStat : ${testList}">
<td th:text="${user.id}" />
<td th:text="${user.name}" />
</tr>
</body>
</html>
Controller code :
#GetMapping("/test")
public String test(Model model) {
model.addAttribute("test", "Bob");
List<ChatUser> users = new ArrayList<>();
users.add(new ChatUser("asdf"));
users.add(new ChatUser("ewfasdf"));
model.addAttribute("testList", users);
return "test";
}
When loading up /test after deploying my webapp I would see Hello Bob, but nothing else. Checking the source of the webpage I see this :
<!DOCTYPE html>
<html>
<body>
Hello Bob
<tr th:each="user,iterStat : [com.mkyong.ChatUser#7a5dd809, com.mkyong.ChatUser#61f4628]">
<td th:text=""/>
<td th:text=""/>
</tr>
</body>
</html>
As seen in the th:each line, the objects are obviously being passed through properly. But the th:text is showing up just blank.
My ChatUser entity :
#Entity
public class ChatUser {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String name;
public ChatUser() {}
public ChatUser(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
What is the issue here?

Related

Thymeleaf + Spring Boot. I try to make dynamic fields, but when the button is pressed nothing happens at all

My Controller:
#Controller
public class MainController {
#GetMapping("/")
public String mainPage() {
return "main";
}
#RequestMapping(value = "/", params = {"addRow"})
public String addRow(ModelForCheck modelForCheck, BindingResult bindingResult) {
modelForCheck.getVariables().add(new Variable());
return "main";
}
}
My model class that I used to test my code:
public class ModelForCheck {
private List<Variable> variables = new ArrayList<>();
public List<Variable> getVariables() {
return variables;
}
public void setVariables(List<Variable> variables) {
this.variables = variables;
}
}
My model class:
public class Variable {
private String name;
private String type;
public Variable() {
}
public Variable(String name, String type) {
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
My html page (main.html):
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Hello!</title>
</head>
<body>
<form th:action="#{/}" method="post">
<h3>Variables:</h3>
<button type="submit" name="addRow">Add Row</button>
<table>
<tr th:each="variable, variableStat : *{variables}">
<td><input type="text" th:field="*{variables[__${variableStat.index}__].name}" placeholder="name"></td>
<td><input type="text" th:field="*{variables[__${variableStat.index}__].type}" placeholder="type..."></td>
</tr>
</table>
<br>
<input type="submit" value="Generate!">
</form>
</body>
</html>
enter image description here
I click on the "Add Row" button, but for some reason there is no reaction at all from the application. There are no error messages in the logs, nor any other messages. I know for sure that the "addRow" method is launched, since I checked it in the debug
I think It is doesn't work because you don't add modelForCheck to Thymeleaf model in addRow method in your controller.

Hibernate, MySQL, Spring MVC,Freemarker :java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax [duplicate]

This question already has answers here:
How to map an entity field whose name is a reserved word in JPA
(8 answers)
Closed 4 years ago.
I'm making simple Spring MVC library app, using Freemarker, MySQL and Hibernate,
i created form for adding new book to the library, it's code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Create new user</title>
</head>
<body>
<form name="booker" action="/newBook" method="post" >
<p>Name</p>
<input title="Name" type="text" name="name">
<p>Desc</p>
<input title="Email" type="text" name="desc">
<p>Author</p>
<input title="Age" type="text" name="aut">
<p>Year</p>
<input title="Age" type="text" name="year">
<input type="submit" value="OK">
</form>
</body>
</html>
Also i have Controller, BookDAO, BookService and Book entity
Controller:
#Controller
#RequestMapping("/")
public class BookController {
#Autowired
private BookService service;
#GetMapping("/books")
public String viewAll(Model model){
model.addAttribute("books",service.findAll());
return "books";
}
#GetMapping("/addBook")
public String addBook(){
return "createBook";
}
#PostMapping("/newBook")
public String newBooks(#ModelAttribute("booker") Book book){
service.add(book);
return "redirect:/books";
}
}
Entity:
#Table(name = "booker")
#Entity
public class Book {
private int id;
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
#Column(name = "idbooker")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private String name;
private String desc;
private String aut;
private int year;
#Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="desc")
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
#Column(name = "aut")
public String getAut() {
return aut;
}
public void setAut(String author) {
this.aut = author;
}
#Column(name = "year")
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
}
When i try to post new book, i get this exception, database columns' names are same can somebody tell how to fix it, ty.
Could be you have some issue with desc (reserved word) try using backtics
#Column(name="`desc`")

can't view records stored in DB in a web page

I'm referring to this guide (http://jvmhub.com/2015/08/09/spring-boot-with-thymeleaf-tutorial-part-3-spring-data-jpa/), the only difference is that i unified the classes PostEntity and Post assuming the name PostEntity.
When i try to store data in db through a form the applications works but it can't allow me to view stored data in a webpage as showed in the guide linked above.
The web page result.html is displayed as
"Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Jul 05 14:25:42 CEST 2018
There was an unexpected error (type=Internal Server Error, status=500).
Exception evaluating SpringEL expression: "PostEntity.title" (template: "result" - line 11, col 9)"
and the console shows the exception:
org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'title' cannot be found on null
It is throwed even with the other attributes (id and content) according to the order they are disposed in result.html.
If i try to print the content of records variable to the console it shows that it is not null so i can't figure out why there is this exception.
Controller:
#Controller
public class Home {
#Autowired private PostRepository postRepository;
#RequestMapping(value="/", method=RequestMethod.GET)
public String index(Model model) {
model.addAttribute("post", new PostEntity());
return "index";
}
#RequestMapping(value = "/", method = RequestMethod.POST)
public String addNewPost( PostEntity post, BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
return "index";
}
postRepository.save(post);
List<PostEntity> records = (List<PostEntity>) postRepository.findAll();
model.addAttribute("posts", records);
return "redirect:result";
}
#RequestMapping(value = "/result", method = RequestMethod.GET)
public String showAllPosts(Model model) {
List<PostEntity> records = (List<PostEntity>) postRepository.findAll();
for (PostEntity record : records) {
System.out.println(record);
}
model.addAttribute("posts", records);
return "result";
}
}
Model class:
#Entity
public class PostEntity {
public PostEntity() {}
public PostEntity(String title, String content) {
this.title = title;
this.content = content;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public int id;
public String title;
public String content;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
index:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot and Thymeleaf example</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h3>Spring Boot and Thymeleaf, part 2 - forms</h3>
<form action="#" th:action="#{/}" th:object="${post}" method="post">
<table>
<tr>
<td>Title:</td>
<td><input type="text" th:field="*{title}" /></td>
<td th:if="${#fields.hasErrors('title')}" th:errors="*{title}">Title error message</td>
</tr>
<tr>
<td>Content:</td>
<td><input type="text" th:field="*{content}" /></td>
<td th:if="${#fields.hasErrors('content')}" th:errors="*{content}">Content error message</td>
</tr>
<tr>
<td><button type="submit">Submit post</button></td>
</tr>
</table>
</form>
</body>
</html>
result
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot and Thymeleaf example</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h3>Spring Boot and Thymeleaf, part 3 - SPRING DATA JPA</h3>
<p th:each="PostEntity : ${posts}">
<h4>Title:</h4>
<div th:text="${PostEntity.title}"/></div>
<h4>ID:</h4>
<div th:text="${PostEntity.id}"/></div>
<h4>Content:</h4>
<div th:text="${PostEntity.content}"/></div>
<div>---------------------------------------------------------</div>
</p>
</body>
</html>
Any suggestions?
You are doing this redirect-thing. When doing this your objects added to the model doesn't reach the further process. I remember running into similar trouble.

Accessing Object in View with Thymeleaf

I have an customer object whose fields I'm trying to access in my view with Thymeleaf. I've used the usual syntax i.e:
<p th:text="${customer.name}"></p>
however, this does not work, it does work when I use the get() method i.e:
<p th:text="${customer.get.name}"></p>
Any idea why that is happening? I'm just getting started with Thymeleaf, so I apologize in advance if this is a dumb question.
Here's my Model:
#Id
#GeneratedValue
private int id;
#NotNull
#Size(min = 2, message="Company name length must be at least 1 character long.")
private String name;
public Customer() {}
public Customer(String name) {
this.name = 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;
}
And the Controller:
#RequestMapping("")
public String index(Model model) {
model.addAttribute("title", "Home");
model.addAttribute("customers", customerDao.findAllByOrderByNameAsc());
return "index";
}
#RequestMapping(value = "", method = RequestMethod.POST)
public String processFetch(#ModelAttribute Customer customer, Model model) {
model.addAttribute("title", "Home");
model.addAttribute("customers", customerDao.findAllByOrderByNameAsc());
model.addAttribute("c", customerDao.findById(customer.getId()));
return "index";
}
and the View:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head th:replace="fragments::head"></head>
<body>
<nav th:replace="fragments::nav"></nav>
<div class="container">
<h1 class="title" th:text="${title}"></h1>
</div>
<div style="text-align: center">
<form method="post" th:object="${customers}" style="display: block;margin: 0 auto;width:300px;margin-top:5%">
<select class="form-control" name="customer">
<option style="text-align:center" th:each="customer:${customers}" th:value="${customer.id}" th:text="${customer.name}"></option>
</select>
<input class="button" style="display:block;margin:0 auto;margin-top:30px" type="submit" value="Fetch" />
</form>
</div>
<div>
<h1 th:text="${c.get().name}"></h1>
</div>
</body>
</html>
Here's my Repository class:
public interface CustomerDao extends CrudRepository<Customer, Integer> {
public Iterable<Customer> findAllByOrderByNameAsc();
}
The error I try to submit the form is:
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'name' cannot be found on null
I'm not sure why it cannot find property 'name'. It should be part of the object.
I appreciate any insight into this!

Error with parsing on the view?

I try to make an web application that will conect with a repository on a server, and i want to print the data on the screen. Actually i try to create a RESTful client. Probably there is a parsing error that doesn't allow me to see the display data
My jsp is the following:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!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">
<title>Insert title here</title>
</head>
<body>
<h1>Get Author</h1>
<c:if test="${empty author}">
No records found!
</c:if>
<c:if test="${!empty author}">
<table style="border: 1px solid #333">
<tr>
<td style="width: 100px">Id</td>
<td>${data.id}</td>
</tr>
<tr>
<td>Name</td>
<td>${data.name}</td>
</tr>
<tr>
<td>Address</td>
<td>${data.address}</td>
</tr>
</table>
</c:if>
</body>
</html>
The controller is the following(i implement the controller with two different ways. The one of them is commented)
#Controller
public class Contraller {
protected static Logger logger = Logger.getLogger("controller");
private RestTemplate restTemplate = new RestTemplate();
#RequestMapping(value = "/datas", method = RequestMethod.GET)
public String getDatas(Model model) {
HttpEntity<Data> entity = new HttpEntity<Data>(headers);
// Send the request as GET
try {
ResponseEntity<DataList> result = restTemplate.exchange("http://www../data/",
HttpMethod.GET, entity, DataList.class);
// Add to model
model.addAttribute("datas", result.getBody().getData());
} catch (Exception e) {
}
// This will resolve to /WEB-INF/jsp/personspage.jsp
return "personspage";
}
/**
* Retrieves a single record from the REST provider
* and displays the result in a JSP page
*/
#RequestMapping(value = "/data", method = RequestMethod.GET)
public String getMyData(#RequestParam("id") Long id, Model model) {
try{
Data results = restTemplate.getForObject("http://www.../data/{id}",
Data.class, id);
model.addAttribute("data", results);
}catch(Exception e){
}
return "getpage";
}
The model:
#XmlRootElement(name = "data", namespace="http://www...")
#XmlAccessorType(XmlAccessType.FIELD)
public class Data {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setFirstName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
In the repository there are 4000 datas. When i give the following URL: localhost:8080/Client_for_rest/data?id=1
(all the id's from 1 to 4000) returns me the view but it doesn't display the data. If i give an id bigger than 4000, i.e. 4001 gives me back that there are no records which is true. According to this i suppose that the client connects with the server side but there is a problem(i suppose with parsing) that it doesn't allow the data to be dispayed on the view. I'm unfamiliar with the Spring MVC framework and i read something about marshaller and castor but i don't how to implement them. Actually i was wondering if there is an easier way to solve my problem. Do i have to use pojo maven dependencies etc?
if you method return type is string use map object and bindresult as the parameters to that method.
and add elements to that map object.
you can directly access that map object on your jsp page
as an example :
#RequestMapping("/locationUpdate.do")
public String locationUpdate(Map<String, Object> map,#ModelAttribute("location") Location location, BindingResult result) {
map.put("location", locationService.getLocationByCode(locationcode));
map.put("locGrp", listLocationGroup());
return "location/locationAdd";
}
now you can directly access location and locGrp in your jsp

Categories