Spring MVC - 分页和请求方法

Posted

技术标签:

【中文标题】Spring MVC - 分页和请求方法【英文标题】:Spring MVC - pagination and request methods 【发布时间】:2013-11-23 11:46:08 【问题描述】:

假设我有这个控制器:

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";
    

编辑: 这是一个clients.jsp 页面:

<%@ 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>

如您所见,第一个方法 (clientsPage) 获取 Client 对象的列表并将它们作为属性传递给 clients.jsp 页面。第二种方法(clientsNavigateToPage)用于处理clients.jsp页面中的表单请求(带有两个按钮(NextPrevious)的简单表单)。第三种方法用于获取具有某个id的多个客户端。但我面临的问题是在处理我的/clients/id.htm 请求后,我无法处理我的/clientsNavigate.htm 请求。

它说: HTTP Status 405 - Request method 'POST' not supported

如何处理这个问题?

【问题讨论】:

请包含您的 HTML(或用于发送表单的任何内容)代码。 您是否检查过表单action 是否正确,即该请求是否发送到正确的控制器?尝试从映射中删除 method = RequestMethod.POST。尽管这似乎是正确的,但让我们检查一下删除它是否有帮助。 @MichałRybak 刚刚检查过。是的,它已发送到正确的控制器。 删除method = RequestMethod.POST 有帮助吗? @MichałRybak 不,它没有。 【参考方案1】:

因为其他所有东西看起来都不像一个错误,所以我认为唯一剩下的问题是表单 url。

对于您的链接,您使用此模式:

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

但是对于页面导航,您使用这个相对 url

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

所以我认为值得一试:

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

顺便说一句:我建议改用 c:url(没有 contextPath,但以斜杠开头)

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

【讨论】:

OP 在评论中说请求被发送到正确的控制器,所以我认为问题出在其他地方。 @Michał Rybak:“我有多少次对你说,当你消除了不可能的事情后,剩下的一切,无论多么不可能,都必须是真相?”亚瑟柯南道尔爵士的《福尔摩斯》。 ;-) -- 根据我在堆栈溢出方面的经验,我不得不说,如果你有一个程序和一个 OP,并且都告诉你一些不同的东西,那么大多数时候代码是不会说谎的。

以上是关于Spring MVC - 分页和请求方法的主要内容,如果未能解决你的问题,请参考以下文章

使用 ASP.Net MVC 对网格进行分页和排序

操作系统——存储管理:分区分页分段请求式分页和虚拟内存

Spring MVC 之请求处理方法可接收参数

Spring MVC 的请求参数获取的几种方法

Spring MVC:将请求属性绑定到控制器方法参数

操作系统| 虚拟存储器(请求分页和请求分段地址变换详解,页面置换算法先进先出LRUClock虚拟存储器的定义和特征)