简单的解释:
SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请求给相应的Handler,Handler处理以后再返回相应的视图(View)和模型(Model),返回的视图和模型都可以不指定,即可以只返回Model或只返回View或都不返回。
DispatcherServlet是继承自HttpServlet的,既然SpringMVC是基于DispatcherServlet的,那么我们需要配置一下DispatcherServlet,好让它能够管理我们希望它管理的内容。HttpServlet是在web.xml文件中声明的。
工作流程如下(如下图所示):
1.用户发送请求至 前端控制器DispatcherServlet。
2.前端控制器DispatcherServlet收到请求后调用处理器映射器HandlerMapping。
3.处理器映射器HandlerMapping根据请求的Url找到具体的处理器,生成处理器对象Handler及处理器拦截器HandlerIntercepter(如果有则生成)一并返回给前端控制器DispatcherServlet。
4.前端控制器DispatcherServlet通过处理器适配器HandlerAdapter调用处理器Controller。
5.执行处理器(Controller,也叫后端控制器)
6.处理器Controller执行完后返回ModelAnView。
7.处理器映射器HandlerAdapter将处理器Controller执行返回的结果ModelAndView返回给前端控制器DispatcherServlet。
8.前端控制器DispatcherServlet将ModelAnView传给视图解析器ViewResolver。
9.视图解析器ViewResolver解析后返回具体的视图View。
10.前端控制器DispatcherServlet对视图View进行渲染视图(即:将模型数据填充至视图中)
11.前端控制器DispatcherServlet响应用户。
(注意颜色)
通过例子来解释:
目录结构:
1.配置:
Servlet的配置: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/j2ee"
xmlns:javaee="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/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<!--指定一个首页 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<!--给 survlet 起个名字,可以是任意的,但要与下面一致-->
<servlet-name>MyDispatcher01</servlet-name>
<!-- servlet的路径(包名+类名)-->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 利用 init- param元素向 servlet提供初始化参数, init- param元素具有 param-name和 param-value子元素 -->
<init- param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value><!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 -->
</init- param>
</servlet>
<servlet-mapping>
<!--servlet名字,与上面要保持一致-->
<servlet-name>MyDispatcher01</servlet-name>
<!-- 这是在浏览器中输入的访问该 servlet的 url-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web- app>
Spring的配置:applicationContext.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" >
<bean id="loginController" class="com.pb.web.controller.LoginController">
<property name="successView" value="showAccount"></property>
<property name="failView" value="login"></property>
</bean>
<!-- HandlerMapping(处理器映射器)。当login.do,就使用loginController这个控制器 -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/login.do">loginController</prop>
</props>
</property>
</bean>
<!-- 对转向页面的路径解析(视图解析器)。prefix:前缀, suffix:后缀 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=". jsp"></property>
</bean>
</beans>
登录界面:login.jsp:
<%@ page language = "java" contentType= "text/html; charset=GB18030"
pageEncoding= "GB18030"%>
<! 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=GB18030">
< title> Insert title here</ title>
</ head>
< body>
${error }
<form action = "login.do" method= "post">
账号登陆 <br >
<hr >
卡号: <input type = "text" name= "cardNo">< br>
密码: <input type = "text" name= "password">< br>
<input type = "submit" value= "登陆">
</form >
</ body>
</ html>
2.控制层Controller(C):负责业务处理
packagecom.pb.web.controller;
importjava.util.HashMap;
importjava.util.Map;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.springframework.web.servlet.ModelAndView;
importorg.springframework.web.servlet.mvc.AbstractController;
importcom.pb.entity.Account;
//AbstractController实现了Controller接口,提供了handleRequestInternal方法,因此我们应该在具体的控制器类中实现handleRequestInternal方法,而不再是handleRequest
publicclass LoginController extendsAbstractController {
privateString successView;
privateString failView;
publicString getSuccessView() {
return successView;
}
publicvoid setSuccessView(String successView) {
this. successView = successView;
}
publicString getFailView() {
return failView;
}
publicvoid setFailView(String failView) {
this. failView = failView;
}
@Override
protectedModelAndView handleRequestInternal(HttpServletRequestrequest,HttpServletResponseresponse)throws Exception {
// TODOAuto-generated method stub
String cardNo= request.getParameter( "cardNo");
String password= request.getParameter( "password");
Account account =getAccount( cardNo, password);
Map<String ,Object>model=new HashMap<String,Object>();
if( account != null){
model.put( "account", account);
return new ModelAndView(getSuccessView(),model);
} else{
model.put( "error", "卡号和密码不正确" );
return new ModelAndView(getFailView(),model);//返回v和m,交给视图解析器viewResolver来解析展示结果
}
}
publicAccount getAccount(String cardNo,String password){
if( cardNo.equals( "123")&& password.equals( "123")){
Accountaccount = newAccount();
account.setCardNo( cardNo);
account.setBalance(88.8f);
return account;
} else{
return null;
}
}
}
3.模型层(M):
packagecom.pb.entity;
publicclass Account {
privateString cardNo;
privateString password;
privatefloat balance;
publicString getCardNo() {
return cardNo;
}
publicvoid setCardNo(String cardNo) {
this. cardNo = cardNo;
}
publicString getPassword() {
return password;
}
publicvoid setPassword(String password) {
this. password = password;
}
publicfloat getBalance() {
return balance;
}
publicvoid setBalance( floatbalance) {
this. balance = balance;
}
}
4.用户展示层(V):
<%@ page language ="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!DOCTYPEhtml PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type" content ="text/html; charset=GB18030">
<title>Insert title here</title>
</head>
<body>
账户信息 <br >
卡号:${account.cardNo }<br>
密码:${account.password }<br>
钱数:${account.balance }<br>
</body>
</html>
5.运行结果: