restful完整实例

口水篇

REST是设计风格而不是标准

  • 资源是由URI来指定。

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

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

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

常用操作

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

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

实战篇

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

Maven依赖


<!-- 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


<? 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配置


<? 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


<?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实体类


package  org.xdemo.example.springrestful.entity;
/**
  * @作者 Goofy
  * @邮件 [email protected]
  * @日期 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


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
  * @邮件 [email protected]
  * @日期 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


<%@ 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( 73 58 58 );
     background-color: rgb( 133 133 133 );
     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


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


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


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

猜你喜欢

转载自blog.csdn.net/qq_38869854/article/details/80664677