SpringMVC详解

  1. SpringMVC介绍
  2. 入门程序
  3. SpringMVC架构讲解
    1. 框架结构
    2. 组件说明
  4. SpringMVC整合MyBatis
  5. 参数绑定
    1. SpringMVC默认支持的类型
    2. 简单数据类型
    3. Pojo类型
    4. Pojo包装类型
    5. 自定义参数绑定
  6. SpringMVC和Struts2的区别
  7. 高级参数绑定
    1. 数组类型的参数绑定
    2. List类型的绑定
  8. @RequestMapping注解的使用
  9. Controller方法返回值
  10. SpringMVC中异常处理
  11. 图片上传处理
  12. Json数据交互
  13. SpringMVC实现RESTful

8、拦截器

Spring入门

Springmvc是什么

Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分,我们可以从Spring的整体结构中看得出来,如下图:

Springmvc处理流程

如下图所示:

入门程序

需求:使用浏览器显示商品列表

创建web工程

springMVC是表现层框架,需要搭建web工程开发。

如下图创建动态web工程:

输入工程名,选择配置Tomcat(如果已有,则直接使用),如下图:

配置Tomcat,如下图:

选择准备好的Tomcat,这里用的是Tomcat7,如下图:

选择成功,点击Finish,如下图:

选择刚刚设置成功的Tomcat,如下图:

如下图选择web的版本是2.5,可以自动生成web.xml配置文件,

创建效果如下图:

导入jar包

从课前资料中导入springMVC的jar包,位置如下图:

复制jar到lib目录,工程直接加载jar包,如下图:

加入配置文件

创建config资源文件夹,存放配置文件,如下图:

创建springmvc.xml

创建SpringMVC的核心配置文件

SpringMVC本身就是Spring的子项目,对Spring兼容性很好,不需要做很多配置。

这里只配置一个Controller扫描就可以了,让Spring对页面控制层Controller进行管理。

创建springmvc.xml

配置文件需要的约束文件,位置如下图:

创建包cn.itcast.springmvc.controller

效果如下图:

配置前端控制器

配置SpringMVC的前端控制器DispatcherServlet

在web.xml中

 

加入jsp页面

把参考资料中的itemList.jsp复制到工程的/WEB-INF/jsp目录下,如下图:

实现显示商品列表页

创建pojo

分析页面,查看页面需要的数据,如下图:

创建商品pojo

 

创建ItemController

 

启动项目测试

启动项目,浏览器访问地址

http://127.0.0.1:8080/springmvc-first/itemList.action

效果如下图:

为什么可以用呢?我们需要分析一下springMVC的架构图。

Springmvc架构

框架结构

框架结构如下图:

架构流程

  1. 用户发送请求至前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
  4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
  5. 执行处理器(Controller,也叫后端控制器)。
  6. Controller执行完成返回ModelAndView
  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
  11. DispatcherServlet响应用户

组件说明

以下组件通常使用框架提供实现:

  • DispatcherServlet:前端控制器

用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。

  • HandlerMapping:处理器映射器

HandlerMapping负责根据用户请求url找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

  • Handler:处理器

Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。

由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。

  • HandlAdapter:处理器适配器

通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

下图是许多不同的适配器,最终都可以使用usb接口连接

usb转网口 usb转串口 usb转ps2

  • ViewResolver:视图解析器

View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。

  • View:视图

springmvc框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。

一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。

说明:在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。

需要用户开发的组件有handler、view

默认加载的组件

我们没有做任何配置,就可以使用这些组件

因为框架已经默认加载这些组件了,配置文件位置如下图:

# Default implementation classes for DispatcherServlet’s strategy interfaces.

# Used as fallback when no matching beans are found in the DispatcherServlet context.

# Not meant to be customized by application developers.

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\

org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\

org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\

org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\

org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\

org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

组件扫描器

使用组件扫描器省去在spring容器配置每个Controller类的繁琐。

使用<context:component-scan>自动扫描标记@Controller的控制器类,

在springmvc.xml配置文件中配置如下:

<!– 配置controller扫描包,多个包之间用,分隔 –>

<context:component-scan base-package=”cn.itcast.springmvc.controller” />

注解映射器和适配器

配置处理器映射器

注解式处理器映射器,对类中标记了@ResquestMapping的方法进行映射。根据@ResquestMapping定义的url匹配@ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器。

HandlerMethod对象中封装url对应的方法Method。

从spring3.1版本开始,废除了DefaultAnnotationHandlerMapping的使用,推荐使用RequestMappingHandlerMapping完成注解式处理器映射。

在springmvc.xml配置文件中配置如下:

<!– 配置处理器映射器 –>

<bean

class=”org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping” />

注解描述:

@RequestMapping:定义请求url到处理器功能方法的映射

配置处理器适配器

注解式处理器适配器,对标记@ResquestMapping的方法进行适配。

从spring3.1版本开始,废除了AnnotationMethodHandlerAdapter的使用,推荐使用RequestMappingHandlerAdapter完成注解式处理器适配。

在springmvc.xml配置文件中配置如下:

<!– 配置处理器适配器 –>

<bean

class=”org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter” />

注解驱动

直接配置处理器映射器和处理器适配器比较麻烦,可以使用注解驱动来加载。

SpringMVC使用<mvc:annotation-driven>自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter

可以在springmvc.xml配置文件中使用<mvc:annotation-driven>替代注解处理器和适配器的配置。

<!– 注解驱动 –>

<mvc:annotation-driven />

视图解析器

视图解析器使用SpringMVC框架默认的InternalResourceViewResolver,这个视图解析器支持JSP视图解析

在springmvc.xml配置文件中配置如下:

 

效果

效果和之前一样,如下图:

整合mybatis

为了更好的学习 springmvc和mybatis整合开发的方法,需要将springmvc和mybatis进行整合。

整合目标:控制层采用springmvc、持久层使用mybatis实现。

创建数据库表

sql脚本,位置如下图:

创建数据库表springmvc,导入到数据库中,如下图:

需要的jar包

  1. spring(包括springmvc)
  2. mybatis
  3. mybatis-spring整合包
  4. 数据库驱动
  5. 第三方连接池。

jar包位置如下图:

整合思路

Dao层:

  1. SqlMapConfig.xml,空文件即可,但是需要文件头。
  2. applicationContext-dao.xml
    1. 数据库连接池
    2. SqlSessionFactory对象,需要spring和mybatis整合包下的。
    3. 配置mapper文件扫描器。

Service层:

  1. applicationContext-service.xml包扫描器,扫描@service注解的类。
  2. applicationContext-trans.xml配置事务。

Controller层:

  1. Springmvc.xml
    1. 包扫描器,扫描@Controller注解的类。
    2. 配置注解驱动
    3. 配置视图解析器

Web.xml文件:

  1. 配置spring
  2. 配置前端控制器。

创建工程

创建动态web工程springmvc-web,如下图:

加入jar包

复制jar包到/WEB-INF/lib中

工程自动加载jar包

加入配置文件

创建资源文件夹config

在其下创建mybatis和spring文件夹,用来存放配置文件,如下图:

sqlMapConfig.xml

使用逆向工程来生成Mapper相关代码,不需要配置别名。

在config/mybatis下创建SqlMapConfig.xml

 

applicationContext-dao.xml

配置数据源、配置SqlSessionFactory、mapper扫描器。

 

db.properties

配置数据库相关信息

 

applicationContext-service.xml

 

applicationContext-trans.xml

 

springmvc.xml

 

web.xml

 

加入jsp页面

复制课前资料的itemList.jsp和itemEdit.jsp到工程中

效果

配置完效果如下图:

实现商品列表显示

需求

实现商品查询列表,从mysql数据库查询商品信息。

DAO开发

使用逆向工程,生成代码

注意修改逆向工程的配置文件,参考MyBatis第二天

逆向工程生成代码如下图:

ItemService接口

public interface ItemService {

/**

* 查询商品列表

*

* @return

*/

List<Item> queryItemList();

}

ItemServiceImpl实现类

 

测试

访问url:

http://127.0.0.1:8080/springmvc-web/itemList.action

效果如下图:

参数绑定

默认支持的参数类型

需求

打开商品编辑页面,展示商品信息。

需求分析

编辑商品信息,首先要显示商品详情

需要根据商品id查询商品信息,然后展示到页面。

请求的url:/itemEdit.action

参数:id(商品id)

响应结果:商品编辑页面,展示商品详细信息。

ItemService接口

编写ItemService接口如下图:

ItemServiceImpl实现类

 

ItemController

页面点击修改按钮,发起请求

http://127.0.0.1:8080/springmvc-web/itemEdit.action?id=1

需要从请求的参数中把请求的id取出来。

Id包含在Request对象中。可以从Request对象中取id。

想获得Request对象只需要在Controller方法的形参中添加一个参数即可。Springmvc框架会自动把Request对象传递给方法。

代码实现

 

默认支持的参数类型

处理器形参中添加如下类型的参数处理适配器会默认识别并进行赋值。

HttpServletRequest

通过request对象获取请求信息

HttpServletResponse

通过response处理响应信息

HttpSession

通过session对象得到session中存放的对象

Model/ModelMap

Model

除了ModelAndView以外,还可以使用Model来向页面传递数据,

Model是一个接口,在参数里直接声明model即可。

如果使用Model则可以不使用ModelAndView对象,Model对象可以向页面传递数据,View对象则可以使用String返回值替代。

不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据。

代码实现:

 

ModelMap

ModelMap是Model接口的实现类,也可以通过ModelMap向页面传递数据

使用Model和ModelMap的效果一样,如果直接使用Model,springmvc会实例化ModelMap。

代码实现:

 

绑定简单类型

当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。

这样,从Request取参数的方法就可以进一步简化。

 

支持的数据类型

参数类型推荐使用包装数据类型,因为基础数据类型不可以为null

整形:Integer、int

字符串:String

单精度:Float、float

双精度:Double、double

布尔型:Boolean、boolean

说明:对于布尔类型的参数,请求的参数值为true或false。或者1或0

请求url:

http://localhost:8080/xxx.action?id=2&status=false

处理器方法:

public String editItem(Model model,Integer id,Boolean status)

@RequestParam

使用@RequestParam常用于处理简单类型的绑定。

value:参数名字,即入参的请求参数名字,如value=“itemId”表示请求的参数 区中的名字为itemId的参数的值将传入

required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错

TTP Status 400 – Required Integer parameter ‘XXXX’ is not present

defaultValue:默认值,表示如果请求中没有同名参数时的默认值

定义如下:

@RequestMapping(“/itemEdit”)

public String queryItemById(@RequestParam(value = “itemId”, required = true, defaultValue = “1”) Integer id,

ModelMap modelMap) {

// 根据id查询商品数据

Item item = this.itemService.queryItemById(id);

// 把商品数据放在模型中

modelMap.addAttribute(“item”, item);

return “itemEdit”;

}

绑定pojo类型

需求

将页面修改后的商品信息保存到数据库中。

需求分析

请求的url:/updateItem.action

参数:表单中的数据。

响应内容:更新成功页面

使用pojo接收表单数据

如果提交的参数很多,或者提交的表单中的内容很多的时候,可以使用简单类型接受数据,也可以使用pojo接收数据。

要求:pojo对象中的属性名和表单中input的name属性一致。

页面定义如下图:

Pojo(逆向工程生成)如下图:

请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性。

ItemService接口

 

ItemServiceImpl实现类

 

ItemController

 

注意:

提交的表单中不要有日期类型的数据,否则会报400错误。如果想提交日期类型的数据需要用到后面的自定义参数绑定的内容。

编写success页面

如下图创建success.jsp页面

页面代码:

 

解决post乱码问题

提交发现,保存成功,但是保存的是乱码

在web.xml中加入:

 

以上可以解决post请求乱码问题。

对于get请求中文参数出现乱码解决方法有两个:

修改tomcat配置文件添加编码与工程编码一致,如下:

<Connector URIEncoding=”utf-8″ connectionTimeout=”20000″ port=”8080″ protocol=”HTTP/1.1″ redirectPort=”8443″/>

另外一种方法对参数进行重新编码:

 

绑定包装pojo

需求

使用包装的pojo接收商品信息的查询条件。

需求分析

包装对象定义如下:

public class QueryVo {

private Item item;

set/get。。。

}

页面定义如下图:

接收查询条件

 

自定义参数绑定

需求

在商品修改页面可以修改商品的生产日期,并且根据业务需求自定义日期格式。

需求分析

由于日期数据有很多种格式,springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。

前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,并对方法中的形参进行参数绑定。可以在springmvc处理器适配器上自定义转换器Converter进行参数绑定。

一般使用<mvc:annotation-driven/>注解驱动加载处理器适配器,可以在此标签上进行配置。

修改jsp页面

如下图修改itemEdit.jsp页面,显示时间

自定义Converter

 

配置Converter

我们同时可以配置多个的转换器。

类似下图的usb设备,可以接入多个usb设备

IMG_256

 

配置方式2(了解)

 

springmvc与struts2不同

  1. springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过滤器。
  2. springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
  3. Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面。Jsp视图解析器默认使用jstl。