MVC的架构
Spring对MVC架构的实现,它主要工作在web层.
特点:他可以使用一个注解将一个简单的javaBean变成控制器
1.SpringMVC工作流程
个人通俗理解:
首先浏览器发出请求,要一个视图页面,视图页面到达前端控制器以后,控制器不会真正的干活,他会把这个东西转交给处理器映射器,
处理器映射器拿到逻辑的相当于url寻找真正处理它的方法,找到的其实是类名方法名,然后把这个东西返回回来,前端控制器会
再次调用处理器适配器,告诉他,你去调用这个方法,调完后会返回两个东西,要么是一个视图,要么是视图加数据,拿过来以后适
配器把这个数据返回给前端控制器,前端控制器拿到的是返回来的数据和逻辑视图,会调用视图解析器把逻辑视图转为真正的物
理视图,物理视图返回给前端控制器,返回来以后,前端控制器有数据了也有真正的jsp文件了,做一个填充,整个响应视图返回去.
2.SpringMVC环境搭建
空工程-->web工程-->导入坐标-->加入springmvc配置文件-->加入web.xml(配置前端控制器)-->编写请求页面-->编写处理器(controller)-->编写响应页面-->部署项目测试
3.自定义类型转换器
自定义一个转换器类实现Converter接口,并实现自定义转换方法
//自定义类型转换器,实现Converter<元数据类型,目标数据类型> public class DateConverter implements Converter<String, Date> { @Override public Date convert(String s) { //字符串转时间 try { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(s); } catch (ParseException e) { System.out.println("数据转换异常"); throw new RuntimeException(e); } } }
在配置文件中声明转化器服务
<!--声明转换器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.jia.converter.DateConverter"></bean> </set> </property> </bean>
将服务注册到注解驱动
<mvc:annotation-driven conversion-service="conversionService"/>
4.Servlet匹配规则
精确匹配 /abc/index.jsp /a/b.jpg /abc/a
路径匹配 /abc/* /*
后缀匹配 *.jsp *.html *.do *.guo
默认匹配 /
几个servlet的作用
5.静态资源释放
方式一(推荐)
<!--释放静态资源-->
<!--当我的项目中的默认Servlet处理不了的请求时,我会把这个请求转交给外部的默认servlet-->
<mvc:default-servlet-handler/>
方式二
<!--释放静态资源-->
<!--当访问的路径是mappring指定的路径时,DispatcherSerlet不在寻找对应的Controller,
而是直接定位静态资源()按照location指定的位置-->
<!-- <mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>-->
6.使用restful风格发送和接收请求
URL当以操作的资源为中心,不希望URL中出现动词. 规定使用请求方式代表增删改查 GET(查询) POST(创建) PUT(修改) DELETE(删除) 原来 Restful风格 保存 /save POST /user 修改 /update?id=1 PUT /user/1 删除 /delete?id=1 DELETE /user/1 查询所有 /findAll GET /user 查询一个 /findById?id=1 GET /user/1
Restful风格
URL当以操作的资源为中心,不希望URL中出现动词.
规定使用请求方式代表增删改查
GET(查询) POST(创建) PUT(修改) DELETE(删除)
7.SpringMVC运行原理
1. 浏览器发出请求
2. Tomcat接收请求,经过请求解析封装出Request和Response对象,然后转交给我们的应用程序
3. 因为我们配置的DispatcherServlet会拦截到请求的路径
4. DispatcherServlet经过一番分析处理,会将请求转发到我们定义的Controller上(@RequestMapping)
5. Controller经过处理,给出了一个返回路径
6. DispatcherServlet拿到这个路径会找到对应的JSP进行视图渲染
8.三大组件的分工
HandlerMapping (处理器映射器) 负责根据请求找到相对应的处理器(我们自己写的Controller)
HandlerAdapter(处理器适配器) 统一适配器接口,对处理器进行了一个封装,可以统一调用
ViewReslover(视图解析器) 根据逻辑视图匹配到真正的视图
9.MVC的职责
发送请求 httpservletrequest model modelandview
返回视图 ${}
返回数据 response.getWriter.write("字符串") 返回一个字符串 加注解@responseBody
10.全局处理异常
我们的思路的是这样的,在我们的程序中不处理异常,就是一层一层的往上抛,最后抛给框架,然后由框架指定一个统一异常处理器进行处理.
1.定义一个处理器类
//自定义异常处理器:实现一个HandlerExceptionResolver,然后实现resolveException方法 @Component public class CommonExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error"); return modelAndView; } }
2.添加一个包扫描
<context:component-scan base-package="com.jia.exception"/>
3.定义一个异常页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
系统升级中,请稍后重试~~~
</body>
</html>
11.拦截器
拦截器是Spring提出的一个概念,它的作用和前面学过的过滤器非常相似,主要是在请求到达控制器之前离开控制器之后和视图渲染之后这三个位置进行拦截,然后加入相应的功能.
明确拦截器的位置
拦截器和过滤器区别
拦截器是SpringMVC提供的,过滤器是servlet规范提供
拦截器一般只会拦截发往控制器的请求,而过滤器一般会拦截所有请求
自定义一个拦截器
自定义一个拦截器类实现HandlerInterceptor接口,并重写其中的方法
public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //成功放行,到时候自己获取Session判断 if(request.getSession().getAttribute("currentUser")!=null){ return true; } //不成功跳转到登录 response.sendRedirect(request.getContextPath()+"/login.jsp"); return false; } }
在配置文件中配置拦截器
<!--配置登录拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截所有-->
<mvc:mapping path="/**"/>
<!--对登录放行,不放行登录永远不可能登录成功-->
<mvc:exclude-mapping path="/user/login"/>
<bean class="com.jia.interceptors.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
12.整合ssm
Spring整合Mybatis的核心思路就是将Mybatis的配置文件和SqlSessionFactory工厂交给Spring管理,让SPring给我们生产dao的对象,并将对象放入容器中.
导入spring和MyBatis整合包
将Mybatis配置文件转移到spring中
<?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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--配置包扫描--> <context:component-scan base-package="com.jia"> <!--按照注解排除,排除掉Controller注解标注的bean--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!--数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///spring93"/> <property name="username" value="root"/> <property name="password" value="adminadmin"/> </bean> <!--事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--数据源--> <property name="dataSource" ref="dataSource"/> <!--别名--> <property name="typeAliasesPackage" value="com.jia.domain"/> <!--如果还需要其他配置,可以直接引入mybatis的配置文件--> <!--<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>--> </bean> <!--mapper映射--> <bean id="configurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.jia.dao"/> </bean> <!--事务注解驱动--> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
在service中注入Dao
测试service
整合Spring和SpringMVC
Spring和SpringMVC本身就是一家,是不需要做整合的.
但是现在的Spring容器自己无法启动,需要借助WEB容器
也就是说,当web容器启动的时候,应该自动加载Spring的配置文件,启动Spring容器
Web容器销毁的时候,应该顺便销毁Spring的容器
那么这个工作是在spring-web包中的一个监听器来做的,它会监听WEB容器的启动和停止,然后就可以控制Spring容器的启动和停止了.
这个包不用单独导入,他已经在spring-webmvc包中了
13.中文乱码
请求
发生位置 发送POST请求时
解决方案 中文乱码过滤器
web.xml <!--配置中文过滤器--> <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>
响应
发生位置 当使用控制器直接返回一个字符串的时候
解决方案
14.事务
1.声明式事务
在配置文件中添加事务注解驱动
<!--事务注解驱动--> <tx:annotation-driven transaction-manager="transactionManager"/>
在service类上添加事务注解
@Transactional
2.编程式事务
15.常见的状态码
200 成功
301 302 页面重定向
400 错误请求
401 未授权
403 禁止访问
404 资源不存在
405 请求类型错误
500 服务器内部错误
503 服务不可用
504 网关超时