一般步骤:
总体结构如图:
1、web.xml
注:Spring配置文件分为两个,业务层和持久层的spring配置文件是classpath:/conf/applicationContext.xml,而web层(也是负责controller层)的spring配置文件是WEB-INF/baobaotao-servlet.xml,当输入某地址时,它首先会在web.xml中根据DispatcherServlet看url是否匹配,如果匹配就走入baobaotao-servlet.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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>easy_springmvc_test</display-name>
<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>
<!-- 业务层和持久层的spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/conf/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- 声明DispatcherServlet -->
<servlet>
<!-- 默认加载WEB-INF/baobaotao-servlet.xml 的spring配置文件,启动web层的spring容器 (注:默认是<name>-servlet.xml) -->
<servlet-name>baobaotao</servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- DispatcherServlet匹配的URL -->
<servlet-mapping>
<servlet-name>baobaotao</servlet-name>
<url-pattern>/</url-pattern>
<!--模式还可以写成 *.html -->
</servlet-mapping>
</web-app>
2、业务层、持久层及对应的spring配置文件
com.domain包下的实体类 User.java
// 相关注释需要用到jar :xstream.jar、validation-api-1.0.0.GA.jar、hibernate-validator-3.1.0.GA.jar
package domain;
import java.util.Date;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.Length;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
@XStreamAlias("message")
public class User {
@XStreamAsAttribute
@Pattern(regexp="w{4,30}")
private String userName;
@XStreamAsAttribute
@Pattern(regexp="S{6,30}")
private String password;
@XStreamAsAttribute
@Length(min=2,max=100)
private String realName;
@XStreamAsAttribute
@Past
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday;
@XStreamAsAttribute
@DecimalMin(value="1000.00")
@DecimalMax(value="100000.00")
@NumberFormat(pattern="#,###.##")
private long salary;
@XStreamOmitField
private Dept dept;
// get、set方法
}
com.service包下的UserService.java
package com.service;
import org.springframework.stereotype.Service;
import com.domain.User;
@Service
public class UserService {
public void createUser(User user){
System.out.println("save user.");
}
public User getUserById(String userId) {
...
}
}
配置文件:classpath:/conf/applicationContext.xml
会扫描com包下除去com.web包(该包放的是controller类型类)的其他所有类
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:component-scan base-package="com">
<context:exclude-filter type="aspectj" expression="com.web.*"/>
</context:component-scan>
</beans>
3、控制层的类及配置文件
com.web包下的UserController.java
类里的方法一般都会反馈逻辑视图名,以转化到对应视图。
关于@RequestMapping的注释,UserController整个类只有在/user的形式下(例如/user.html)才会用到,register()方法只有在/user/register的形式下才用到,createUser方法只有在/user的请求且请求方法必须是POST。
package com.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.domain.User;
import com.service.UserService;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/register")
public String register(){
return "user/register";
}
// 处理/user的请求,但是请求方法必须是POST
@RequestMapping(method = RequestMethod.POST)
public ModelAndView createUser(User user) {
userService.createUser(user);
ModelAndView mav = new ModelAndView();
// 逻辑视图名为user/createSuccess
mav.setViewName("user/createSuccess");
mav.addObject("user", user);
return mav;
}
}
WEB-INF/baobaotao-servlet.xml
注:扫描com.web下的所有controller类,类里的方法会携带逻辑视图名,比如逻辑视图是”user/register”,在视图解析器下,转到/WEB-INF/views/user/register.jsp页面。
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:component-scan base-package="com.web" />
<!-- 视图名称解析器,将视图逻辑名解析为/WEB-INF/views/<viewName>.jsp -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/"
p:suffix=".jsp"></bean>
</beans>
4、页面jsp
WEB-INF/views/user下的
register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%--
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
--%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>新增用户</title>
</head>
<body>
<form method="post" action='${pageContext.request.contextPath}/user.html' >
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="userName" value="${user.userName}"/></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password" value="${user.password}"/></td>
</tr>
<tr>
<td>姓名:</td>
<td><input type="text" name="realName" value="${user.realName}"/></td>
</tr>
<tr>
<td>生日:</td>
<td><input type="text" name="realName" value="${user.birthday}"/></td>
</tr>
<tr>
<td>工资:</td>
<td><input type="text" name="realName" value="${user.salary}"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" name="提交"/></td>
</tr>
</table>
</form>
</body>
</html>
createSuccess.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<title>用户创建成功</title>
</head>
<body>
恭喜,用户${user.userName}创建成功
</body>
</html>
5、运行结果
开始输入地址:http://localhost:8080/easy_springmvc_test/user/register.html
后来跳转地址:http://localhost:8080/easy_springmvc_test/user.html
6、运行流程分析
在访问http://localhost:8080/easy_springmvc_test/user/register.html 时,先根据web.xml中看看url是否匹配DispatcherServlet,如果匹配就步入web层(controller层)的配置文件WEB-INF/baobaotao-servlet.xml。该配置文件中先是扫描了com.web包下的所有controller类,所以扫描到了UserController.java,看看里面是否有方法能执行 /user/register.html,发觉register()方法可以,且该方法反馈的逻辑视图名为”user/register”,从该方法跳出来继续走baobaotao-servlet.xml中的下面的视图名称解析器,从而将解析为/WEB-INF/views/user/register.jsp,于是第一个页面出现了。
第一个页面提交时,表单的action=’${pageContext.request.contextPath}/user.html’,表示要转向http://localhost:8080/easy_springmvc_test/user.html,还是先从web.xml中分析DispatcherServlet到baobaotao-servlet.xml,依次还是扫描UserController.java,发觉处理/user的请求且请求方法是POST,故执行的方法是public ModelAndView createUser(User user),在执行此方法时register.jsp中的表单数据也传到了该方法的参数user中,该方法的方法体中反馈了逻辑视图名为”user/createSuccess”,把user也当做信息传输了一下。方法执行完退出继续配置文件中的视图解析器,页面解析为/WEB-INF/views/user/createSuccess.jsp,第二个页面也出现了,结束。