Spring MVC 01
Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分,可以从Spring的整体结构中看出来
Springmvc处理流程
jar包
commons-logging-1.1.1.jar jstl-1.2.jar spring-aop-4.1.3.RELEASE.jar spring-aspects-4.1.3.RELEASE.jar spring-beans-4.1.3.RELEASE.jar spring-context-4.1.3.RELEASE.jar spring-context-support-4.1.3.RELEASE.jar spring-core-4.1.3.RELEASE.jar spring-expression-4.1.3.RELEASE.jar spring-jdbc-4.1.3.RELEASE.jar spring-jms-4.1.3.RELEASE.jar spring-messaging-4.1.3.RELEASE.jar spring-tx-4.1.3.RELEASE.jar spring-web-4.1.3.RELEASE.jar spring-webmvc-4.1.3.RELEASE.jar
结构
struts2----action
springmvc----controller(也叫Handler层)
搭建
web.xml配置前端控制器
可以看出它是基于Servlet的
<!-- 前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 默认找 /WEB-INF/[servlet的名称]-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 1. /* 拦截所有 jsp js png .css 真的全拦截 建议不使用 2. *.action *.do 拦截以do action 结尾的请求 肯定能使用 ERP 各种管理系统 3. / 拦截所有 (不包括jsp) (包含.js .png.css) 强烈建议使用 前台 面向消费者 www.jd.com/search /对静态资源放行 --> <url-pattern>*.action</url-pattern> </servlet-mapping>
ItemController.java
import java.util.ArrayList; import java.util.Date; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.itheima.springmvc.pojo.Items; /** * 商品管理 */ @Controller public class ItemController { //入门程序 第一 包类 + 类包 + 方法名 @RequestMapping(value = "/item/itemlist.action") public ModelAndView itemList(){ // 创建页面需要显示的商品数据 List<Items> list = new ArrayList<Items>(); list.add(new Items(1, "1华为 荣耀8", 2399f, new Date(), "质量好!1")); list.add(new Items(2, "2华为 荣耀8", 2399f, new Date(), "质量好!2")); list.add(new Items(3, "3华为 荣耀8", 2399f, new Date(), "质量好!3")); list.add(new Items(4, "4华为 荣耀8", 2399f, new Date(), "质量好!4")); list.add(new Items(5, "5华为 荣耀8", 2399f, new Date(), "质量好!5")); list.add(new Items(6, "6华为 荣耀8", 2399f, new Date(), "质量好!6")); ModelAndView mav = new ModelAndView(); //数据 跳转视图 mav.addObject("itemList", list); mav.setViewName("itemList"); return mav; } }
springmvc.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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 扫描@Controler @Service --> <context:component-scan base-package="com.itheima"/> <!-- 处理器映射器 --> <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> --> <!-- 处理器适配器 --> <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> --> <!-- 注解驱动 有了这个,上面两个都不用配了--> <mvc:annotation-driven/> <!-- 视图解释器 省得写一长串--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
结构
流程
- 用户发送请求至前端控制器DispatcherServlet
- DispatcherServlet收到请求调用HandlerMapping处理器映射器。
- 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
- DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
- 执行处理器(Controller,也叫后端控制器)。
- Controller执行完成返回ModelAndView
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器
- ViewReslover解析后返回具体View
- DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet响应用户
处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。
handler和view是由程序员开发的组件
整合mabatis(等于是整合ssm)
配置文件
- applicationContext.xml
- db.properties
- log4j.properties
- springmvc.xml
- sqlMapConfig.xml
这些里边关联的模块(数据库连接,日志,spring核心),通过web.xml的配置加载到容器中
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- Spring监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
需要对applicationContext.xml中的配置项进行强化一下,因为每一个配置项都是ssm的重要资源
并且每一个资源,都配置了一个<bean id="" class="某个jar包中的类">
这些资源,可能还需要向spring索要一些条件,通常放在<property name="" value="" ref=""中,其中ref是其它bean的id,value是路径
参数绑定
xxController是单例的,多线程调用其方法副本
前台参数绑在什么东西上,传递给后台,后台如何取值,处理,返回
默认参数绑定:request,response,session,model
@RequestMapping(value = "/itemEdit.action") // public ModelAndView toEdit(@RequestParam(value = "id",required = false,defaultValue = "1") Integer idaaq, public ModelAndView toEdit(Integer id, HttpServletRequest request,HttpServletResponse response ,HttpSession session,Model model){ //Servlet时代开发 // String id = request.getParameter("id"); //查询一个商品 // Items items = itemService.selectItemsById(Integer.parseInt(id)); Items items = itemService.selectItemsById(id); ModelAndView mav = new ModelAndView(); //数据 mav.addObject("item", items); mav.setViewName("editItem"); return mav; }
实体类型的参数绑定
//提交修改页面 入参 为 Items对象 @RequestMapping(value = "/updateitem.action") // public ModelAndView updateitem(Items items){ public ModelAndView updateitem(QueryVo vo){ //修改 itemService.updateItemsById(vo.getItems()); ModelAndView mav = new ModelAndView(); mav.setViewName("success"); return mav; }
和形参名items没什么关系,只要前台传来的属性名可以和Items接收对象的属性名对应上即可取到
filter过滤器处理POST乱码问题(解决GET请求乱码问题可以通过修改tomcat8080URIEncoding配置实现)
<!-- 处理POST提交乱码问题 --> <filter> <filter-name>encoding</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>encoding</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping>
绑定包装的pojo(实体中还有实体作为属性)
<form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" method="post"> <input type="hidden" name="items.id" value="${item.id }" /> 修改商品信息: <table width="100%" border=1> <tr> <td>商品名称</td> <td><input type="text" name="items.name" value="${item.name }" /></td> </tr> <tr> <td>商品价格</td> <td><input type="text" name="items.price" value="${item.price }" /></td> </tr>
前台提交的参数多加一层就完事了
自定义参数绑定
<!-- 处理器映射器 --> <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> --> <!-- 处理器适配器 --> <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> --> <!-- 注解驱动 --> <mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/> <!-- 配置Conveter转换器 转换工厂 (日期、去掉前后空格)。。 --> <bean id="conversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <!-- 配置 多个转换器--> <property name="converters"> <list> <bean class="com.itheima.springmvc.conversion.DateConveter"/> </list> </property> </bean>
这个事情由处理器适配器来做,适配器来配置哪个类来进行转换,将前台参数进行转换
import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.core.convert.converter.Converter; /** * 转换日期类型的数据 * S : 页面传递过来的类型 * T : 转换后的类型*/ public class DateConveter implements Converter<String, Date>{ public Date convert(String source) { // TODO Auto-generated method stub try { if(null != source){//2016:11-05 11_43-50 DateFormat df = new SimpleDateFormat("yyyy:MM-dd HH_mm-ss"); return df.parse(source); } } catch (Exception e) { // TODO: handle exception } return null; } }
效果就是:参数传递到了后台,按照名称进行参数绑定
private Integer id; private String name; private Float price; private String pic; private Date createtime; private String detail;
当出现需要由String转为Date时,因为Converter<String, Date>
就会进入到上面的convert方法
插一句:
浏览器地址栏请求服务器上的项目,有两个东西可以请求:
一个是静态资源文件,另一个是controller中配置的@RequestMapping
而WEB-INF目录下的资源是受保护的,不能直接访问
springmvc与struts2不同
struts2绑定参数是绑定在成员变量上,而springmvc是绑定在形参上
springmvc是单例的,struts2是多例的
springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例)
struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
springmvc存数据是放到request域中,无值栈概念(Struts采用值栈存储请求和响应的数据,通过OGNL存取数据)
springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过滤器。
springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面。Jsp视图解析器默认使用jstl