SpringMVC 中使用 REST

1. 在 web.xml 里加上 HiddenHttpMethodFilter

<!-- 浏览器的 form 不支持 put, delete 等 method, 由该 filter 将 /blog?_method=delete 转换为标准的 http delete 方法 -->
<filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <servlet-name>springmvc</servlet-name>
</filter-mapping>

2. 新建一个 Controller 类: controller/RestController.java

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class RestController {
    // 处理 GET 请求,显示 rest-form 页面
    @RequestMapping(value="/rest", method= RequestMethod.GET)
    public String rest() {
        return "rest-form.htm";
    }

    // 处理 POST 请求
    @RequestMapping(value="/rest", method= RequestMethod.POST)
    @ResponseBody
    public String restPost() {
        return "{method: \"POST\"}";
    }

    // 处理 PUT 请求
    @RequestMapping(value="/rest", method= RequestMethod.PUT)
    @ResponseBody
    public String restPut() {
        return "{method: \"PUT\"}";
    }

    // 处理 DELETE 请求
    @RequestMapping(value="/rest", method= RequestMethod.DELETE)
    @ResponseBody
    public String restDelete() {
        return "{method: \"DELETE\"}";
    }
}

3. 新建一个网页 WEB-INF/view/ftl/rest-form.htm

页面里有 4 个按钮,分别为 GET, PUT, POST, DELETE

Form 表单默认支持 GET 和 POST 请求,但不支持 PUT 和 DELETE 请求。为了发送 PUT, DELETE请求,在 form 里添加一个隐藏域 _method 表明发送 PUT, DELETE 请求,使用 POST 提交。

<!-- UUID: 982401A7-85F5-48AA-A2E6-D88A0960758D -->
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <style>
        body { padding: 25px 50px; }
        button { width: 100px; }
    </style>
</head>
<body>
    <!-- 测试 form 的不同 method,default HTML form 不支持 put and delete -->

    <form action="/rest" method="get">
        <button type="submit">Get</button>
    </form>

    <form action="/rest" method="post">
        <button type="submit">Post</button>
    </form>

    <form action="/rest" method="post">
        <input type="hidden" name="_method" value="put"/>
        <button type="submit">Put</button>
    </form>

    <form action="/rest" method="post">
        <input type="hidden" name="_method" value="delete"/>
        <button type="submit">Delete</button>
    </form>
</body>
</html>

项目目录结构

4. 访问 http://localhost:8080/rest

点击 Get 仍然显示当前页,这没错,处理 GET 请求的方法返回的 View Name 就是当前页面的名字。点击 PUT 按钮显示如下,说明 PUT 请求被方法 restPut() 处理,和期望的一样。

点击 PostDelete按钮,同样的被正确的响应。

5. 使用 AJAX 发送请求

Form 表单不支持提交 PUT,DELETE 请求,所以我们通过隐藏域的方式间接的达到了目的。但是 AJAX 原生的就支持 GET, PUT, POST, DELETE 请求

5.1. 在 RestController.java 新增下面的这个函数,用于访问 rest-ajax.htm 页面

    @RequestMapping("/rest-ajax")
    public String restAjax() {
        return "rest-ajax.htm";
    }

5.2. 把 jquery.js 放到 WEB-INF/resources/js 目录下

5.3. 创建 view/ftl/rest-ajax.htm 页面

<!-- UUID: 93DEA045-2C24-408F-8F6F-F3CA166800DC -->
<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
    button {
        width: 80px;
    }
    </style>

<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    var targetUrl = "http://localhost:8080/rest";

    // 点击 Get 按钮
    $("#get-btn").click(function() {
        $.ajax({
            url: targetUrl,
            type: "GET",
            success: function(data) {
                alert(data);
            }
        });
    });

    // 点击 Post 按钮
    $("#post-btn").click(function() {
        $.ajax({
            url: targetUrl,
            type: "POST",
            success: function(data) {
                alert(data);
            }
        });
    });

    // 点击 Get 按钮
    $("#put-btn").click(function() {
        $.ajax({
            url: targetUrl,
            type: "PUT",
            success: function(data) {
                alert(data);
            }
        });
    });

    // 点击 Get 按钮
    $("#delete-btn").click(function() {
        $.ajax({
            url: targetUrl,
            type: "DELETE",
            success: function(data) {
                alert(data);
            }
        });
    });
});
</script>
</head>
<body>
    <button id="get-btn">Get</button>
    <button id="post-btn">Post</button>
    <button id="put-btn">Put</button>
    <button id="delete-btn">Delete</button>
</body>
</html>

点击 PUT 按钮,可以知道 PUT 请求被方法 restPut() 处理,和期望的一样。

点击 Post,Delete按钮,同样的被正确的响应。

5.4. 最后再来看一下项目的目录结构