REST风格与传统风格比较
查询用户
传统方式 /user_detail?id=120
Rest风格 /user/120
删除用户
传统方式 /user_delete?id=123
Rest风格 /user/123/delete
修改用户
传统方式 /user_update?id=123
Rest风格 /user/123/update
获取列表
传统方式 /user_list
Rest风格 /users 或者 /user/users
JSR303
JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,官方参考实现是Hibernate Validator。
此实现与Hibernate ORM 没有任何关系。JSR 303 用于对Java Bean 中的字段的值进行验证。
Bean validation 下载地址: http://download.oracle.com/otndocs/jcp/bean_validation-1_1_0_cr1-pfd-spec/index.html
实例演示
实体类
package com.springmvc.demo.entity; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; /** * * User.java * * @version : 1.1 * * @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a> * * @since : 1.0 创建时间: 2013-4-13 上午10:42:20 * * TODO : * */ public class User { @NotNull(message="用户名不能为空") private String username; @NotNull(message="密码不能为空") @Size(min=4,max=10,message="密码长度必须在4-10的长度") private String password; @Pattern(regexp="^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+.[a-zA-Z]{2,5}?((.cn)|(.jp))?$", message="邮箱格式不正确") private String email; public User(){ } public User(String username, String password, String email) { super(); this.username = username; this.password = password; this.email = email; } //getter and setter }web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 配置字符过滤器,必须在OpenSessionInViewerFilter之前 --> <filter> <filter-name>CharacterFilter</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> </filter> <filter-mapping> <filter-name>CharacterFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>dispatcher</servlet-name> <!-- 此处用的是dispacter,所以同目录下的想xml文件名应该为dispacter-servlet.xml --> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd "> <!-- 指定使用注解方式配置,配置自动扫描的包名, base-package指定自己应用中控制器所在的包目录 <context:component-scan/> 扫描指定的包中的类上的注解,常用的注解有: @Controller 声明Action组件 @Service 声明Service组件 @Service("myMovieLister") @Repository 声明Dao组件 @Component 泛指组件, 当不好归类时. @RequestMapping("/menu") 请求映射 @Resource用于注入,( j2ee提供的 ) 默认按名称装配, @Resource(name="beanName") @Autowired用于注入,(srping提供的) 默认按类型装配 @Transactional(rollbackFor={Exception.class}) 事务管理 @ResponseBody @Scope("prototype")设定bean的作用域 --> <context:component-scan base-package="com.springmvc.demo.controller" /> <!-- 默认的注解映射的支持 --> <!-- JSR-303 support will be detected on classpath and enabled automatically --> <mvc:annotation-driven/> <!-- http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch05s07.html --><!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置视图层 使用jstl标签 --> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <!-- 定义视图前缀格式 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 定义视图后缀格式 --> <property name="suffix" value=".jsp" /> </bean> </beans>控制器
package com.springmvc.demo.controller; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.springmvc.demo.entity.User; /** * * UserController.java * * @version : 1.1 * * @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a> * * @since : 1.0 创建时间: 2013-4-13 下午06:21:34 * * TODO : * */ @Controller @RequestMapping(value="/user") public class UserController { private Map<String,User> users = new HashMap<String, User>(); public UserController(){ users.put("suruonian", new User("suruonian","suruonian","suruonian@demo.com")); users.put("linyunxi", new User("linyunxi","linyunxi","linyunxi@163.com")); users.put("dennisit", new User("dennisit","dennisit","dennisit@163.com")); users.put("moshaobai", new User("moshaobai","bing_he","1325103287@qq.com")); } /** * * * Description: 构建REST风格 /user/users的GET请求时才执行该方法的操作RequestMethod.GET表示 * 只处理GET请求 * @param model 用于上下文参数传递 * @return 视图页面 user/list 结合user-servlet.xml中配置的视图模型匹配视图页面 * 实例中方法返回表示/WEB-INF/jsp/user/list.jsp页面 * */ @RequestMapping(value="/users",method=RequestMethod.GET) public String list(Model model){ model.addAttribute("users", users); return "user/list"; } /** * * * Description: 链接到页面时是GET请求,执行该方法 <a href="add">添加</a> * @return 返回给用户添加页面 * */ @RequestMapping(value="/add",method=RequestMethod.GET) public String add(Model model){ model.addAttribute("user",new User()); //开启ModelDriven 跳转到增加页面时使用该Model return "user/add"; } /** * * Description: 添加操作 请求/user/add form表单提交时使用的post请求调用该方法 * @param user 添加的User对象 * @param br 验证绑定 * @return 视图页面 * 添加成功 请求重定向redirect:/user/users 表示执行操作结束后请求定向为/user/users * 添加失败 页面转到/WEB-INF/jsp/add.jsp 这里有验证绑定,将在视图页面展示验证错误信息 * */ @RequestMapping(value="/add",method=RequestMethod.POST) public String add(@Validated User user,BindingResult br){ //需要说明的是BindingResult形参一定要跟@Validated修饰的形参后面写验证 if(br.hasErrors()){ //如果有错误,直接跳转到添加视图 return "user/add"; //服务端跳转 该跳转会自动在前面增加 forward } users.put(user.getUsername(), user); return "redirect:/user/users"; //客户端跳转 使用 redirect } /** * * * Description: 查看操作 根据用户名查看 REST风格: /detail/查看的用户名 * @param username 带查看的用户名@PathVariable 修饰username 表示用请求路径中的username作为 形参 * @param model 携带数据的Model * @return 视图页面 /WEB-INF/jsp/user/detail.jsp页面 * */ @RequestMapping(value="/{username}",method=RequestMethod.GET) public String detail(@PathVariable String username, Model model){ System.out.println("获取到传入的参数值为:" + username); model.addAttribute("user", users.get(username)); return "user/detail"; } /** * * * Description: 预更新操作根据用户名查询用户信息 然后数据交给携带体 展示到视图 REST风格: /更新的用户的用户名/update * @param username @PathVariable修饰 表示形参同URL中的请求参数 * @param model 携带数据的Model * @return 视图页面/WEB-INF/jsp/user/update页面 * */ @RequestMapping(value="/{username}/update",method=RequestMethod.GET) public String update(@PathVariable String username, Model model){ System.out.println("获取到传入的参数值为:" + username); model.addAttribute(users.get(username)); return "user/update"; } /** * * * Description: 真正更新的操作 REST风格: /更新的用户的用户名/update * @param username 带更新的用户的用户名 * @param user 带更新的用户的信息对象 @Validated修饰表示信息需要被验证 * @param br 验证信息绑定对象 必须紧跟在待验证的信息形参后面 * @return 视图页面 * 更新成功 请求重定向 /user/users * 更新失败 转到/WEB-INF/jsp/user/update.jsp页面 * */ @RequestMapping(value="/{username}/update",method=RequestMethod.POST) public String update(@PathVariable String username, @Validated User user,BindingResult br){ if(br.hasErrors()){ //如果有错误,直接跳转到修改视图 return "user/update"; } users.put(username, user); return "redirect:/user/users"; } /** * * * Description: 删除操作 REST风格:/删除的用户名/delete * @param username 删除的用户名 类似表主键,可以标记到整个记录信息 * @return 视图页面 * 请求重定向到 /user/users * */ @RequestMapping(value="/{username}/delete",method=RequestMethod.GET) public String delete(@PathVariable String username){ System.out.println("获取到传入的参数值为:" + username); users.remove(username); return "redirect:/user/users"; } }
视图层/WEB-INF/jsp/user/下的list.jsp,add.jsp,detail.jsp,update.jsp文件
list.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path; %> <!DOCTYPE HTML> <html> <head> <base href="<%=basePath%>"> <title><%=basePath%></title> </head> <body> <h2>用户信息展示</h2> <p><a href="<%=basePath %>/user/add">添加信息</a></p> <c:forEach items="${users}" var="usermap"> 姓名: <a href="<%=basePath %>/user/${usermap.value.username }">${usermap.value.username} </a> 密码: ${usermap.value.password } 邮箱: ${usermap.value.email } <a href="<%=basePath %>/user/${usermap.value.username }/update">修改</a> <a href="<%=basePath %>/user/${usermap.value.username }/delete">删除</a> <br/> </c:forEach> </body> </html>
add.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML> <html> <head> <base href="<%=basePath%>"> <title><%=basePath%></title> </head> <body> <h2>增加用户信息页面</h2> <br> <!-- 此时没有写action,直接提交会提交给/add --> <sf:form method="post" modelAttribute="user"> 姓名:<sf:input path="username"/> <sf:errors path="username" /> <br/> 密码:<sf:password path="password"/> <sf:errors path="password" /> <br/> 邮箱:<sf:input path="email"/> <sf:errors path="email" /> <br/> <input type="submit" value="添加" /> </sf:form> </body> </html>
detail.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path; %> <!DOCTYPE HTML> <html> <head> <base href="<%=basePath%>"> <title><%=basePath%></title> </head> <body> <h2>用户详细信息页面</h2> <br> 姓名: ${user.username} <br> 密码: ${user.password } <br> 邮箱: ${user.email } <br/> <a href="<%=basePath %>/user/users">返回用户列表</a> </body> </html>
update.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path; %> <!DOCTYPE HTML> <html> <head> <base href="<%=basePath%>"> <title><%=basePath%></title> </head> <body> <h2>修改用户信息页面</h2> <br> <!-- 此时没有写action,直接提交会提交给/update --> <sf:form method="post" modelAttribute="user"> 姓名:<sf:input path="username"/> <sf:errors path="username" /> <br/> 密码:<sf:password path="password"/> <sf:errors path="password" /> <br/> 邮箱:<sf:input path="email"/> <sf:errors path="email" /> <br/> <input type="submit" value="修改" /> </sf:form> </body> </html>
作者:苏若年
链接:http://www.cnblogs.com/dennisit/archive/2013/04/13/3019391.html]