1. 程式人生 > >springMVC之增刪改查

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>