Home > Blockchain >  Path variable changes with pagination, err: Failed to convert value of type java.lang.String to requ
Path variable changes with pagination, err: Failed to convert value of type java.lang.String to requ

Time:03-05

html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>End Value</title>
    <link th:href="@{/static/css/bootstrap.min.css}" rel="stylesheet"/>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>
    <style>
#simulat {
  font-family: Arial, Helvetica, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

#simulat td, #plantEvent th {
  border: 1px solid #ddd;
  padding: 8px;
}

#simulat tr:nth-child(even){background-color: #f2f2f2;}

#simulat tr:hover {background-color: #ddd;}

#simulat th {
  padding-top: 12px;
  padding-bottom: 12px;
  text-align: left;
  background-color: #04AA6D;
  color: white;
}
</style>
</head>
<body>
<br>
<td>
    <a th:href="@{~/SimulationsForm}" >Back to simulation form site</a>
    <a th:href="@{~/SimulationsValues}" >Back to simulation values site</a>
</td>
<table id="simulat" border="1" >
    <thead>
    <tr>
        <th>Pv</th>
        <th>Pr</th>
        <th>Pi</th>
        <th>Pm</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="sim, iStat : ${allP.content}"
        th:style="${iStat.odd}? 'font-weight: bold;'"
        th:alt-title="${iStat.even}? 'even' : 'odd'">
        <td th:text="${sim.healthy_Prone_To_Infection}"></td>
        <td th:text="${sim.regained_Health_And_Immunity}"></td>
        <td th:text="${sim.number_Of_Infected}"></td>
        <td th:text="${sim.dead}"></td>
    </tr>
    </tbody>
</table>
<div style="display: inline" th:if="${allP.totalPages > 0}" 
     th:each="pageNumber : ${pageNumbers}">
    <a th:href="@{/SimulationsValuesById/{id}/(size=${allP.size}, page=${pageNumber})}"
       th:text=${pageNumber}
       th:></a>
</div>
<br>
Provide simulation name
<input id="vall2" type="text" >
<br>
Provide day
<input id="vall3" type="text" ><br>
<button onclick="myFunction2()" >Find simulation values for given day for specific simulation by
    name
</button>
<br>
<br>
<br>
Simulations:
<br>
<table>
    <thead>
    <tr >
        <th>Name</th>
        <th>Days</th>
    </tr>
    </thead>
    <tbody>
    <th:block th:each="sim : ${s}">
        <tr>
            <td th:text="${sim.simulation_Name}"></td>
            <td th:text="${sim.simulation_Time}"></td>
        </tr>
    </th:block>
    </tbody>
</table>
<br>
<script>
function myFunction2() {
  var intt = document.getElementById("vall2").value;
  var intt2 = document.getElementById("vall3").value;
location.href = 'http://localhost:8080/SimulationsValues/' intt '/' intt2;
}
</script>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</html>

Controller

 @GetMapping("SimulationsValuesById/{id}/")
    public String showSimulationsValuesForSimulation(@PathVariable("id") Long id,
                                                     @RequestParam(value = "page", defaultValue = "1") Integer page,
                                                     @RequestParam(value = "size", defaultValue = "5") Integer size,
                                                     Model model) {
        Page<SimulationsValues> ratePage = simulationService.pagination(id, PageRequest.of(page - 1, size));
        model.addAttribute("allP", ratePage);
        int totalPages = ratePage.getTotalPages();
        if (totalPages > 0) {
            List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
                    .boxed()
                    .collect(Collectors.toList());
            model.addAttribute("pageNumbers", pageNumbers);
        }
        model.addAttribute("s", simulationRepository.findAll());
        return "allSimsSimulationValues";
    }

Pagination method

public Page<SimulationsValues> pagination(Long id, Pageable pageable) {
        int pageSize = pageable.getPageSize();
        int currentPage = pageable.getPageNumber();
        int startItem = currentPage * pageSize;
        List<SimulationsValues> list;
        if (eachRemainingDayService.getSimulations().stream().filter(e -> e.getId().equals(id))
                .collect(Collectors.toList()).get(0).getSimulationsValues().size() < startItem) {
            list = Collections.emptyList();
        } else {
            int toIndex = Math.min(startItem   pageSize, (simulationRepository.findAll().stream()
                    .filter(e -> e.getId().equals(id)).collect(Collectors.toList()).get(0)
                    .getSimulationsValues().size()));
            list = simulationRepository.findAll().stream()
                    .filter(e -> e.getId().equals(id)).collect(Collectors.toList()).get(0)
                    .getSimulationsValues().subList(startItem, toIndex);
        }
        return new PageImpl<>(list, PageRequest.of(currentPage, pageSize), simulationRepository.findAll()
                .stream().filter(e -> e.getId().equals(id)).collect(Collectors.toList()).get(0)
                .getSimulationsValues().size());
    }

Hi, I have a problem. I have a table with pagination (values of that table are spread on 5 pages) and the url to this table is for example: http://localhost:8080/SimulationsValuesById/2563/ where 2563 is a path variable and an id of some object whose fields I want to show in that table and when I click on some page number (here page 2) under that table, I get error status 400 and on the console error: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "{id}"] and url gets changed to http://localhost:8080/SimulationsValuesById/{id}/?size=5&page=2. Why id gets changed to some String (here {id}) when I try to get on some page? ({id} is on every page) How do I make this path variable constant so it stays the same no matter what page I get on so I get http://localhost:8080/SimulationsValuesById/2563/?size=5&page=2 or http://localhost:8080/SimulationsValuesById/1111/?size=5&page=2?Thanks in advance.

CodePudding user response:

From what I see you need to set a value for your {id} path variable, just like you do for size and page (reference):

<div style="display: inline" th:if="${allP.totalPages > 0}" 
     th:each="pageNumber : ${pageNumbers}">
    <a th:href="@{/SimulationsValuesById/{id}/(id=${someValue}, size=${allP.size}, page=${pageNumber})}"
       th:text=${pageNumber}
       th:></a>
</div>

If I understood correctly what needs to be done, you should have two separate endpoints in your controller:

  • one for pagination, without id. This will return a list of simulations for the current page:
@GetMapping("/simulations")
    public String showSimulations(@RequestParam(value = "page", defaultValue = "1") Integer page,
                                  @RequestParam(value = "size", defaultValue = "5") Integer size,
                                  Model model) 
{
    // return a list of simulations for a given page
}

Iterate through the simulations:

<div th:each="simulation : ${simulations}">
    <a th:href="@{/simulation/{id}(id = ${simulation.id})}">
        <span th:text="${simulation.name}"></span>
    </a>
</div>
  • a second one for getting the information for a specific simulation
@GetMapping("/simulation/{id}")
    public String showSimulation(@PathVariable("id") int id, 
                                  Model model) 
{
    // return simulation details
}

CodePudding user response:

 @GetMapping("SimulationsValuesById/{id}/")
    public String showSimulationsValuesForSimulation(@PathVariable("id") Long id,
                                                     @RequestParam(value = "page", defaultValue = "1") Integer page,
                                                     @RequestParam(value = "size", defaultValue = "5") Integer size,
                                                     Model model) {
        Page<SimulationsValues> ratePage = simulationService.pagination(id, PageRequest.of(page - 1, size));
        model.addAttribute("allP", ratePage);
        int totalPages = ratePage.getTotalPages();
        if (totalPages > 0) {
            List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
                    .boxed()
                    .collect(Collectors.toList());
            model.addAttribute("pageNumbers", pageNumbers);
        }
        model.addAttribute("idS", id);
        model.addAttribute("s", simulationRepository.findAll());
        return "allSimsSimulationValues";
    }
<div style="display: inline" th:if="${allP.totalPages > 0}" 
     th:each="pageNumber : ${pageNumbers}">
    <a th:href="@{/SimulationsValuesById/{idS}/(idS=${idS}, size=${allP.size}, page=${pageNumber})}"
       th:text=${pageNumber}
       th:></a>
</div>

I simply passed id from @PathVariable() to .html as idS and there used it as a part of a url and everything works as it should.

  • Related