一起进阶学习JAVA:Spring MVC 应用
什么是MVC
MVC是一种用于设计创建Web应用程序的表现层的模式,全名是Model(模型) View(视图) Controller(控制器)。
- Model(模型):模型包含业务模型和数据模型,其中业务模型主要使用于业务处理,数据模型主要用于包装数据;
- View(视图):通常作用指展示数据的(jsp,html等前端显示页面),视图一般都是依据数据模型来创建的;
- Controller(控制器):主要是处理用户交互请求
什么是Spring MVC
- Spring MVC全称Spring Web MVC,是一套基于java实现MVC设计模型的轻量级Web框架。
- 相对于servlet和struts来说Spring MVC不需要和前者一样去实现接口,只需要通过注解就可以使java类称为一个请求处理的控制器。
- Spring MVC还支持RESTful编程风格的请求。
- Spring MVC本质上还是对Servlet的一种封装,其主要作用是:1.接受请求;2.返回响应,跳转页面。
Spring MVC的请求处理流程
步骤说明
- 用户通过页面或其他方式发送请求至前端控制器DispatcherServlet
- 前端控制器DispatcherServlet收到用户请求转而调用处理映射器HandlerMapping
- 处理映射器HandlerMapping根据请求的url找到具体的后端控制器Handler生成处理器对象以及拦截器等一并返回给前端控制器DispatcherServlet
- 前端控制器DispatcherServlet调用处理器适配器HandlerAdapter去找到合适的Handler
- 处理器适配器HandlerAdapter执行Handler
- Handler执行完毕后将返回给处理器适配器HandlerAdapter一个ModelAndView对象
- 处理器适配器HandlerAdapter向前端控制器DispatcherServlet返回ModelAndView对象
- 前端控制器DispatcherServlet根据拿到的ModelAndView对象去请求视图解析器ViewResolver解析视图
- 视图解析器ViewResolver解析视图完成后向前端控制器DispatcherServlet返回View对象
- 前端控制器DispatcherServlet根据拿到的View对象以及将ModelAndView对象中的模型数据填充至Request域中
- 前端控制器DispatcherServlet向用户响应结果
Spring MVC核心组件
-
DispatcherServlet(前端控制器)
主要作用是处理用户请求接收以及响应结果;
DispatcherServlet接收用户发送的请求,并且将请求分发到各个Handler并从中获取Handler的处理结果进行包装解析返回给用户 -
HandlerMapping(处理器映射器)
HandlerMapping主要通过用户请求来查找对应的Handler处理器,这个Handler处理器可以是标注了@RequestMapping的类以及方法。Handler处理器主要负责具体的请求处理 -
HandlerAdapter(处理器适配器)
HandlerAdapter是一个适配器。servlet的方法结构都是doService(HttpServletRequest req,HttpServletResponse resp)形式的,HandlerAdapter适配器就是按照一定的规则对各个Handler进行适配,让固定的Servlet处理方法来调用Handler -
HandlerExceptionResolver(异常解析器)
主要处理Handler中产生的异常,并且根据异常设置ModelAndView,然后交给渲染方法进行渲染 -
ViewResolver(视图解析器)
主要用于将String类型的视图名和Locale解析为Viwe类型的视图。Controller层返回的String类型的视图名最终会在这里解析成View视图。ViewResolver视图解析器主要完成找到渲染所用的模板以及找到视图的类型(如JSP,HTML等)并填入参数。其中InternalResourceViewResolver是针对Jsp类型的视图的 -
RequestToViewNameTranslator
RequestToViewNameTranslator主要是从请求中获取ViewName。在ViewResolver视图解析器中,ViewResolver会从Controller层返回的String类型的视图名中解析ViewName,但是始终会有在Controller层不设置ViewName的情况发生,RequestToViewNameTranslator主要就是针对这种情况去获取ViewName -
LocaleResolver(国际化解析器)
-LocaleResolver主要是从请求中解析Locale,通过Locale解析结果来确定当前的区域来执行国际化操作 -
ThemeResolver(主题解析器)
在Spring MVC中一个主题对应一个properties文件,在properties文件中会存放当前主题相关的样式文件,图片等资源。ThemeResolver主题解析器根据所指定的主题名来解析应用相关的主题。但是往往不同主题的操作是使用在前端页面中编写不同主题的样式等资源文件并且多编写几套页面的方式来完成的 -
MultipartResolver(多媒体解析器)
MultipartResolver多媒体解析器在大部分时候是用于文件上传的解析处理的,MultipartResolver 的主要作用就是将普通请求封装成一个MultipartHttpServletRequest请求。 -
FlashMapManager(重定向处理器)
FlashMapManager主要用于后端业务的重定向操作中的参数传递,其参数传递主要通过FlashMap来操作传递。在重定向之前将要传递的参数数据封装到请求中的OUTPUT_FLASH_MAP_ATTRIBUTE 属性中,然后在重定向后的Handler中,Spring会自动将数据注入到Model中。FlashMapManager就是用来管理FlashMap的。
Spring MVC中的参数绑定
参数绑定就是Spring MVC如何接收请求参数
与原生Servlet的不同
- 原生Servlet:
String ageStr = request.getParameter("age");
Integer age = Integer.parseInt(ageStr);
- Spring MVC:
@RequestMapping("xxx")
public String handle(Integer age) {
System.out.println(age);
}
- Spring MVC支持使用 Servlet API 作为方法参数
当我们的接口方法中需要使用HttpServletRequest、HttpServletResponse、HttpSession等Servlet API的时候可以直接在方法的形参中声明
/**
* url:/xxx/method?param1=1
*/
@RequestMapping("/method")
public ModelAndView method(HttpServletRequest request, HttpServletResponse response,HttpSession session) {
}
- 绑定简单的参数类型
Integer、int:整数型;
String:字符串;
Float、float:单精度型;
Double、double:双精度型;
Boolean、boolean:布尔型(布尔型只能接受true、false、1、0四种内容)
当参数名称与url当中不同时用@RequestParam注解进行手动映射
/**
* url:/xxx/method?ids=1&flag=1&str=qaq&price=10.01&f=0.1
*/
@RequestMapping("/method")
public ModelAndView method(@RequestParam("ids") Integer id,Boolean flag, String str, double price, float f) {
}
- 绑定VO对象/VO包装对象类型参数
public class RequestVO {
private String param1;
private String param2;
private User user;
public String getParam1() {
return param1;
}
public void setParam1(String param1) {
this.param1 = param1;
}
public String getParam2() {
return param2;
}
public void setParam2(String param2) {
this.param2 = param2;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
/**
* url:/xxx/method?param1=a1¶m2=a2&user.name=aaa&user.password=123456
*/
@RequestMapping("/method")
public ModelAndView method(RequestVO requestVO) {
}
- 绑定日期类型参数
绑定日期类型参数需要单独配置参数类型转换器
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date parse = simpleDateFormat.parse(source);
return parse;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
并且将自定义参数类型转换器配置注册至Spring mvc中
<mvc:annotation-driven conversionservice="conversionServiceBean"/>
<bean id="conversionServiceBean" class="org.springframework.format.support.FormattingConversionServiceF actoryBean">
<property name="converters">
<set>
<bean class="com.xxx.xxx.xxx.DateConverter"> </bean>
</set>
</property>
</bean>
Handler中的方法
@RequestMapping("/method")
public ModelAndView method(Date date) {
}
Spring MVC对RESTful风格的支持
RESTful只是一种请求风格,并不是标准协议
Restful认为网络上任何一个文本、图片、服务等具体存在的就是一个资源,只要是资源就可以用一个url进行指向,也就是每种资源都有对应的一个URL,即每个URL是每个资源的独一无二的标识符。
Restful的优点
- 结构清晰
- 符合标准
- 易于理解
- 方便扩展
Restful请求
- 没有使用Restful风格请求时,url中定义了具体的动作以及参数锁定到具体的操作上
/demo/method.action?id=3
- 使用Restful风格的请求时,资源就会有一个具体的uri进行标识
/demo/3 HTTP GET :对id为3的数据进行查询操作
/demo/3 HTTP POST :对id为3的数据进行新增操作
/demo/3 HTTP PUT :对id为3的数据进行修改操作
/demo/3 HTTP DELETE :对id为3的数据进行删除操作
在Restful中get请求代表查询,post请求代表新增,put请求代表修改,delete请求代表删除。
但是在我们常规的HTTP请求中只有post和get请求,put和delete请求几乎不适用,那么如果要让Spring MVC去识别这两种请求,我们需要在web.xml中单独配置请求方式过滤器
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filterclass>org.springframework.web.filter.HiddenHttpMethodFilter</filterclass>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在Handler方法中
@RequestMapping(value = "/demo/{id}",method = {RequestMethod.GET})
public ModelAndView demoGet(@PathVariable("id") Integer id) {
//这里进行查询操作
}
@RequestMapping(value = "/demo/{id}",method = {RequestMethod.POST})
public ModelAndView demoPost(@PathVariable("id") Integer id) {
//这里进行新增操作
}
@RequestMapping(value = "/demo/{id}",method = {RequestMethod.PUT})
public ModelAndView demoPut(@PathVariable("id") Integer id) {
//这里进行修改操作
}
@RequestMapping(value = "/demo/{id}",method = {RequestMethod.DELETE})
public ModelAndView demoDelete(@PathVariable("id") Integer id) {
//这里进行删除操作
}
Spring MVC的JSON交互
JSON是一组以特定格式书写的字符串,它与语言无关,JSON用特殊符号{}表示对象,特殊符号[]表示数组
{“name”: “aa”} 表示一个包含name为aa的json对象
[{“name”: “aa”},{“name”: “bb”}] 表示一个包含name为aa和name为bb的json数组
Spring MVC使用JSON格式交互需要引用JSON相关的jar包用以支持
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
在Handler方法的参数上需要标识注解@RequestBody用于表示当前参数是以JSON格式传入,在方法上或者方法的返回参数前标识注解@ResponseBody用于表示当前返回参数是以JSON格式传递
@RequestMapping("/method")
public @ResponseBody ResponseVO method(@RequestBody RequestVO requestVO) {
}
@RequestMapping("/method")
@ResponseBody
public ResponseVO method(@RequestBody RequestVO requestVO) {
}
在添加了@ResponseBody注解后,不再走视图解析器流程,直接等同于response输出