Spring RESTful风格url示例

时间:2022-12-10 21:12:52

转载自:http://www.xdemo.org/spring-restful/

口水篇

REST是设计风格而不是标准

  • 资源是由URI来指定。

  • 对资源的操作包括获取、创建、修改和删除资源

    这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。

  • 通过操作资源的表现形式来操作资源。

常用操作

GET 获取
POST 提交
PUT 更新
Delete 删除

REST确实不是标准,只是设计风格,目的只是让url看起来更简洁实用,是资源状态的一种表达。

实战篇

Demo下载地址http://pan.baidu.com/s/1o6sJLZs

项目结构

Spring RESTful风格url示例

Maven依赖

123456789101112131415161718192021222324252627282930313233 <!-- Jar版本管理 --><properties>    <springframework>4.0.2.RELEASE</springframework>    <log4j>1.2.17</log4j>    <jstl>1.2</jstl></properties><dependencies>    <!-- Spring web mvc -->    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-webmvc</artifactId>        <version>${springframework}</version>    </dependency>    <!-- JSTL -->    <dependency>        <groupId>jstl</groupId>        <artifactId>jstl</artifactId>        <version>${jstl}</version>    </dependency>    <!-- log4j -->    <dependency>        <groupId>log4j</groupId>        <artifactId>log4j</artifactId>        <version>${log4j}</version>    </dependency>    <!-- 单元测试 -->    <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <version>3.8.1</version>        <scope>test</scope>    </dependency></dependencies>

web.xml配置

需要注意,HiddenHttpMethodFilter是针对浏览器表单不支持put和delete方法而设计的,通过在表单中设置隐藏域,来分发到相应的处理器上,如<input type="hidden" name="_method" value="put" />

开发后记:最近把RESTful风格融入到了项目中去了,在开发过程中发现一个问题,就是aJax提交的PUT请求,无法通过HiddenHttpMethodFilter这个过滤器拿到值,后来搜索一番,改用HttpPutFormContentFilter即可

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 <?xml version="1.0" encoding="UTF-8"?><!-- 通过http://java.sun.com/xml/ns/javaee/获取最新的schemaLocation --><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    version="3.0">    <display-name>SpringActivemqServer</display-name>    <!-- WebAppRootKey -->    <context-param>        <param-name>webAppRootKey</param-name>        <param-value>example.SpringActivemqServer</param-value>    </context-param>    <!-- Log4J Start -->    <context-param>        <param-name>log4jConfigLocation</param-name>        <param-value>classpath:log4j.properties</param-value>    </context-param>    <context-param>        <param-name>log4jRefreshInterval</param-name>        <param-value>6000</param-value>    </context-param>    <!-- Spring Log4J config -->    <listener>        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>    </listener>    <!-- Log4J End -->    <!-- Spring 编码过滤器 start -->    <filter>        <filter-name>characterEncoding</filter-name>        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>        <init-param>            <param-name>encoding</param-name>            <param-value>UTF-8</param-value>        </init-param>        <init-param>            <param-name>forceEncoding</param-name>            <param-value>true</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>characterEncoding</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <!-- Spring 编码过滤器 End -->    <!-- Spring Application Context Listener Start -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath*:applicationContext.xml</param-value>    </context-param>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <!-- Spring Application Context Listener End -->    <!-- Spring MVC Config Start -->    <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-mvc.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>SpringMVC</servlet-name>        <!-- Filter all resources -->        <url-pattern>/</url-pattern>    </servlet-mapping>    <!-- Spring MVC Config End -->    <!-- 隐藏的HttpMethod方法过滤器,表单提交中需要携带一个name=_method的隐藏域,value=put或者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>    <welcome-file-list>        <welcome-file>index.jsp</welcome-file>    </welcome-file-list></web-app>

spring-mvc.xml配置

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 <?xml version="1.0" encoding="UTF-8"?>  <!-- 查找最新的schemaLocation 访问 http://www.springframework.org/schema/ --><beans xmlns="http://www.springframework.org/schema/beans"        xmlns:context="http://www.springframework.org/schema/context"         xmlns:mvc="http://www.springframework.org/schema/mvc"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://www.springframework.org/schema/beans           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd           http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-4.0.xsd           http://www.springframework.org/schema/mvc           http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">    <!-- 防止@ResponseBody中文乱码 -->    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">        <property name="messageConverters">            <list>                <bean                    class="org.springframework.http.converter.StringHttpMessageConverter">                    <property name="supportedMediaTypes">                        <list>                            <bean class="org.springframework.http.MediaType">                                <constructor-arg index="0" value="text" />                                <constructor-arg index="1" value="plain" />                                <constructor-arg index="2" value="UTF-8" />                            </bean>                        </list>                    </property>                </bean>            </list>        </property>    </bean>      <!-- 启用MVC注解 -->    <mvc:annotation-driven />     <!-- 静态资源文件,不会被Spring MVC拦截 -->    <mvc:resources location="/resources/" mapping="/resources/**"/>         <!-- 指定Sping组件扫描的基本包路径 -->    <context:component-scan base-package="org.xdemo.example" >        <!-- 这里只扫描Controller,不可重复加载Service -->        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>    </context:component-scan>           <!-- JSP视图解析器-->    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">          <property name="prefix" value="/WEB-INF/views/" />          <property name="suffix" value=".jsp" />        <property name="order" value="1" />    </bean></beans>

applicationContext.xml

123456789101112131415161718 <?xml version="1.0" encoding="UTF-8"?><!-- 查找最新的schemaLocation 访问 http://www.springframework.org/schema/ --><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:context="http://www.springframework.org/schema/context"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd        http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-4.0.xsd">     <!-- 配置扫描路径 -->     <context:component-scan base-package="org.xdemo.example">       <!-- 只扫描Service,也可以添加Repostory,但是要把Controller排除在外,Controller由spring-mvc.xml去加载 -->       <!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" /> -->       <!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" /> -->       <!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" /> -->       <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>     </context:component-scan></beans>

User实体类

12345678910111213141516171819202122232425262728293031323334353637383940 package org.xdemo.example.springrestful.entity;/** * @作者 Goofy * @邮件 252878950@qq.com * @日期 2014-4-2下午1:40:32 * @描述 用户实体类 */public class User {    private String userId;    private String userName;    public User(){}    public User(String userId,String userName){        this.userId=userId;        this.userName=userName;    }    /**     * @return the userId     */    public String getUserId() {        return userId;    }    /**     * @param userId the userId to set     */    public void setUserId(String userId) {        this.userId = userId;    }    /**     * @return the userName     */    public String getUserName() {        return userName;    }    /**     * @param userName the userName to set     */    public void setUserName(String userName) {        this.userName = userName;    }}

UserController

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 package org.xdemo.example.springrestful.controller;import java.util.ArrayList;import java.util.List; import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;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;import org.springframework.web.servlet.ModelAndView;import org.xdemo.example.springrestful.entity.User;/** * @作者 Goofy * @邮件 252878950@qq.com * @日期 2014-4-2下午1:28:07 */@Controller@RequestMapping("/user")public class UserController {    public List<User> list=null;    /**     * user路径下默认显示用户列表     * @return     */    @RequestMapping(method=RequestMethod.GET)    public ModelAndView index(){        if(list==null){            list=getUserList();        }        ModelMap model=new ModelMap();        model.addAttribute("list",list);        return new ModelAndView("user/index",model);    }    /**     * 跳转到添加用户页面,约定优于配置,默认匹配文件/WEB-INF/views/user/add.jsp     */    @RequestMapping("add")    public void add(){}    /**     * 新增保存用户     * @param user     * @return ModelAndView     */    @RequestMapping(method=RequestMethod.POST)    public ModelAndView addUser(User user){        if(list==null){            list=getUserList();        }        list.add(user);        ModelMap model=new ModelMap();        model.addAttribute("list",list);        return new ModelAndView("user/index",model);    }    /**     * 查看用户详细信息     * @param id     * @return ModelAndView     */    @RequestMapping(method=RequestMethod.GET,value="{id}")    public ModelAndView viewUser(@PathVariable("id")String id){        User user=findUserById(id);        ModelMap model=new ModelMap();        model.addAttribute("user",user);        return new ModelAndView("user/view",model);    }         /**     * 删除用户     * @param id     */    @ResponseBody    @RequestMapping(method=RequestMethod.DELETE,value="{id}")    public String deleteUser(@PathVariable("id")String id){        if(list==null){            list=getUserList();        }        removeUserByUserId(id);        return "suc";    }         /**     * 跳转到编辑页面     * @param id     * @return ModelAndView     */    @RequestMapping("{id}/edit")    public ModelAndView toEdit(@PathVariable("id")String id){                 User user=findUserById(id);        ModelMap model=new ModelMap();        model.addAttribute("user",user);                 return new ModelAndView("user/edit",model);    }         /**     * 更新用户并跳转到用户列表页面     * @param user     * @return ModelAndView     */    @RequestMapping(method=RequestMethod.PUT)    public ModelAndView edit(User user){        updateUser(user);        return new ModelAndView("redirect:/user/");    }     /********************下面方法是操作数据的*********************/    /**     * 造10个用户     * @return List<User>     */    private List<User> getUserList(){        List<User> list=new ArrayList<User>();        for(int i=0; i<10;i++){            list.add(new User((i+1)+"","李四"+(i+1)));        }        return list;    }    /**     * 删除用户     * @param id     * @return List<User>     */    private List<User> removeUserByUserId(String id){        if(list==null)return null;        for(User user:list){            if(user.getUserId().equals(id)){                list.remove(user);break;            }        }        return list;    }    /**     * 查找用户     * @param id     * @return User     */    private User findUserById(String id){        User user=null;        if(list==null)return null;        for(User _user:list){            if(_user.getUserId().equals(id)){                user=_user;break;            }        }        return user;    }    /**     * 更新用户     * @param user     */    private void updateUser(User user){        for(User _user:list){            if(_user.getUserId().equals(user.getUserId())){                _user.setUserName(user.getUserName());break;            }        }    }          }

用户列表页面index.jsp

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%    String path = request.getContextPath();    String basePath = request.getScheme() + "://"            + request.getServerName() + ":" + request.getServerPort()            + path + "/";%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"><title>用户列表</title><script type="text/javascript"    src="<%=basePath%>resources/jquery-1.11.0.min.js"></script><style type="text/css">a {    border: 1px solid rgb(735858);    background-color: rgb(133133133);    height: 50px;    line-height: 50px;    color: white;    text-decoration: none;    font-weight: bold;    padding: 5px;    margin: 5px;}</style><script type="text/javascript"> function deleteUser(id){    $.ajax({        type: 'delete',        url:'<%=basePath%>user/'+id,        dataType:'text'        success:function(data){            if(data=="suc"){                alert("删除成功");                location.reload();            }        },        error:function(data){        }    });} </script></head> <body>    <div style="margin:0 auto;width:500px;">        <a href="<%=basePath%>user/add">新增用户</a>        <table>            <tr>                <th>用户ID</th>                <th>用户名称</th>                <th>操作</th>            </tr>            <c:forEach var="user" items="${list }">                <tr>                    <td>${user.userId }</td>                    <td>${user.userName }</td>                    <td>                        <a href="<%=basePath %>user/${user.userId}/edit">编辑用户</a>                        <a href="<%=basePath %>user/${user.userId}">查看用户</a>                        <a href="javascript:void(0);" onclick="deleteUser(${user.userId })">删除该用户</a>                    </td>                </tr>            </c:forEach>        </table>    </div></body></html>

编辑用户页面edit.jsp

123456789101112131415161718192021222324252627282930313233343536373839 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%    String path = request.getContextPath();    String basePath = request.getScheme() + "://"            + request.getServerName() + ":" + request.getServerPort()            + path + "/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"><title>新增用户页面</title></head><body>    <div style="margin:0 auto;width:400px;">        <form action="<%=basePath%>user" method="post">        <!--此隐藏域可以被HiddenHttpMethodFilter所处理,然后分发到不同的HttpMethod的处理器上-->        <input type="hidden" name="_method" value="put" />            <table>                <tr>                    <th>用户ID</th>                    <th>用户名称</th>                </tr>                <tr>                    <td><input type="text" name="userId" id="userId" value="${user.userId }" readonly="readonly"/>                    </td>                    <td><input type="text" name="userName" id="userName" value="${user.userName }"/>                    </td>                </tr>                <tr>                    <td colspan="2"><input type="submit" value="保存用户" />                    </td>                </tr>            </table>        </form>    </div></body></html>

新增用户页面add.jsp

123456789101112131415161718192021222324252627282930313233343536373839 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%    String path = request.getContextPath();    String basePath = request.getScheme() + "://"            + request.getServerName() + ":" + request.getServerPort()            + path + "/";%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"><title>新增用户页面</title><meta http-equiv="description" content="This is my page"></head><body>    <div style="margin:0 auto;width:400px;">        <form action="<%=basePath%>user" method="post">            <table>                <tr>                    <th>用户ID</th>                    <th>用户名称</th>                </tr>                <tr>                    <td><input type="text" name="userId" id="userId" />                    </td>                    <td><input type="text" name="userName" id="userName" />                    </td>                </tr>                <tr>                    <td colspan="2"><input type="submit" value="保存用户" />                    </td>                </tr>            </table>        </form>    </div></body></html>

查看用户页面view.jsp

1234567891011121314151617181920212223242526272829303132333435363738394041 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%    String path = request.getContextPath();    String basePath = request.getScheme() + "://"            + request.getServerName() + ":" + request.getServerPort()            + path + "/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"><title>用户详情页面</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"></head><body>    <div style="margin:0 auto;width:400px;">        <form action="<%=basePath%>user" method="post">            <table>                <tr>                    <th>用户ID</th>                    <th>用户名称</th>                </tr>                <tr>                    <td>${user.userId}</td>                    <td>${user.userName}</td>                </tr>                <tr>                    <td colspan="2"><input type="button" value="返回用户列表"                        onclick="history.go(-1)" />                    </td>                </tr>            </table>        </form>    </div></body></html>

运行截图


Spring RESTful风格url示例

Spring RESTful风格url示例

Spring RESTful风格url示例