溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SpringMVC如何實現(xiàn)RESTful風(fēng)格

發(fā)布時間:2021-11-30 12:53:36 來源:億速云 閱讀:261 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下SpringMVC如何實現(xiàn)RESTful風(fēng)格,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

    1、RESTful簡介

    RESTful為Representational State Transfer的縮寫,中文釋義為“表現(xiàn)層狀態(tài)轉(zhuǎn)換”。RESTful不是一種標(biāo)準(zhǔn),而是一種設(shè)計風(fēng)格。

    RESTful本質(zhì)上是一種分布式系統(tǒng)的應(yīng)用層解決方案,它的主要作用是充分并正確利用HTTP協(xié)議的特性,規(guī)范資源獲取的URL路徑。

    通俗地講,RESTful風(fēng)格的設(shè)計允許將參數(shù)通過URL拼接傳到服務(wù)端,目的是讓URL看起來更簡潔實用。并且對于不同操作,要指定不同的HTTP方法(POST/GET/PUT/DETELE)。

    可以這么說,只要是具有上述相關(guān)約束條件和原則的應(yīng)用程序或設(shè)計就可以被稱為RESTful風(fēng)格的應(yīng)用。

    2、SpringMVC實現(xiàn)RESTful風(fēng)格

    SpringMVC支持實現(xiàn)RESTful風(fēng)格的請求。SpringMVC可以使用@RequestMapping注解的路徑設(shè)置,結(jié)合@PathVariable注解的參數(shù)指定,來實現(xiàn)RESTful風(fēng)格的請求。

    【示例】實現(xiàn)一個在服務(wù)端出來RESTful風(fēng)格請求的Controller方法。

    /**
     * 獲取用戶
     *
     * @author pan_junbiao
     */
    @RequestMapping(value = "/getUser/{id}", method = RequestMethod.GET)
    @ResponseBody
    public UserInfo getUserById(@PathVariable("id") int userId)
    {
        UserInfo userInfo = new UserInfo();
        //獲取用戶信息
        if (userId == 1)
        {
            userInfo.setUserId(1);
            userInfo.setUserName("pan_junbiao的博客");
            userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");
            userInfo.setRemark("您好,歡迎訪問 pan_junbiao的博客");
        }
        //返回結(jié)果
        return userInfo;
    }

    2.1 @PathVariable注解

    在上述方法中,在@RequestMapping注解的請求路徑中添加了一個動態(tài)數(shù)據(jù)“{id}”,它的作用是解析前臺的請求路徑,將動態(tài)數(shù)據(jù)所在的位置解析為名為 id 的請求參數(shù)。

    而在Controller的參數(shù)中,使用@PathVariable注解,在其中指定請求參數(shù)的key名稱,并映射在后面定義的形參上,這里定義userId形參來接收名為id的請求參數(shù)。

    方法體中其余的操作就是正常的業(yè)務(wù)邏輯,最后使用@ResponseBody注解加上之前配置的類型轉(zhuǎn)換器,返回客戶端JSON類型的用戶信息。

    總的來說,利用SpringMVC實現(xiàn)RESTful風(fēng)格主要就是在于請求路徑和請求參數(shù)的映射,以及RequestMethod的指定。

    2.2 修改SpringMVC的前端控制器配置

    之前在項目工程的web.xml配置文件中,配置了SpringMVC的前端控制器,用于集中處理請求,配置如下:

    <!-- SpringMVC前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring-mvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

    可以看到,前端控制器過濾的是后綴為“*.action”的請求路徑,所以編寫的RESTful風(fēng)格的請求是不能被前端控制器過濾并解析的,所以要修改該配置,使得RESTful風(fēng)格的請求可以被SpringMVC的前端控制器處理:

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    造成問題:這里修改成了過濾所有請求類型的請求至前端控制器。這可能會帶來靜態(tài)資源訪問的問題,將在下面處理該問題。

    執(zhí)行結(jié)果:

    SpringMVC如何實現(xiàn)RESTful風(fēng)格

    從執(zhí)行結(jié)果中可以看到,成功查詢了id為1的用戶信息,這說明RESTful風(fēng)格的請求服務(wù)編寫成功。

    3、靜態(tài)資源訪問問題

    前面在web.xml中配置了符合RESTful風(fēng)格的DispatcherServlet前端控制器過濾器,實現(xiàn)了正確處理RESTful風(fēng)格請求的機制。但是這種過濾方式會造成靜態(tài)資源無法訪問的問題,例如在JavaWeb項目中創(chuàng)建名為img的目錄,并且在該目錄中放置一張名為myImage.jpg的圖片。

    由于圖片放置在WEB-INF文件夾外(由于JavaWeb的保護機制,WEB-INF文件夾下的文件不可以直接訪問),所以原則上是可以通過直接訪問靜態(tài)資源的方式獲取到該圖片的,但是發(fā)現(xiàn)并沒有成獲取到圖片資源,如下圖:

    SpringMVC如何實現(xiàn)RESTful風(fēng)格

    這是為什么呢?原因在于在web.xml中配置的前端控制器的請求過濾機制,為了接收RESTful風(fēng)格的請求,將過濾的后綴去除了,變成過濾所有后綴的請求路徑,此時靜態(tài)資源會被當(dāng)作一個業(yè)務(wù)請求被DispatcherServlet前端控制器處理,前端控制器沒有發(fā)現(xiàn)能夠處理該請求的Controller控制器方法,所以對外拋出404(請求資源不可用)錯誤。

    如果想正常處理靜態(tài)資源,但又要保證RESTful請求的正常響應(yīng),可以通過下面兩種方法來解決。

    3.1 解決方法一

    方法一,在SpringMVC的核心配置文件中使用<mvc:resource>標(biāo)簽配置靜態(tài)資源的解析路徑,將需要加載的靜態(tài)資源的URI路徑配置在標(biāo)簽中,然后配置該URI映射的真實資源路徑。配置如下:

    <!-- 靜態(tài)資源的解析,包括:js/css/img... -->
    <mvc:resources location="/js/" mapping="/js/**"/>
    <mvc:resources location="/css/" mapping="/css/**"/>
    <mvc:resources location="/img/" mapping="/img/**"/>

    當(dāng)在SpringMVC的核心配置文件中配置了靜態(tài)資源文件的解析路徑后,前端控制器就會根據(jù)請求URL中的具體子路徑來映射出靜態(tài)資源的真實路徑,然后為前端反饋真實的靜態(tài)資源信息。

    3.2 解決方法二

    方法二,在SpringMVC的核心配置文件中使用<mvc:default-servlet-handler/>配置默認的Servlet處理器,該配置將在SpringMVC上下文中定義一個DefaultServletHttpRequestHandler,它會對進入DispatcherServlet前端控制器的請求進行篩查,如果發(fā)現(xiàn)是沒有經(jīng)過映射的請求,就將該請求交由Web應(yīng)用服務(wù)器默認的Servlet處理,如果不是靜態(tài)資源的請求,才由DispatcherServlet前端控制器繼續(xù)處理。

    此時就可以將請求中的靜態(tài)資源與其他業(yè)務(wù)請求分開處理,從而正常地返回靜態(tài)資源信息。

    <!-- 2.靜態(tài)資源默認servlet配置
            (1)加入對靜態(tài)資源的處理:js/css/img...
            (2)允許使用"/"做整體映射
         -->
    <mvc:default-servlet-handler/>

    執(zhí)行結(jié)果:

    SpringMVC如何實現(xiàn)RESTful風(fēng)格

    這說明靜態(tài)資源請求被單獨進行了處理,從而保證了RESTful請求能夠被Controller控制器正常處理并響應(yīng),也保證了靜態(tài)資源的正常獲取。

    4、綜合實例

    上面的代碼為查詢類型的請求代碼,而新增、修改以及刪除的請求與此類似,區(qū)別就是需要指定不同的RequestMethod屬性(POST/PUT/DELETE)。實例代碼如下:

    (1)創(chuàng)建用戶信息實體類(UserInfo.java)

    package com.pjb.ssm.entity; 
    /**
     * 用戶信息實體類
     *
     * @author pan_junbiao
     **/
    public class UserInfo
    {
        private int userId; //用戶ID
        private String userName; //用戶姓名
        private String blogUrl; //博客地址
        private String remark; //備注
     
        //省略getter與setter方法...
    }

    (2)創(chuàng)建用戶信息控制器(UserController.java),實現(xiàn)RESTful風(fēng)格的請求

    package com.pjb.ssm.controller; 
    import com.pjb.ssm.entity.UserInfo;
    import org.springframework.stereotype.Controller;
    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.ResponseBody;
     
    /**
     * 用戶信息控制器
     *
     * @author pan_junbiao
     **/
    @Controller
    @RequestMapping("user")
    public class UserController
    {
        /**
         * 獲取用戶
         *
         * @author pan_junbiao
         */
        @RequestMapping(value = "/getUser/{id}", method = RequestMethod.GET)
        @ResponseBody
        public UserInfo getUserById(@PathVariable("id") int userId)
        {
            UserInfo userInfo = new UserInfo();
            //獲取用戶信息
            if (userId == 1)
            {
                userInfo.setUserId(1);
                userInfo.setUserName("pan_junbiao的博客");
                userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");
                userInfo.setRemark("您好,歡迎訪問 pan_junbiao的博客");
            }
            //返回結(jié)果
            return userInfo;
        }
     
        /**
         * 新增用戶
         */
        @RequestMapping(value = "/addUser", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;"})
        @ResponseBody
        public String addUser(UserInfo userInfo)
        {
            return "執(zhí)行新增用戶,用戶名稱:" + userInfo.getUserName();
        }
     
        /**
         * 刪除用戶
         */
        @RequestMapping(value = "/deleteUser/{id}", method = RequestMethod.DELETE, produces = {"text/html;charset=UTF-8;", "application/json;"})
        @ResponseBody
        public String deleteUser(@PathVariable("id") int userId)
        {
            return "執(zhí)行刪除用戶,用戶ID:" + userId;
        }
     
        /**
         * 修改用戶
         */
        @RequestMapping(value = "/updateUser", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;"})
        @ResponseBody
        public String updateUser(UserInfo userInfo)
        {
            return "執(zhí)行修改用戶,用戶名稱:" + userInfo.getUserName();
        }
    }

    (3)創(chuàng)建執(zhí)行頁面(index.jsp),在該頁面中使用了JQuery框架

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>首頁</title>
        <meta name="author" content="pan_junbiao的博客">
    </head>
    <body>
    <h2>首頁</h2>
    <input type="button" id="btnGetUser" value="獲取用戶"/>
    <input type="button" id="btnAddUser" value="新增用戶"/>
    <input type="button" id="btnDeleteUser" value="刪除用戶"/>
    <input type="button" id="btnUpdateUser" value="修改用戶"/><br>
    <p id="msg" ></p>
    </body>
    <script src="${pageContext.request.contextPath}/JS/jquery-3.4.1.min.js"></script>
    <script>
        //獲取用戶按鈕事件
        $("#btnGetUser").click(function () {
            var url = "${pageContext.request.contextPath}/user/getUser/1";
            window.location.href = url;
        });
     
        //新增用戶按鈕事件
        $("#btnAddUser").click(function () {
            //執(zhí)行Ajax請求
            $.ajax({
                type: "POST",
                url: "${pageContext.request.contextPath}/user/addUser",
                data: {
                    userId: 1,
                    userName: "pan_junbiao的博客"
                },
                success: function (result) {
                    $("#msg").append(result + "<br>");
                }
            });
        });
     
        //刪除用戶按鈕事件
        $("#btnDeleteUser").click(function () {
            //執(zhí)行Ajax請求
            $.ajax({
                type: "DELETE",
                url: "${pageContext.request.contextPath}/user/deleteUser/1",
                success: function (result) {
                    $("#msg").append(result + "<br>");
                }
            });
        });
     
        //修改用戶按鈕事件
        $("#btnUpdateUser").click(function () {
            //執(zhí)行Ajax請求
            $.ajax({
                type: "POST",
                url: "${pageContext.request.contextPath}/user/updateUser",
                data: {
                    userId: 1,
                    userName: "pan_junbiao的博客"
                },
                success: function (result) {
                    $("#msg").append(result + "<br>");
                }
            });
        });
    </script>
    </html>

    執(zhí)行結(jié)果:

    SpringMVC如何實現(xiàn)RESTful風(fēng)格

    以上是“SpringMVC如何實現(xiàn)RESTful風(fēng)格”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

    向AI問一下細節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI