SpringMVC
Spring web MVC是web层的框架,是Spring框架的一部分
springmvc组件介绍
DispatcherServlet:前端控制器
HandlerMapping:处理器映射器
Handler:处理器
HandlAdapter:处理器适配器
ViewResolver:视图解析器
view:视图
说明:
在springmvc的各个组件中,处理器映射器,处理器适配器,视图解析器称为springmvc的三大组件.可以认为
是一个中心三个基本点,需要用户开发的组件有handler.view
springmvc组件配置
处理器映射器/处理器适配器
通过观察发现默认的处理器适配器和处理器映射器,在3.2后使用新的配置,所以我们要重去配置新的处理器映射
器和处理器适配器.
在springmvc的配置文件中需要将新的处理器映射器和处理器适配器配置进容器中
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
这样配置有点麻烦,可以使用注解驱动来加载.
SpringMVC使用
<mvc:annotation-driven/>
用来自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter
视图解析器
通过配置视图解析器的前缀和后缀在前端控制器将modelAndView交给视图解析器的时候,自动会视图的路径添
加前缀和后缀
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF"></property>
<property name="suffix" value=".jsp"></property>
</bean>
Springmvc处理流程
前段控制器(DiapatchServlet)是springmvc的心脏,用来拦截用户的请求,其本质是一个servlet,其受到请求后将数据
交给处理器(handler)去执行相关处理
1.用户向服务器发送请求,请求被Spring前端控制Servlet DispatcherServlet捕获;
2.DispatcherServlet对请求URL进行解析,得到请求资源标识符(URL).然后根据该URL,调用HandlerMapping获
得该Handler配置的所有相关的对象(包括handle对象以及Handler对象对应的拦截器),最后以
HandleExecutionChain对象的形式返回;
3.DispatcherServlet根据获得的Handler,选择一个合适的HandlerAdapter
4.提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller).在填充Handler的入参过程中,根
据你的配置,Spring将帮你做一些额外的工作
4.1HttpMessageConveter:将请求消息(如Json,xml等数据)转换成一个对象,将对象转化为指定的响
应信息.
4.2数据转换:对请求消息进行数据转换.如String装换成Integer,Double
4.3数据格式化:对请求消息进行数据格式化.如将字符串转换成格式化或格式化日期等
4.4数据验证:验证数据的有效性(长度,格式等),验证结果储存到BindingResult或Error中
5.Handler执行完成后,向DispatcherServlet返回一个ModerAndView对象.
6.根据返回的ModeAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)
进行视图的解析
7.ViewReslover解析后返回具体View
8.DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中).
9.DispatcherServlet响应用户
Hello World
导包 4+2+aop+web+webmvc+jstl(1.2版本只需一个文 件即可)
设置springmvc的约束文件
新建config的source folder
创建配置文件springmvc.xml,配置扫描controller包
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/200 1/XMLSchema-instance"
xmlns="http://www.springframework.or g/schema/beans"
xmlns:aop="http://www.springframewor k.org/schema/aop"
xmlns:context="http://www.springframe work.org/schema/context"
xmlns:tx="http://www.springframewor k.org/schema/tx"
xmlns:p="http://www.springframework.o rg/schema/p"
xmlns:mvc="http://www.springframewor k.org/schema/mvc"
xsi:schemaLocation="http://www.spring framework.org/schema/mvc http://www.sprin gframework.org/schema/mvc/spring-mvc- 4.2.xsd
http://www.springframework.org/sc hema/beans
http://www.springframework.or g/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/sc hema/context
http://www.springframework.o rg/schema/context/spring-context-4.2.xsd
http://www.springframework.org/sc hema/aop
http://www.springframework.org/s chema/aop/spring-aop-4.2.xsd
http://www.springframework.org/sc hema/tx
http://www.springframework.org/sc hema/tx/spring-tx-4.2.xsd">
<context:component-scan base-package="co m.zhiyou100.springmvc.controller"/>
</beans>
配置 xml文件,配置前端控制器和servlet的初始化参数为springmvc配置文件的路径,和Spring相同param-name为
contextConfigLocation,只不过这个初始化参数指的是servlet的初始化参数(如果不配置路径,springmvc回去
找/WEB-INF/servlet名字-servlet.xml此文件,如果没有此文件就会报异常)
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>ContextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
创建一个包叫做controller这个就是web层
在其中创建类,用来处理请求
@Controller
public class RoleController {
@RequestMapping("/role/roleList.action")
public ModelAndView roleList() {
ModelAndView mv = new ModelAndView();
List<Role> list = new ArrayList<>();
list.add(new Role(1,"老师1","剑客1",new Timestamp(System.currentTimeMillis())));
list.add(new Role(2,"老师2","剑客2",new Timestamp(System.currentTimeMillis())));
list.add(new Role(3,"老师3","剑客3",new Timestamp(System.currentTimeMillis())));
list.add(new Role(4,"老师4","剑客4",new Timestamp(System.currentTimeMillis())));
list.add(new Role(5,"老师5","剑客5",new Timestamp(System.currentTimeMillis())));
mv.addObject("list",list);
mv.setViewName("/WEB-INF/view/role/roleList.jsp");
return mv;
}
}
静态资源放行
前端控制器的本质是一个servlet,所以url-pattern符合servlet的规则,但是springmvc是需
要拦截请求才能使用框架进行处理的,所以关于路径匹配一般不会使用完全路径匹配和目录
匹配,一般设置为后缀名匹配(推荐使用这种方式),也可以使用/和/*,但是/*是会对jsp进行拦
截的,所以一般一般不使用/*.但是使用/也会对静态资源进行拦截,这就需要我们在
controller进行静态资源的操作,显然这种方式不可取,所以如果配置了/,就需要设置静态资
源放行
注意:如果前端控制器配置为扩展名匹配的话,是不需 要设置静态资源放行的,并且建议使用
扩展名匹配
方式一
tomcat内部有一个叫做默认servlet的url-pattern为/器可以处理静态资源,我们可以在配
置文件中配置一个默认的servlet为这个进行处理,必须要注解驱动才能正常使用
<mvc:default-servlet-handler/>
方式二
手动建立映射关系,/**表示可以有下一级文件夹,这种映射路径的方法,内部是由处理器映射
器去执行具体的映射过程,所以必须配置注解驱动. 此方法的好处是路径可以直接在配置文
件中进行指定
参数绑定
如果我们定义了请求.响应,session,springmvc就会将
HttpServletReqest,HttpServletResponse,HttpSession三个对象作为参数传递过来.我们
在定义参数的时候还可以写Model/ModelMap
Model/ModelMap是用来向页面进行传值使用的,这两个哪一个都可以
简单类型参数
参数类型推荐使用包装数据类型,因为基础数据类型不可以为null
整形:Intger,int
字符串:String
单精度:Float,float
双精度:Double, double
布尔型:Boolean,boolean
@RequestParam
如果表单中的name属性和参数名称不一致的时候可以使用@RequestParam建立映射关
系,一但使用了这个注解,传递的参数就必须含有该名称,如果没有名称,就会报错
@RequestMapping("role/updateRole.action")
public ModelAndView test02(@RequestParam(value="id")Integer theid) {
System.out.println(theid);
return null;
}
参数绑定model类
需保证表单的name属性和model中的属性--对应
解决乱码
在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>*.action</url-pattern>
</filter-mapping>
数组参数绑定
在表单如果有checkbox这种多选框,提交到controller,可以通过数组的形式进行获取,那么
需要将checkbox的name属性设置为方法的参数的名称,也可以在包装类中定义成员变量的
名字为表单的name数属性
集合类型参数绑定
在表单中如果牵扯到表格中的数据批量修改,并且没一行有多个数据都要更改,我们把每一行
当做一个对象,把多行数据放入对象集合中进行提交,
不过这种方法仅仅适合于包装类,不能直接把值传入向应的参数.
<c:forEach var="role" items="${ list }" varStatus="status">
<tr>
<td>${ status.count }</td>
<td>
<input type="text" name="list[${status.index}].rName" value="${role.rName }">
</td>
<td>
<input type="text" name="list[${status.index}].rDesc" value="${role.rDesc }">
<input type="hidden" name="list[${status.index}].rId" value="${role.rId}">
</td>
<td>
<fmt:formatDate value="${role.rUpdatetime}" type="both"
pattern="MM-dd HH:mm"/>
</td>
<td>
<a class="fa fa-pencil" title="编辑"
href="<c:url value="/role/updateRole.action?id=${role.rId}" />"></a>
<a class="fa fa-remove" title="删除" href="<c:url
value="/deleteRole?id=${role.rId}" />"></a>
</td>
</tr>
</c:forEach>
public class Role {
private Integer rId;
private String rName;
private String rDesc;
private Date rUpdatetime;
private String[] hobby;
@RequestMapping("/role/updateList.action")
public ModelAndView updateRoleList(RoleOV ro,Role role) {
ModelAndView mv = new ModelAndView();
System.out.println(ro);
rs.updateList(ro);
return null;
}