1.web.xml
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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">
<display-name>02_spring_mvc_user</display-name>
<filter>
<filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- springMVC 1.创建servlet -->
<servlet>
<!-- 需要在WEB-INF下面创建对应的hello-servlet.xml -->
<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>
<!-- 捕获所有请求,基于rest -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--
OS(OpenSymphony)的SiteMesh是一个用来在JSP中实现页面
布局和装饰(layout and decoration)的框架组件,
能够帮助网站开发人员较容易实现页面中动态内容和静态装饰外观的分离
-->
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
2.user-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- springMVC 2.创建对应的servlet -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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">
<!-- 开启SpringMVC -->
<mvc:annotation-driven/>
<context:component-scan base-package="cn.edu.zttc.controller"></context:component-scan>
<mvc:resources location="/resources/" mapping="/resources/**"/>
<!-- 配置视图的前缀和后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property> -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="5000000"></property>
</bean>
</beans>
3.decorators.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
装饰者,将所有页面都潜入basic的页面之中,使用
<decorator:body />标签
被嵌入的页面不用填写html的头标签等,只需要写body信息
-->
<decorators defaultdir="/WEB-INF/temp/">
<!-- Any urls that are excluded will never be decorated by Sitemesh -->
<excludes>
<pattern>/json*</pattern>
</excludes>
<decorator name="main" page="basic.jsp">
<pattern>/*</pattern>
</decorator>
</decorators>
4.basic.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<!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>Insert title here</title>
</head>
<body>
<h1>
User Manager
</h1>
<hr/>
<decorator:body />
</body>
</html>
5.error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@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>error</title>
</head>
<body>
${ex.message }
</body>
</html>
6.login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@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>Insert title here</title>
</head>
<body>
<form method="post">
username<input type="text" name="username"/><br/>
password<input type="password" name="password"/><br/>
<input type="submit"/>
</form>
</body>
</html>
7.add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@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>Insert title here</title>
</head>
<body>
<sf:form method="post" modelAttribute="user" enctype="multipart/form-data">
username<sf:input path="username"/><sf:errors path="username"/><br/>
password<sf:input path="password"/><sf:errors path="password"/><br/>
nickname<sf:input path="nickname"/><br/>
email<sf:input path="email"/><sf:errors path="email"/><br/>
file<input type="file" name="files"/><br/>
file<input type="file" name="files"/><br/>
<input type="submit"/>
</sf:form>
</body>
</html>
8.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">
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/resources/css/main.css">
<title>Insert title here</title>
</head>
<body>
${loginUser.nickname}----${redir}<br/>
<a href="add">添加用户</a>
<a href="login">用户登录</a><br/>
<!-- 获取的是map,所以需要先.value -->
<c:forEach items="${users }" var="user">
<a href="${user.value.username}">查看用户</a><a href="${user.value.username}/update">更新</a><a href="${user.value.username}/delete">删除</a>${user.value.username }=====${user.value.nickname }<br/>
</c:forEach>
</body>
</html>
9.show.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>Insert title here</title>
</head>
<body>
${user.username }=====${user.nickname }=====${user.email }<br/>
</body>
</html>
10.update.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@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>Insert title here</title>
</head>
<body>
<sf:form method="post" modelAttribute="user">
username<sf:input path="username"/><sf:errors path="username"/><br/>
password<sf:input path="password"/><sf:errors path="password"/><br/>
nickname<sf:input path="nickname"/><br/>
email<sf:input path="email"/><sf:errors path="email"/><br/>
<input type="submit"/>
</sf:form>
</body>
</html>
11.UserController
package cn.edu.zttc.controller;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
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.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import cn.edu.zttc.vo.User;
import cn.edu.zttc.vo.UserException;
/**
* springMVC加入了JSR303(Bean Validate的功能)
* @author admin
*/
@Controller
@RequestMapping("/user")
@SessionAttributes(value="loginUser")
public class UserController {
private final static Map<String, User> users = new HashMap<String, User>();
public UserController(){
users.put("ldh", new User("ldh", "123", "ldh@163.com", "华仔"));
users.put("zxy", new User("zxy", "123", "ldh@163.com", "学友"));
users.put("gfc", new User("gfc", "123", "ldh@163.com", "郭富城"));
users.put("lm", new User("lm", "123", "ldh@163.com", "黎明"));
}
/**
* 获取用户列表
* @param model
* @return
*/
@RequestMapping({"/users","/"})
public String list(Model model){
model.addAttribute("users",users);
return "user/list";
}
/**
* 跳转到添加页面
* @param model
* @return
*/
@RequestMapping(value="/add",method=RequestMethod.GET)
public String add(Model model){
model.addAttribute(new User());
return "user/add";
}
/**
*
* 添加页面提交请求,post方式
* @param user
* @param file 上传文件方式
* @param binding 接收错误信息的(必须要在要进行验证的对象之后)
* @return
*/
//参数user与页面的form表单中的modelAttribute的值一样
@RequestMapping(value="/add",method=RequestMethod.POST)
public String add(@Valid User user,BindingResult binding,@RequestParam MultipartFile[] files,HttpServletRequest req){
if (binding.hasErrors()) {
return "user/add";
}
// System.out.println(file.getContentType()+","+file.getName()+","+file.getOriginalFilename());
String realPath = req.getSession().getServletContext().getRealPath("/resources/upload");
for(MultipartFile file:files){
try {
System.out.println(realPath);
FileUtils.copyInputStreamToFile(file.getInputStream(), new File(realPath+"/"+file.getOriginalFilename()));
} catch (IOException e) {
e.printStackTrace();
}
}
users.put(user.getUsername(), user);
//执行客户端跳转
return InternalResourceViewResolver.REDIRECT_URL_PREFIX+"/user/users";
}
/**
* 显示用户信息
* @param username
* @param model
* @return
*/
@RequestMapping(value="/{username}",method=RequestMethod.GET)
public String show(@PathVariable String username,Model model){
model.addAttribute(users.get(username));
return "user/show";
}
/**
* 跳转到更新页面
* @param username
* @param model
* @return
*/
@RequestMapping(value="/{username}/update",method=RequestMethod.GET)
public String update(@PathVariable String username,Model model){
model.addAttribute(users.get(username));
return "user/update";
}
/**
* 更新页面提交请求
* @param username
* @param user
* @param br 接收错误信息的
* @return
*/
//参数user与页面的form表单中的modelAttribute的值一样
@RequestMapping(value="/{username}/update",method=RequestMethod.POST)
public String update(@PathVariable String username,@Valid User user,BindingResult br){
if (br.hasErrors()) {
return "user/update";
}
users.put(username, user);
return InternalResourceViewResolver.REDIRECT_URL_PREFIX+"/user/users";
}
/**
* 删除操作
* @param username
* @return
*/
@RequestMapping(value="/{username}/delete",method=RequestMethod.GET)
public String delete(@PathVariable String username){
users.remove(username);
return InternalResourceViewResolver.REDIRECT_URL_PREFIX+"/user/users";
}
/**
* 跳转到登录页面
* @return
*/
@RequestMapping(value="/login",method=RequestMethod.GET)
public String login(){
return "user/login";
}
/**
* 登录提交页面
* @param username
* @param password
* @return
*/
@RequestMapping(value="/login",method=RequestMethod.POST)
public String login(String username,String password,Model model){
if (!users.containsKey(username)) {
throw new UserException("用户名不存在");
}
if (!password.equals(users.get(username).getPassword())) {
throw new UserException("用户名密码不正确");
}
model.addAttribute("loginUser",users.get(username));
return InternalResourceViewResolver.REDIRECT_URL_PREFIX+"/user/users";
}
/**
* 捕获异常执行的方法
* @return
*/
@ExceptionHandler(UserException.class)
public String handlerException(Exception ex,HttpServletRequest req){
req.setAttribute("ex", ex);
return "error";
}
/**
* redirect方式传request范围的对象
* @param model
* @param ra
* @return
*/
@RequestMapping(value="/redir")
public String redir(Model model,RedirectAttributes ra){
ra.addFlashAttribute("redir","我的redirect方式传request范围的对象");
return InternalResourceViewResolver.REDIRECT_URL_PREFIX+"/user/users";
}
}
12.User
package cn.edu.zttc.vo;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
public class User {
private String username;
private String password;
private String email;
private String nickname;
public User() {
super();
}
public User(String username, String password, String email, String nickname) {
super();
this.username = username;
this.password = password;
this.email = email;
this.nickname = nickname;
}
@NotEmpty(message="用户名不能为空")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@NotEmpty(message="密码不能为空")
@Size(min=1,max=20,message="密码长度应在1-20之间")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Pattern(regexp="^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$",message="邮箱格式不正确")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
13.UserException
package cn.edu.zttc.vo;
public class UserException extends RuntimeException {
private static final long serialVersionUID = 1L;
public UserException() {
super();
// TODO Auto-generated constructor stub
}
public UserException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public UserException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public UserException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}
项目结构图:
引入的包: