Spring MVC 体系结构和处理请求控制器
1.MVC设置模式
- 数据访问接口:DAO层
- 处理业务逻辑:Service层
- 数据实体:POJO
- 负责前端请求的接受并处理:Servlet
- 负责前端页面展示:JSP
2.1 JSP Model1
主要还是通过JSP页面和业务逻辑处理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L2mwazHr-1571626776347)(C:\Users\lw\Desktop\20160626172053254.jpg)]
2.2 JSP Model2
把业务流程控制交给控制器来实现,JSP专注于视图的展示即可
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KwKwznvN-1571626776348)(C:\Users\lw\Desktop\20160626172036334.jpg)]
3.Spring MVC环境搭建
- 引入jar文件
- Spring MVC配置
- 创建Controller(处理请求的控制器)
- 创建View
- 部署运行
4.Spring MVC框架的请求处理流程及体系结构
4.1 Spring MVC框架的请求处理流程
- 实现用户发送请求到前端控制器,前端控制器根据请求信息,来决定来选择哪个页面控制器来运行处理,并把请求委托给它,即Servlet控制器的控制逻辑部分
- 页面控制器接受到请求后,进行业务处理,处理完毕后返回一个ModelAndView
- 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的真正视图,并把模型数据传入以便将视图渲染展示
- 前端控制器再次收回控制权,将响应结果返回给用户
4.2 Spring MVC框架的体系结构
- 客户端发出HTTP请求,Web应用服务器接收此请求。如匹配DispatcherServlet的请求映射路径,则Web容器将该请求转交给DispatcherServlet处理;
- DispatcherServlet拿到请求之后,根据请求的信息(URL、请求参数、HTTP方法等)及HandlerMapping的配置找到处理请求的处理器(Handler);
- 当DispatcherServlet找到相应的Handler之后,通过HandlerAdapter对Handler进行封装,再以统一的适配器接口调用Handler。HandlerAdapter可以理解为真正使用Handler来干活的人。
- 在请求信息真正到达调用Handler的处理方法之前的这段时间,Spring MVC还完成了很多工作,它会将请求信息以一定的方式转换并绑定到请求方法的入参,对于入参的对象会进行数据转换、数据格式化以及数据校验等。这些都做完以后,最后才真正调用Handler的处理方法进行相应的业务逻辑处理。
- 处理器完成业务处理之后,将一个ModelAndView对象返回给DispatcherServlet,其中包含了逻辑视图名和模型数据信息。
- 处理器完成业务处理之后,将一个ModelAndView对象返回给DispatcherServlet,其中包含了逻辑视图名和模型数据信息。
- 得到真正的视图对象之后,DispatcherServlet会根据ModelAndView对象中的模型数据对View进行视图渲染。
- 最终客户端获得响应消息。
4.2.1 Spring MVC 框架的特点
- 清晰的角色划分,Spring MVC在Model,View和Controller方面提供了一个非常清晰的角色划分,这三个方面真正是各司其职,各负其责
- 灵活的配置功能
- 提供了大量的控制器接口和实现类,开发者可以使用Spring提供的控制权实现类,也可以自己实现控制器接口
- 真正做到与View层的实现无关
- 国际化支持
- 面向接口编程
- Spring提供了Web应用开发的一整套流程,不仅仅是MVC,它们之间可以很方便地结合一起
5.参数传递(View to Controller)
1.@RequestMapping
@RequestMapping(value = "/welcome",method = RequestMethod.GET,params = "username")
public String welcome(@RequestParam String username){
logger.info("welcome:"+username);
return "indxe";
}
2.@RequestParam
- value:参数名
- required:是否必需,默认为true,表示请求中必须包含对应的参数名,若不存在将抛出异常
- defaultValue;默认参数名,不推荐使用
6.参数传递(Controller to View)
1.ModelAndView
(1)添加模型数据
- ModelAndView addObject(String attributeName,Object attriteValue):该方法的第一个参数为key值,第二个参数为key对应的value
- ModelAndView addAllObjects(Map<String,?>modelMap):从此方法中可以看出,模型数据也是一个Map对象,我们可以添加Map对象到Model中
(2)设置视图
- void setView(View view):指定一个具体的视图对象
- void setViewName(String viewName):指定一个逻辑视图名
2.Model
除了可以使用ModelView对象来返回模型数据外,我们还可以使用Spring MVC 提供的Model对象来完成模型数据的传递
3.Map
@RequestMapping("/index3")
public String index3(String username, Map<String,Object> model){
logger.info("hello,SpringMVC! username:"+username);
model.put("username",username);
return "index";
}
SpringMVC+JDBC框架
7.SpringMVC
1)MVC模型
M-Model模型
模型(Model)的职责是负责业务逻辑,包含两层:业务数据和业务处理逻 辑,比如实体类,DAO,Service都属于模型层
V-View视图
视图(View)的职责是负责显示界面和用户交互(收集用户信息),属于视图层的 组件是不包含业务逻辑和控制逻辑的JSP
C-Controller控制器
控制器是模型层与视图层之间的桥梁,用于控制流程,比如在Servlet项目中 单一控制器ActionServlet
2) 什么是SpringMVC
SpringMVC是Spring框架中一个功能模块,实现了MVC结构,便于简单,快 速开发的MVC结构的WEB程序,SpringMVC提供的API封装了WEB开发中常 用的 功能,简化了WEB过程
3) Spring MVC的核心组件
Spring MVC提供了M,V和C相关的主要实现组件,具体如下: DispatcherServlet(控制器,请求入口)
HandlerMapping(控制器,请求派发)
Controller(控制器,请求处理流程)
ModelAndView(模型,封装)
ViewResolver(视图、视图显示处理器)
4) Spring处理流程
浏览器向服务器发送请求,请求交给前端控制器DispatcherServlet处理,前端控 制通过HandlerMapping找到相对应的Controller,执行Controller组件的约定方 法处理请求,在约定方法中调用模型层组件完成业务处理,约定方法返回一个 ModelAndView对象,此对象封装了处理结果数据和视图名称信息,前端控制 器接收到ModelAndView之后调用ViewResolver来定位View(JSP),传递数据信 息,生成响应页面
8.基于XML配置的MVC应用
搭建Spring MVC环境
1) 创建WEB工程,导入SpringMVC相关开发包:Spring IOC,web,webMVC等开 发包
2) 在src下添加Spring XML配置文件,名称可以自定义,例如spring-mvc.xml
<!-- 声明Controller --> <bean id="helloController" class="com.xms.controller.HelloController"></bean> <!-- 定义请求处理映射HandlerMapping --> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <!-- 指定请求和Controller对应关系 --> <property name="mappings"> <props> <prop key="/hello/hello.do">helloController</prop> </props> </property> </bean> <!-- 定义视图解析器 ViewResolver--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean>
3) 在web.xml中配置DispatcherServlet前端控制器组件,DispatcherServlet组件 在Spring MVC中已提供,只需要配置即可,配置DispatcherServlet时,同时指定 XML配置文件
<servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
Controller组件负责执行具体的业务处理,编写时需要实现Controller接口及约定 方法HandleRequest
Controller接口及约定方法handleRequest
public class HelloController implements Controller { public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { System.out.println("Hello.Spring MVC"); return new ModelAndView("hello"); }}
Controller组件中约定的handleRequest方法执行后会返回一个ModelAndView对 象,此对象封装模型数据和视图名称ModelAndView(String
viewName)ModelAndView(String viewName,Model model) viewName是视图 名称,model是业务处理的数据 通过HandlerMapping组件,DispatcherServlet 控制器可以将客户端的Http请求映射到对应的Controller组件上
SimpleUrlHandlerMapping维护一个Http请求和Controller映射关系表(Map),根 据列表对应关系调用Controller ViewResolver组件,Controller组件返回一个 ModelAndView对象,Spring中的视图以名字为标识,视图解析器 ViewResolver通过名字来解析视图 InternalResourceViewResolver: UrlBasedViewResolver的子类,它支持InternalResourceView(对Servlet和JSP的 包装),以及子类 JstlView和TitlesView响应类型3. 基于注解配置的MVC应用推 荐使用@Controller声明Controller组件,可以使Controller控制器更加灵活,可 以不用实现Controller接口,请求处理方法也可以灵活的定义。 为了使 @Controller注解生效,需要在Spring的XML配置文件中开启组件扫描 定义。 context:componnent-scanbase-package=""/
@RequestMapping注解可以使用类定义和方法定义上,表明此组件或方法与哪一个请求对应。
@Controller@RequestMapping("/demo") //命名空间public class HelloController { @RequestMapping("/hello.do") //地址 public ModelAndView execute(){ System.out.println("hello.Controller"); return new ModelAndView("/jsp/hello");
}}
9.JSpring对JDBC整合
1) spring对DAO异常提供统一处理
2) spring对DAO编写提供支持的抽象类
3) 提供编程效率,减少JDBC编码量
JdbcTemplate
封装了连接获取以及连接释放等工作,从而简化我们对JDBC的使用避免忘记关闭连接等错误
JdbcTemplate提供以下主要方法:
queryForInt()
queryForObject()
query()
update()
execute()
基于jdbc技术编写DAO组件可以采用以下两种方式:
-
DAO继承JdbcDaoSupport,通过getJdbcTemplate()方法来获取JdbcTemplate对象,需要在DAO实现类中注入一个DataSource对象来完成JdbcTemplate的实例化
-
DAO组件不继承JdbcDaoSupport,在Spring容器中配置一个JdbcTemplate的Bean,然后注入给DAO实现类
10.Spring+ JDBC Template
-
创建工程,搭建Spring MVC和JDBC技术环境 引入数据库驱动包 引入DBCP连接池开发包 添加Spring相关技术环境 引入Spring IoC 在src下添加spring.xml web.xml. 配置DispatcherServlet主控制器
-
基于jdbcTemplate实现DAO组件 根据数据表编写实体类 编写DAO接口和实现类 在Spring容器中配置DAO实现类 定义DAO对象,注入jdbcTemplate
-
编写和配置Spring MVC 主要组件,如Controller HandlerMapping, viewResolver 编写Controller和请求处理方法 配置mvc:annotation-driven/支持@Requestmapping 配置Controller组件 开启组件扫描,将Controller扫描到Spring容器 需要DAO时采用注入方式注入 在请求处理方法上使用@RequestMapping指定对应请求配置ViewResolver
-
编写JSP视图组件,利用JSTL标签和EL表达式显示数据
Spring MVC扩展和SSM框架整合
11.JSON对象的处理
11.1. 使用@ResponseBody实现数据输出
1)DAO层,Service层
DAO层(UserDao.java,UserDaoImpl.java)提供一个通过userCode获取User对象的方法即可。Service(UserService.java,UserServiceImpl.java)同上
2)改造Controller层
修改UserController.java,增加通过用户名(userCode)进行同名验证的处理方法
@RequestMapper(value="ucexist.html")
@ResponeseBody
public Object userCodeIsExit(@RequestParam String userCode){
logger.debug("userCodeIsExit userCode:"+userCode);
HashMap<String, String> resultMap = new HashMap<String,String>();
if(StringUtils.isNullOrEmpty(userCode)){
resultMap.put("userCode","exist");
}else{
User user = userService.selectUserCodeExist(userCode);
if(null != user){
resultMap.put("userCode","exist");
}else{
resultMap.put("userCode","noexist");
}
}
return JSONArray.toJSONString(resultMap);
}
3)改造View层
userCode.bind("blur",function(){
$.ajax({
type:"GET",
url:path+"/user/ucexist.html",
data:{userCode:userCode.val()},
dataType:"json",
success:function(data){
if(data.userCode == "exist"){
validateTip(userCode.next(),{"color":"red"},imgNo+"该用户账号已存在",false);
}else{
validateTip(userCode.next(),{"color":"green"},imgYes+"该账号可以使用",true)
}
},
error:function(data){
validateTip(userCode.next(),{"color":"red"},imgNo+"您访问的页面不存在",false);
}
})
}).bind("focus",function(){
validateTip(userCode.next(),{"color":"#666"},"* 用户编码是您登陆系统的账号",false)
}).focus();
12.框架整合(Spring MVC+Spring+Mabatis)
1.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<welcome-file-list>
</welcome-file-list>
<!-- 监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 加载app.xml文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:app.xml</param-value>
</context-param>
<!-- 前端控制器 -->
<servlet>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 过滤器设置字符编码UTF-8 -->
<filter>
<filter-name>characterEncoding</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>characterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2.配置文件
(1)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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 扫包 -->
<context:component-scan base-package="cn.xxxx.service"></context:component-scan>
<!-- 读取jdbc配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- JNDI获取数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" scope="singleton">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${uname}" />
<property name="password" value="${password}" />
</bean>
<!-- 事务管理 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 使用aop管理事务 -->
<tx:advice id="advice">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="uodate*" propagation="REQUIRED"/>
<tx:method name="query*" propagation="NEVER" read-only="true"/>
<tx:method name="get*" propagation="NEVER" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* cn.xxxx.service..*.*(..))" id="pointcut1"/>
<aop:advisor advice-ref="advice" pointcut-ref="pointcut1"/>
</aop:config>
<!-- 配置mybitas SqlSessionFactoryBean-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
<!-- Mapper接口所在包名,Spring会自动查找其下的Mapper -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.xxxx.mapper" />
</bean>
</beans>
(2)springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
4 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
5 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
6 xsi:schemaLocation="http://www.springframework.org/schema/beans
7 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
8 http://www.springframework.org/schema/context
9 http://www.springframework.org/schema/context/spring-context-2.5.xsd
10 http://www.springframework.org/schema/aop
11 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
12 http://www.springframework.org/schema/tx
13 http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
14 http://www.springframework.org/schema/mvc
15 http://www.springframework.org/schema/mvc/spring-mvc.xsd">
16
17 <!-- 扫包 -->
18 <context:component-scan base-package="cn.xxxx.controller"></context:component-scan>
19
20 <!-- JSON格式转换-->
21 <mvc:annotation-driven>
22 <mvc:message-converters>
23 <bean
24 class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
25 <property name="supportedMediaTypes">
26 <list>
27 <value>text/html;charset=UTF-8</value>
28 <value>applcation/json</value>
29 </list>
30 </property>
31 <property name="features">
32 <list>
33 <value>WriteDateUseDateFormat</value>
34 </list>
35 </property>
36 </bean>
37 <bean class="org.springframework.http.converter.StringHttpMessageConverter">
38 <property name="supportedMediaTypes">
39 <list>
40 <value>application/json;charset=UTF-8</value>
41 </list>
42 </property>
43 </bean>
44 </mvc:message-converters>
45 </mvc:annotation-driven>
46
47 <!-- 多视图解析器 -->
48 <bean
49 class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
50 <property name="favorParameter" value="true"></property>
51 <property name="mediaTypes">
52 <map>
53 <entry key="json" value="application/json;charset=UTF-8"></entry>
54 <entry key="html" value="text/html;charset=UTF-8"></entry>
55 </map>
56 </property>
57 <property name="viewResolvers">
58 <list>
59 <bean
60 class="org.springframework.web.servlet.view.InternalResourceViewResolver">
61 <property name="prefix" value="/WEB-INF/jsp/"></property>
62 <property name="suffix" value=".jsp"></property>
63 </bean>
64 </list>
65 </property>
66 </bean>
67
68 <!-- 静态资源加载 -->
69 <mvc:resources location="/statics/" mapping="/statics/**" />
70
71 <!-- 全局异常处理 -->
72 <bean
73 class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
74 <property name="exceptionMappings">
75 <props>
76 <prop key="java.lang.RuntimeException">error</prop>
77 </props>
78 </property>
79 </bean>
80
81 <!-- 文件上传 -->
82 <bean name="multipartResolver"
83 class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
84 <property name="maxUploadSize" value="5024000"></property>
85 <property name="defaultEncoding" value="UTF-8"></property>
86 </bean>
87
88 <!-- 拦截器 -->
89 <mvc:interceptors>
90 <!-- 判断用户是否登录 -->
91 <mvc:interceptor>
92 <mvc:mapping path="/user/**"/>
93 <bean class="cn.bdqn.interceptor.SystemInterceptor"/>
94 </mvc:interceptor>
95 </mvc:interceptors>
96 </beans>
(3)mybatis_config.xml
<?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE configuration
3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
5 <configuration>
6 <!-- 设置全局性懒加载——即所有相关联的实体都被初始化加载 -->
7 <settings>
8 <setting name="lazyLoadingEnabled" value="false" />
9 </settings>
10
11 <!-- 为pojo类取别名 -->
12 <typeAliases>
13 <package name="cn.xxxx.pojo"/>
14 </typeAliases>
15 </configuration>
2
5
6
7
8
9
10
11
12
13
14
15