Howto integrate Jasper HTML Report in Spring View (Conceptional) - spring

Howto integrate Jasper HTML Report in Spring View (Conceptional)
I would like to create a kind of dashboard in my Spring framework Application.
I have a view (jsp) and would like to include Jasper Report HTML/Pie Chart Image Output ( in my html sample) in a specific part of my produced HTML Page.
Is this possible to do ? If yes. Will the report be generated in the controller and sent to the view by ModelView ?
My View (dashboard.jsp) looks like this (sample):
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<h2>Key Figures</h2>
<table border=1 width=700>
<tbody>
<tr> <Navigation Items like Buttons and Tabs> </tr>
<tr height=200>
<td><c:forEach var="listValue" items="${lists}">
<li>${listValue}</li>
</c:forEach>
</td>
<td>Other Content from the Model</td>
</tr>
<tr height=200>
<td><My Pie Chart 1></td>
<td><My Pie Chart 2></td>
</tr>
</tbody>
</table>
</body>
</html>

Related

Why i am unable to launch Thymeleaf Template with springboot application?

I am using IntelliJ IDEA community Edition 2020.1.2 x64 and written a program using Spring DataJPA and Thymeleaf,there is no problem with my code and i am not getting error but when i am passing URL which i mapped in controller class i am unable to get desired result i.e the thymeleaf template which i have created is not displayed on browser.
I am posting the controller class,thymeleaf template and output which i am getting on browser to make you clear:-
controller class:
#RestController
#RequestMapping("/ecommerce")
public class EmployeeController {
#Autowired
private ProductService productService;
#GetMapping("/available")
public String ShowAllProducts(Model model)
{
model.addAttribute("listProducts",productService.getAllProducts());
return "availableProducts";
}
}
Thymeleaf template:-
<!DOCTYPE html>
<html xmlns:th="html://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>AvailableProducts</title>
</head>
<body>
<div align="center">
<h1>Product List</h1>
<table>
<thead>
<tr>
<th>p_id</th>
<th>ProductName</th>
<th>Productcost</th>
<th>QuantityAvailable</th>
</tr>
</thead>
<tbody>
<tr th:each="product : ${listProducts}">
<td th:text="${product.productId}"></td>
<td th:text="${product.productName}"></td>
<td th:text="${product.productCost}"></td>
<td th:text="${product.quanityAvailable}"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Output on browser:-
Dependency added:-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
application.properties:-
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ecommerce
spring.datasource.username=root
spring.datasource.password=deep
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto= update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.thymeleaf.prefix=classpath*:/templates/
spring.thymeleaf.check-template-location=true
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.mode=HTML5
At last when i am passing url http://hocalhost:8080/ecommerce/available what i am seeing in console is,hibernate is accessing the database every time.
Thanks in advance..
Please help i am stuck and don't know what i am doing wrong and not able to figure out on my own..
In your case seems like controller is just returning string "availableProducts" and its not resolving as thymleaf template. you can just return some dummy name("availableProductsTest") and you will see same(availableProductsTest) on the web page.
Did you referred to sample https://spring.io/guides/gs/serving-web-content/
Sample code is available here .. git clone https://github.com/spring-guides/gs-serving-web-content.git
if you just add your product class and modify the Greetings contoller like below then you can see its working!
#GetMapping("/greeting")
public String greeting(#RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
List<Products> productList= new ArrayList<>();
Products product = new Products("productId","ProductName", "ProductCost", "ProductQtyAvlb");
productList.add(product);
model.addAttribute("listProducts",productList);
return "greeting";
}
Also modify greetings template as below
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'Hello, ' + ${name} + '!'" />
<div align="center">
<h1>Product List</h1>
<table>
<thead>
<tr>
<th>p_id</th>
<th>ProductName</th>
<th>Productcost</th>
<th>QuantityAvailable</th>
</tr>
</thead>
<tbody>
<tr th:each="product : ${listProducts}">
<td th:text="${product.productId}"></td>
<td th:text="${product.productName}"></td>
<td th:text="${product.productCost}"></td>
<td th:text="${product.quanityAvailable}"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Hope this Helps! Happy Coding
Web reference: https://spring.io/guides/gs/serving-web-content/
Whenever you get Whitelabel Error Page you will have details about error listed on same page also same details can be seen in server logs or on console of the application.
For example if i use wrong template name in controller then i see below:
2020-07-28 22:35:51.031 ERROR 19572 --- [nio-8080-exec-1] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-1] Exception processing template "greeting1": Error resolving template [greeting1], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [greeting1], template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]

How to Load Data From a Json Using Thymeleaf Template

I have a rest api returns a Json value as a Output of the service call.
eg:- https://localhost:8080/getEmployees/loadAll
this returns following json values
eg:-
{
"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]
}
I need to load the following json values to my thymeleaf table.
In normal way returning values in controller using modal in spring can retun values as list like following.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Employee List</title>
</head>
<body>
<h1>Welcome</h1>
<br>
<h3>Employee List</h3>
<br />
<table border="1">
<tr>
<td>Employee First Name</td>
<td>Employee Last Name</td>
</tr>
<tr th:each="emp : ${empList}">
<td th:text="${emp.firstName}">First Name</td>
<td th:text="${emp.name}">Last Name</td>
</tr>
</table>
</body>
</html>
is there a way to accomplish this using above json using thymeleaf?
You can do something like that using the following structure.
When you call the service
https://localhost:8080/getEmployees/loadAll
you will need to pass the employees data using model.addAttribute.
For instance, let's say you have the following method:
#RequestMapping(value="/getEmployees/loadAll")
String getAllEmployees(Model model) {
model.addAttribute("empList", <your service here that generates the data>);
return "pagenamehere";
}
The above method, will only be executed when you make a call using the following url: https://localhost:8080/getEmployees/loadAll
and it will add your empList data as an attribute. Then, the return string indicates the name of the page that will load. You will need to use your own page with the thymeleaf code.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Employee List</title>
</head>
<body>
<h1>Welcome</h1>
<br>
<h3>Employee List</h3>
<br />
<table border="1">
<tr>
<td>Employee First Name</td>
<td>Employee Last Name</td>
</tr>
<tr th:each="emp : ${empList}">
<td th:text="${emp.firstName}">First Name</td>
<td th:text="${emp.lastNname}">Last Name</td>
</tr>
</table>
</body>
</html>
Now, thymeleaf will be able to display the given data.
I think that you are a little confused. Thymeleaf templates are compiled on server side generating html code. Then, no thymeleaf code found on client side.
The json data got of the api response is generated on client side.
One way is use javascript to load the api response data into a html table.
Another way can you take is modify the controller that calls to the thymeleaf template to get the JSon value. If you store this response (on an object List named empList on your example) yo can add the object into the Controller response (Model or ModelAndView objects) as a template attribute.

Why is <c:forEach> not working with Ajax request in JSP Spring?

I am fetching some data with a Ajax request in my main JSP page.
Snippet of main.jsp
function gu(){
$.get('/admin/getAllUsers', {}, function(data) {
console.log(data); // see below
$("#allUsersData").html(data);
});
}
In my Spring controller I add all the users to a different JSP page.
Snippet of MainController.java
#RequestMapping(value = "/admin/getAllUsers", method = RequestMethod.GET)
public String getAllUsers(Model model){
List<User> users = userRepository.findAll();
System.out.println(users.size()); // output: 3
model.addAttribute("allUsers", users);
return "data/all-users";
}
Now in all-users.jsp I have a <c:forEach> which is supposed to load all users in a html table:
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<c:if test="${not empty allUsers}">
<c:forEach items="${allUsers}" var="usr">
<tr>
<td>${usr.firstName}</td>
<td>${usr.lastName}</td>
<td>${usr.username}</td>
<td>${usr.creationDate}</td>
</tr>
</c:forEach>
</c:if>
</tbody>
</table>
However, when I add the html coming from the request to my main JSP page, an empty table is shown. When I log the result of the Ajax request I find that the user data is inserted in the all-users.jsp:
<c:if test="true">
<c:forEach items="[User{id=1, username='username1', firstName='John', lastName='Doe', roles=[Role{id=1, name='ROLE_USER'}], creationDate=2018-02-19T08:58:13.333}, User{id=2, username='username2', firstName='John2', lastName='Doe2', roles=[Role{id=3, name='ROLE_USER'}], creationDate=2018-02-19T08:58:13.471}]" var="usr">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</c:forEach>
</c:if>
Why is it happening that the data is loaded into the data JSP page, but not shown when appending it to the main JSP page?
Can you check, maybe you haven't included the core tag library in your JSP file.
You will do this by inserting the following Line at the top of your file.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<JSP> Stuck on Onclick mehot d with Ajax

I have a code as following;
JSP
<script type="text/javascript">
fnSelGrp = function(year)
$('#name').val(nm);
};
</script>
<table id = "One">
<tr> <td>onclick="fnSelGrp('${result.name}')">${result.name}</td> </tr>
</table>
<table id="Two">
<tr> <td> "HELLO" </td> </tr>
</table>
When I click on 'name', I want the table 'Two' to be disappeared and replace it with other JSP page, using AJAX.
It seems I should give 'fnSelGrp' an ID to make onClick function.
Can anyone help?
It looks like you are using jquery, so ensure that your jquery libraries are included before the <script> tag.
<script src="js/jquery-1.8.3.js" type="text/javascript"></script>
The code
$('#name').val(nm);
means set the value of the element with the ID name with nm
You do not have a element with the ID name

Dynamic Spring form action

I am trying to create a form in Spring MVC.
I would like to set action attribute of the <form> element dynamically using scriplet or something else.
MyForm:
<form:form id="myForm" modelAttribute="myFormBean"
action="<%=baseUrl%>/myFormControllerPattern" name="myForm">
<fieldset>
<table>
<tr>
<th>Name</th>
<td><form:input path="name" /></td>
</tr>
<tr>
<th>Age</th>
<td><form:input path="age"/></td>
</tr>
</table>
</fieldset>
</form:form>
Error:
attribute for %>" is not properly terminated
Found the solution. Thanks to jelies.
Added baseUrl in my controller like this:
model.setAttribute("baseUrl",url);
and then used it in my form in JSP:
<form action="${baseUrl}/myFormControllerPattern">
try to use javascript/jQuery trick:
var curl = document.location.pathname;
curl = curl.substring(0, curl.indexOf(".html"));
the first row will take your app address, then you cut the ".html" substring, thus enabling to add "/myFormControllerPattern" to the end of the string.
Change form action with javascript instead. Pass baseUrl as a model variable in your spring controller and use a javascript function like this to change form action:
function changeAction () {
var baseUrl = "${baseUrl}";
var form = document.getElementById("myForm");
form.action = baseUrl;
}
Hope it helps.
c:url tag can be usefull
include to jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
and then
<form id="myForm" action="<c:url value="/myFormControllerPattern" />" name="myForm">

Resources