springMVC之增刪改查
一、核心原理
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>
<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>
<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;
}
}
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";
}
}
一般建議返回字串, 但我們也可以返回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>
② 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>
③ 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>
④ 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>