来自:http://blog.csdn.net/zdp072/article/details/38691049
一、核心原理
1. 用于发送请求给服务器: /home.htm
2. 请求被DispatchServlet拦截到
3. DispatchServlet通过HandleMapping检查url有没有对应的Controller, 如果有则调用Controller
4. Controller开始执行业务逻辑
5. Controller执行完毕后, 如果返回字符串, 则ViewResolver将字符串转化成相应的视图对象;
如果返回ModelAndView对象, 该对象本身就包含了视图对象信息.
6. DispatchServlet将视图对象中的数据输出给服务器.
7. 服务器将数据输出给客户端.
二、REST风格
1. 查询:
传统: /user_query?id=123
rest: /user/123
2. 删除:
传统: /user_delete?id=123
rest: /user/123/delete
3. 更新:
传统: /user_update?id=123
rest: /user/123/update
4. 列表:
传统: /user_list
rest: /user/users
三、增删改查
1. 代码结构
2. web.xml 配置DispatchServlet
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://java.sun.com/xml/ns/javaee"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
- http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
- <!-- user需要和配置文件user-servlet.xml名字对应 -->
- <servlet>
- <servlet-name>user</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>user</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- <!-- 配置过滤器, 设置编码为UTF-8 -->
- <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>
- </web-app>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- user需要和配置文件user-servlet.xml名字对应 -->
<servlet>
<servlet-name>user</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>user</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 配置过滤器, 设置编码为UTF-8 -->
<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>
</web-app>
<load-on-startup>1</load-on-startup>是启动顺序,让这个Servlet随Servletp容器一起启动。
<url-pattern>/</url-pattern> 会拦截所有的请求。
在DispatcherServlet的初始化过程中,框架会在web应用的 WEB-INF文件夹下寻找名为[servlet-name]-servlet.xml 的配置文件,
生成文件中定义的bean。我们配的是user,所以它会找到user-servlet.xml文件。
3. user-servlet.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:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.1.xsd">
- <!-- spring自动扫描的包名 -->
- <context:component-scan base-package="com.zdp"></context:component-scan>
- <!-- 使用spring注解 -->
- <mvc:annotation-driven />
- <!-- 设置返回url前缀和后缀 -->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
- <property name="prefix" value="/WEB-INF/jsp/"></property>
- <property name="suffix" value=".jsp"></property>
- </bean>
- <!-- 指明静态资源位置 -->
- <mvc:resources location="/WEB-INF/resources/" mapping="/resources/**"/>
- </beans>
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- spring自动扫描的包名 -->
<context:component-scan base-package="com.zdp"></context:component-scan>
<!-- 使用spring注解 -->
<mvc:annotation-driven />
<!-- 设置返回url前缀和后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 指明静态资源位置 -->
<mvc:resources location="/WEB-INF/resources/" mapping="/resources/**"/>
</beans>
<context:component-scan/> 扫描指定的包中的类上的注解,常用的注解有:
@Controller 声明Action组件
@Service 声明Service组件 @Service("userService")
@Repository 声明Dao组件
@Component 泛指组件, 当不好归类时.
@RequestMapping("/user") 将url和类绑定
@RequestParam("name") String username 用于将指定的请求参数赋给方法中的形参, 如果请求参数名称和形参一致, 则不需要这种写法
@Resource 用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName")
@Autowired 用于注入,(srping提供的) 默认按类型装配
@Transactional( rollbackFor={Exception.class}) 事务管理
@ResponseBody
@Scope("prototype") 设定bean的作用域
/WEB-INF/resources映射到ResourceHttpRequestHandler进行处理,location指定静态资源的位置.
配置了<mvc:annotation-driven />,spring会自动帮我们注册这个bean,就不须要我们显示的注册这个bean了。
4. User.java
- /**
- * 实体类
- */
- public class User {
- private String username;
- private String password;
- public User() {
- }
- public User(String username, String password) {
- this.username = username;
- this.password = password;
- }
- @NotEmpty(message="用户名不能为空")
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- @Size(min=1,max=10,message="密码的长度应该在1和10之间")
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- }
/**
* 实体类
*/
public class User {
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
@NotEmpty(message="用户名不能为空")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Size(min=1,max=10,message="密码的长度应该在1和10之间")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
5. UserController.java
- @Controller
- @RequestMapping("/user")
- public class UserController {
- // 使用map模拟数据库
- private Map<String, User> userMap = new HashMap<String, User>();
- public UserController() {
- userMap.put("zhangsan", new User("zhangsan", "123"));
- userMap.put("lishimin", new User("lishimin", "456"));
- }
- // 获取用户列表
- // 访问方法: http://localhost/springmvc_user/user/users
- @RequestMapping(value = "/users", method = RequestMethod.GET)
- public String list(Model model) {
- model.addAttribute("users", userMap);
- return "/user/list";
- }
- // 跳转到添加用户页面(get请求)
- // 访问方法: http://localhost/springmvc_user/user/add
- @RequestMapping(value = "/add", method = RequestMethod.GET)
- public String add(@ModelAttribute("user") User user) {
- return "user/add";
- }
- // 具体的添加用户处理方法(post请求)
- // 注意: BindingResult必须在User之后, 中间不能有其他的参数
- @RequestMapping(value = "/add", method = RequestMethod.POST)
- public String add(@Validated User user, BindingResult br) throws IOException { // @Validated: 对User数据进行校验
- if (br.hasErrors()) {
- return "user/add"; // 如果有错误, 则直接跳转到add添加用户页面
- }
- userMap.put(user.getUsername(), user);
- return "redirect:/user/users"; // 重定向到用户列表页面
- }
- // 查看用户信息
- // 访问方法: http://localhost/springmvc_user/user/zhangsan
- @RequestMapping(value="/{username}", method=RequestMethod.GET)
- public String show(@PathVariable String username, Model model) { // @PathVariable: 路径里面的值作为参数
- model.addAttribute(userMap.get(username));
- return "user/show";
- }
- // 跳转到修改用户信息页面
- // 访问方法: http://localhost/springmvc_user/zhangsan/update
- @RequestMapping(value="/{username}/update", method=RequestMethod.GET)
- public String update(@PathVariable String username, Model model) { // @PathVariable: 路径里面的值作为参数
- model.addAttribute(userMap.get(username)); // 等同: model.addAttribute("user", userMap.get(username));
- return "user/update";
- }
- // 具体的修改用户处理方法(post请求)
- // 注意: BindingResult必须在User之后, 中间不能有其他的参数
- @RequestMapping(value="/{username}/update", method=RequestMethod.POST)
- public String update(@PathVariable String username, @Validated User user, BindingResult br) {
- if(br.hasErrors()) {
- return "user/update"; // 如果有错误, 则直接跳转到update修改用户页面
- }
- userMap.remove(username);
- userMap.put(user.getUsername(), user);
- return "redirect:/user/users";
- }
- // 删除用户信息
- // 访问方法: http://localhost/springmvc_user/zhangsan/delete
- @RequestMapping(value="/{username}/delete",method=RequestMethod.GET)
- public String delete(@PathVariable String username) {
- userMap.remove(username);
- return "redirect:/user/users";
- }
- }
@Controller
@RequestMapping("/user")
public class UserController {
// 使用map模拟数据库
private Map<String, User> userMap = new HashMap<String, User>();
public UserController() {
userMap.put("zhangsan", new User("zhangsan", "123"));
userMap.put("lishimin", new User("lishimin", "456"));
}
// 获取用户列表
// 访问方法: http://localhost/springmvc_user/user/users
@RequestMapping(value = "/users", method = RequestMethod.GET)
public String list(Model model) {
model.addAttribute("users", userMap);
return "/user/list";
}
// 跳转到添加用户页面(get请求)
// 访问方法: http://localhost/springmvc_user/user/add
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String add(@ModelAttribute("user") User user) {
return "user/add";
}
// 具体的添加用户处理方法(post请求)
// 注意: BindingResult必须在User之后, 中间不能有其他的参数
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String add(@Validated User user, BindingResult br) throws IOException { // @Validated: 对User数据进行校验
if (br.hasErrors()) {
return "user/add"; // 如果有错误, 则直接跳转到add添加用户页面
}
userMap.put(user.getUsername(), user);
return "redirect:/user/users"; // 重定向到用户列表页面
}
// 查看用户信息
// 访问方法: http://localhost/springmvc_user/user/zhangsan
@RequestMapping(value="/{username}", method=RequestMethod.GET)
public String show(@PathVariable String username, Model model) { // @PathVariable: 路径里面的值作为参数
model.addAttribute(userMap.get(username));
return "user/show";
}
// 跳转到修改用户信息页面
// 访问方法: http://localhost/springmvc_user/zhangsan/update
@RequestMapping(value="/{username}/update", method=RequestMethod.GET)
public String update(@PathVariable String username, Model model) { // @PathVariable: 路径里面的值作为参数
model.addAttribute(userMap.get(username)); // 等同: model.addAttribute("user", userMap.get(username));
return "user/update";
}
// 具体的修改用户处理方法(post请求)
// 注意: BindingResult必须在User之后, 中间不能有其他的参数
@RequestMapping(value="/{username}/update", method=RequestMethod.POST)
public String update(@PathVariable String username, @Validated User user, BindingResult br) {
if(br.hasErrors()) {
return "user/update"; // 如果有错误, 则直接跳转到update修改用户页面
}
userMap.remove(username);
userMap.put(user.getUsername(), user);
return "redirect:/user/users";
}
// 删除用户信息
// 访问方法: http://localhost/springmvc_user/zhangsan/delete
@RequestMapping(value="/{username}/delete",method=RequestMethod.GET)
public String delete(@PathVariable String username) {
userMap.remove(username);
return "redirect:/user/users";
}
}
一般建议返回字符串, 但我们也可以返回ModelMap、ModelAndView、map、List、Set、Object、无返回值。
返回字符串: 根据返回值找对应的显示页面。路径规则为:prefix前缀 + 返回值 + suffix后缀组成
6. jsp pages
① list.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>用户列表 </title>
- <!-- 引入静态文件, 需要在user-servlet.xml配置映射关系 -->
- <link rel="stylesheet" href="<%=request.getContextPath()%>/resources/css/main.css" type="text/css">
- </head>
- <body>
- <a href="add">添加</a>
- <br/>
- <c:forEach items="${users}" var="usermap">
- <a href="${usermap.value.username}">${usermap.value.username}</a>
- -- <a href="${usermap.value.username}/update">修改</a>
- -- <a href="${usermap.value.username}/delete">删除</a><br/>
- </c:forEach>
- </body>
- </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户列表 </title>
<!-- 引入静态文件, 需要在user-servlet.xml配置映射关系 -->
<link rel="stylesheet" href="<%=request.getContextPath()%>/resources/css/main.css" type="text/css">
</head>
<body>
<a href="add">添加</a>
<br/>
<c:forEach items="${users}" var="usermap">
<a href="${usermap.value.username}">${usermap.value.username}</a>
-- <a href="${usermap.value.username}/update">修改</a>
-- <a href="${usermap.value.username}/delete">删除</a><br/>
</c:forEach>
</body>
</html>
② add.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>添加用户</title>
- </head>
- <body>
- <!-- 如没写action, 也会提交给add(匹配文件名) -->
- <sf:form method="post" modelAttribute="user" action="add">
- Username:<sf:input path="username"/><sf:errors path="username"/><br/>
- Password:<sf:password path="password"/><sf:errors path="password"/><br/>
- <input type="submit" value="添加用户"/>
- </sf:form>
- </body>
- </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>添加用户</title>
</head>
<body>
<!-- 如没写action, 也会提交给add(匹配文件名) -->
<sf:form method="post" modelAttribute="user" action="add">
Username:<sf:input path="username"/><sf:errors path="username"/><br/>
Password:<sf:password path="password"/><sf:errors path="password"/><br/>
<input type="submit" value="添加用户"/>
</sf:form>
</body>
</html>
③ show.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>用户详细信息</title>
- </head>
- <body>
- Username:${user.username}<br/>
- Password:${user.password}<br/>
- </body>
- </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户详细信息</title>
</head>
<body>
Username:${user.username}<br/>
Password:${user.password}<br/>
</body>
</html>
④ update.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>修改用户</title>
- </head>
- <body>
- <!-- 如没写action, 也会提交给update(匹配文件名) -->
- <sf:form method="post" modelAttribute="user" action="update">
- Username:<sf:input path="username"/><sf:errors path="username"/><br/>
- Password:<sf:password path="password"/><sf:errors path="password"/><br/>
- <input type="submit" value="修改用户"/>
- </sf:form>
- </body>
- </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>修改用户</title>
</head>
<body>
<!-- 如没写action, 也会提交给update(匹配文件名) -->
<sf:form method="post" modelAttribute="user" action="update">
Username:<sf:input path="username"/><sf:errors path="username"/><br/>
Password:<sf:password path="password"/><sf:errors path="password"/><br/>
<input type="submit" value="修改用户"/>
</sf:form>
</body>
</html>