Branislav Lazic
Branislav Lazic

Reputation: 14806

Spring MVC - pagination and request methods

Let's say I have this controller:

import org.java.wsg.service.ClientsService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.support.PagedListHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;

@Controller
public class ClientsController {

    @Autowired
    ClientsService clientsService;

    @RequestMapping(value = "/clients.htm")
    public String clientsPage(HttpServletRequest request, Model model) {

        PagedListHolder pagedList = new PagedListHolder(clientsService.getClients());
        pagedList.setPageSize(50);
        request.getSession().setAttribute("clientsList", pagedList);

        model.addAttribute("clients", pagedList.getPageList());

        return "clients";
    }

    @RequestMapping(value = "/clientsNavigate.htm", method = RequestMethod.POST)
    public String clientsNavigateToPage(HttpServletRequest request, Model model,
                                        @RequestParam String action) {

        PagedListHolder pagedList = (PagedListHolder) request.getSession().getAttribute("clientsList");

        if (action.equals("next")) {
            pagedList.nextPage();

        } else if (action.equals("previous")) {
            pagedList.previousPage();
        }

        model.addAttribute("clients", pagedList.getPageList());

        return "clients";
    }

    @RequestMapping(value = "/clients/{id}.htm", method = RequestMethod.GET)
    public String clientById(Model model, @PathVariable Integer id, HttpServletRequest request) {

        PagedListHolder pagedList = new PagedListHolder(clientsService.getClientById(id));
        pagedList.setPageSize(50);
        request.getSession().setAttribute("clientsList", pagedList);

        model.addAttribute("clients", pagedList.getPageList());

        return "clients";
    }
}

EDIT: Here is an clients.jsp page:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
         pageEncoding="ISO-8859-1" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!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=ISO-8859-1">
    <title>Clients</title>
    <link rel="stylesheet" type="text/css"
          href="<c:url value='/resources/css/bootstrap.css'/>"/>
    <script type="text/javascript" src="<c:url value="/resources/js/bootstrap.js" />">

    </script>

    <script type="text/javascript"
            src="<c:url value="/resources/js/bootstrap.min.js" />">

    </script>

</head>
<body>
<div class="container-fluid">
    <div class="row-fluid">

        <div class="span10 offset1">
            <center>
                <h2>Clients</h2>
            </center>

            <table class="table table-hover">
                <tr>
                    <th>
                        <center>Id</center>
                    </th>
                    <th>
                        <center>Ip</center>
                    </th>
                    <th>
                        <center>Connections</center>
                    </th>
                    <th>
                        <center>GUID</center>
                    </th>
                    <th>
                        <center>Name</center>
                    </th>
                    <th>
                        <center>Group</center>
                    </th>
                    <th>
                        <center>Time added</center>
                    </th>
                    <th>
                        <center>Last seen</center>
                    </th>
                </tr>
                <c:forEach items="${clients}" var="c">
                    <tr>
                        <td><c:out value="${c.id}"/></td>
                        <td><c:out value="${c.ip}"/></td>
                        <td><c:out value="${c.connections}"/></td>
                        <td><c:out value="${c.guid}"/></td>
                        <td><a href="${pageContext.request.contextPath}/clients/${c.id}.htm"><c:out
                                value="${c.name}"/></a>
                        </td>
                        <td><c:out value="${c.group}"/></td>
                        <td><c:out value="${c.timeAdd}"/></td>
                        <td><c:out value="${c.timeEdit}"/></td>

                    </tr>
                </c:forEach>
            </table>
            <form:form method="post" action="clientsNavigate.htm">
                <input type="submit" name="action" value="previous" class="btn btn-info" />
                <input type="submit" name="action" value="next" class="btn btn-info" />

            </form:form>
        </div>
    </div>
</div>
</body>
</html>

As you may see, first method (clientsPage) fetches list of i.e. Client objects and pass them as an attribute to clients.jsp page. Second method (clientsNavigateToPage) is used to process form request (simple form with two buttons (Next and Previous)) in clients.jsp page. And third method is used to obtain multiple clients with some id. But problem I'm facing is after I process my /clients/{id}.htm request I can't process my /clientsNavigate.htm request.

It says: HTTP Status 405 - Request method 'POST' not supported

How to deal with this issue?

Upvotes: 1

Views: 5645

Answers (1)

Ralph
Ralph

Reputation: 120771

Because every thing else looks not like a bug, I think the only remaining problem is the form url.

For your links you use this pattern:

<a href="${pageContext.request.contextPath}/clients/${c.id}.htm">...</a>

But for the page nav you use this relative url

<form:form method="post"
           action="clientsNavigate.htm"

So I think it would be worth trying:

<form:form method="post"
           action="${pageContext.request.contextPath}/clientsNavigate.htm" ...

Btw: I would recommend to use c:url (without contextPath but starts with slash) instead

<c:url var="navFormUrl" value= "/clientsNavigate.htm" />
<form:form method="post" action="${navFormUrl}" ...

Upvotes: 2

Related Questions