五. REST 风格的CRUD
不熟悉SpringMVC 的JSON用法的,可以参照 老蝴蝶以前写的文章: SpringMVC的JSON处理及FastJSON的整合使用(七)
对 form 表单传递的 _method ,不熟悉的,可以参照老蝴蝶以前写的文章:
SpringMVC的form表单标签使用(八)
json使用的是fastjson.
五.一 User.java 实体类
public class User implements Serializable{ private static final long serialVersionUID = 1L; private Integer id; private String name; private String sex; private Integer age; private String description; private String password; public User() { super(); } public User(Integer id, String name, String password,String sex, Integer age, String description) { super(); this.id = id; this.name = name; this.password=password; this.sex = sex; this.age = age; this.description = description; } //省略了setter和getter方法 }
五.二 Dao接口和实现类 来存储数据
利用静态类进行存储数据,而不是存储在数据库里。 SpringMVC与数据库整合,老蝴蝶放在下面的文章中讲。
UserDao.java
package com.yjl.dao; import java.util.List; import com.yjl.pojo.User; public interface UserDao { int addUser(User user); int deleteUserById(int id); int updateUser(User user); List<User> findAll(); User findById(int id); }
UserDaoImpl.java
package com.yjl.dao; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Repository; import com.yjl.pojo.User; @Repository public class UserDaoImpl implements UserDao{ private static List<User> userList=new ArrayList<User>(); static { //好久没有用这些人名了,都快忘记自己的初心了。 User user1=new User(1,"父亲","123","男",50,"爸爸"); User user2=new User(2,"母亲","123","女",48,"妈妈"); User user3=new User(3,"慧芳","123","女",27,"大姐"); User user4=new User(4,"正伟","123","男",28,"大姐夫"); User user5=new User(5,"莉莉","123","女",25,"二姐"); User user6=new User(6,"敬龙","123","男",26,"二姐夫"); User user7=new User(7,"两个蝴蝶飞","123","男",24,"在下"); userList.add(user1); userList.add(user2); userList.add(user3); userList.add(user4); userList.add(user5); userList.add(user6); userList.add(user7); } @Override public int addUser(User user) { userList.add(user); return 1; } @Override public int deleteUserById(int id) { //如果id一样,就表示是同一个对象。 User user=findById(id); if(user!=null){ userList.remove(user); } return 1; } @Override public int updateUser(User user) { User user1=findById(user.getId()); //应该是修改,老蝴蝶这为了方便,先删除,再添加。 if(user1!=null){ userList.remove(user1); } userList.add(user); return 1; } @Override public List<User> findAll() { return userList; } @Override public User findById(int id) { for(User user:userList){ if(user.getId()==id){ return user; } } return null; } }
这里,省略service层, 直接Action层调用。
五.三 后端UserAction 实现
package com.yjl.action; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; 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.ResponseBody; import com.yjl.dao.UserDao; import com.yjl.pojo.User; /** @atuhor:yuejl @Description: 类描述 */ @Controller @RequestMapping(value="/user") public class UserAction { @Autowired private UserDao userDao; //转到登录的页面 @RequestMapping(value="toLogin") public String toLogin(Model model){ model.addAttribute("user",new User()); return "user/login"; } //在后端的时候, 用@PathVariable 注解进行接收REST 风格的传参。 //一定不要忘记添加 produces 属性。 添加时,方法为POST @RequestMapping(value="add",method=RequestMethod.POST,produces={"application/json"}) public @ResponseBody Map<String,Object> add(User user){ System.out.println("user:"+user.toString()); userDao.addUser(user); Map<String,Object> resultMap=new HashMap<String,Object>(); resultMap.put("request_status",true); return resultMap; } //修改时,方法为PUT @RequestMapping(value="edit/{id}",method=RequestMethod.PUT,produces={"application/json"}) public @ResponseBody Map<String,Object> edit(User user){ userDao.updateUser(user); Map<String,Object> resultMap=new HashMap<String,Object>(); resultMap.put("request_status",true); return resultMap; } //删除时,方法用DELETE @RequestMapping(value="deleteById/{id}",method=RequestMethod.DELETE,produces={"application/json"}) public @ResponseBody Map<String,Object> deleteById(@PathVariable(value="id") int id){ userDao.deleteUserById(id); Map<String,Object> resultMap=new HashMap<String,Object>(); resultMap.put("request_status",true); return resultMap; } //查询时,用GET @RequestMapping(value="findById/{id}",method=RequestMethod.GET,produces={"application/json"}) public @ResponseBody Map<String,Object> findById(@PathVariable(value="id") int id){ User user=userDao.findById(id); Map<String,Object> resultMap=new HashMap<String,Object>(); resultMap.put("request_status",true); resultMap.put("user",user); return resultMap; } //查询时,用GET @RequestMapping(value="findAll",method=RequestMethod.GET,produces={"application/json"}) public @ResponseBody Map<String,Object> findAll(){ List<User> userList=userDao.findAll(); Map<String,Object> resultMap=new HashMap<String,Object>(); resultMap.put("request_status",true); resultMap.put("userList",userList); return resultMap; } }
定义一个resultMap 对象, 返回json数据,为true表示成功,来提示前端。 前端根据request_status 来确定是否成功执行后端程序。
五.四 springmvc.xml 配置JSON
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <!-- 配置的是注解的,重写视图解析器 --> <context:component-scan base-package="com.yjl"></context:component-scan> <!--配置静态资源 --> <mvc:resources location="/js/" mapping="/js/**"></mvc:resources> <mvc:resources location="/css/" mapping="/css/**"></mvc:resources> <mvc:resources location="/image/" mapping="/image/**"></mvc:resources> <!-- 设置fastjson的配置方案 --> <mvc:annotation-driven> <!-- 设置不使用默认的消息转换器 --> <mvc:message-converters register-defaults="false"> <!-- 配置Spring的转换器 --> <bean class="org.springframework.http.converter.StringHttpMessageConverter"/> <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/> <!-- 配置fastjson中实现HttpMessageConverter接口的转换器 --> <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <!-- 加入支持的媒体类型:返回contentType --> <property name="supportedMediaTypes"> <list> <!-- 这里顺序不能反,一定先写text/html,不然ie下会出现下载提示 --> <value>text/html;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> <!-- 可添加其他的属性来扩展功能,如日期 --> <property name="features"> <list> <!-- 默认的意思就是不配置这个属性,配置了就不是默认了 --> <!-- 是否输出值为null的字段 ,默认是false--> <value>WriteMapNullValue</value> <value>WriteNullNumberAsZero</value> <value>WriteNullListAsEmpty</value> <value>WriteNullStringAsEmpty</value> <value>WriteNullBooleanAsFalse</value> <value>WriteDateUseDateFormat</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/"></property> <!-- 后缀 --> <property name="suffix" value=".jsp"></property> </bean> </beans>
五.六 web.xml 配置
配置过滤器, 顺序不能弄错。
<!--配置中文乱码过滤器--> <filter> <filter-name>EncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <!-- 类里面有一个属性 encoding,来动态注入编码 --> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <!-- 是否强制使用encoding的编码方式。 默认为false --> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置隐藏请求方法过滤器 --> <filter> <filter-name>hiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 过滤器 --> <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:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
五.七 前端Ajax 实现
<body> <h2>两个蝴蝶飞,REST使用</h2> <form:form commandName="user" type="post"> <button type="button" id="add" onclick="addJson()">添加</button><br/> <button type="button" id="edit" onclick="editJson()">修改</button><br/> <button type="button" id="delete" onclick="delJson()">删除</button><br/> <button type="button" id="findById" onclick="findByIdJson()">查询id></button><br/> <button type="button" id="findAll" onclick="findAllJson()">查询全部</button><br/> <div id="showId"> 展示的信息</div> </form:form> <script> function addJson(){ //添加一个id=10的数据 jsonAjax("add","add","id=10&name=精灵妹&password=1234&sex=女&age=24&description=一个快乐的精灵&_method=POST"); } function editJson(){ //修改id=10的数据, 修改名称和描述 jsonAjax("edit","edit/10","id=10&name=精灵妹&description=一个快乐的精灵哈哈&_method=PUT"); } function delJson(){ //删除id=10的元素 jsonAjax("delete","deleteById/10","_method=DELETE"); } function findByIdJson(){ //查询id=10的数据 jsonAjax("findById","findById/10","_method=GET"); } function findAllJson(){ //查询全部 jsonAjax("findAll","findAll","_method=GET"); } function jsonAjax(sign,url,data){ var message=""; switch(sign){ case "add":{ message="添加成功"; break; } case "edit":{ message="修改成功"; break; } case "delete":{ message="删除成功"; break; } case "findById":{ message="查询单个成功"; break; } case "findAll":{ message="查询全部成功"; break; } } $.ajax({ type:"post", url:url, //注意请求路径 data:data, success:function(resultData){ if(resultData.request_status){ //清空 $("#showId").empty(); //追加 $("#showId").append(message+"<br/>"); if(sign=="findById"){ var data=resultData.user; var str="<table><tr><th>编号</th><th>姓名</th><th>描述</th></tr>"; str+="<tr>"; str+="<td>"+data.id+"</td>"; str+="<td>"+data.name+"</td>"; str+="<td>"+data.description+"</td>"; str+="</tr>"; str+="</table>"; $("#showId").append(str); } if(sign=="findAll"){ var data=resultData.userList; var str="<table><tr><th>编号</th><th>姓名</th><th>描述</th></tr>"; $.each(data,function(idx,item){ str+="<tr>"; str+="<td>"+item.id+"</td>"; str+="<td>"+item.name+"</td>"; str+="<td>"+item.description+"</td>"; str+="</tr>"; }) str+="</table>"; $("#showId").append(str); } } } }) } </script> </body>
五.八 重启服务器,进行验证
刚进去时,是这样
点击查询全部, 进行显示全部的信息
点击添加按钮,进行添加
进行查询 id
点击修改按钮
修改后,再次查询id
点击查询全部,看删除前是什么内容
点击删除按钮,进行删除
再次点击查询全部,看是否删除成功
删除成功。
这只是REST 风格的小例子。
谢谢!!!