SpringMVC
-
SpringMVC介绍
用我们自己的话来说:SpringMVC 是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级WEB层框架。
作用:
参数绑定(获得请求参数)
调用业务
响应 -
SpringMVC 的优点
1)清晰的角色划分:
前端控制器(DispatcherServlet)
请求到处理器映射(HandlerMapping)
处理器适配器(HandlerAdapter)
视图解析器(ViewResolver)
处理器或页面控制器(Controller)
验证器( Validator)
命令对象(Command 请求参数绑定到的对象就叫命令对象)
表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
2)分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。
3)由于命令对象就是一个 POJO,无需继承框架特定 API,可以使用命令对象直接作为业务对象。
4)和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。
5)可适配,通过 HandlerAdapter 可以支持任意的类作为处理器。
6)可定制性, HandlerMapping、 ViewResolver 等能够非常简单的定制。
7)功能强大的数据验证、格式化、绑定机制。
8)利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。
9)本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
10)强大的 JSP 标签库,使 JSP 编写更容易。
………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配置支持等等。 -
SpringMVC请求响应流程
-
SpringMVC的组件
-
RequestMapping注解详解
1)RequestMapping
作用:
RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系
把url与controller中的方法进行绑定,当请求过来时,通过url去找对应的controller对应的方法,再调用
使用的位置:
RequestMapping注解可以作用在方法和类上
使用在类上:
请求 URL 的第一级访问目录。此处不写的话,就相当于应用的根目录。 写的话需要以/开头 .它出现的目的是为了使我们的 URL 可以按照模块化管理
访问的url = /类上的requestmapping/方法上的requestmapping
使用在方法上:
请求 URL 的第二级访问目录
RequestMapping的属性:
path: 指定请求路径的url
value: value属性和path属性是一样的
method : 指定该方法的请求方式
params: 指定限制请求参数的条件
headers: 发送的请求中必须包含的请求头 -
SpringMVC进阶
1)请求参数的绑定
请求参数类型是简单(基本,String)类型- 方法的形参和请求参数的name一致就可以
请求参数类型是pojo对象类型 - 形参就写pojo对象
- pojo的属性必须和请求参数的name一致就可以
请求参数类型是pojo对象类型, 包含集合 - 形参就写pojo对象
- pojo的属性必须和请求参数的name一致就可以
- 如果包含List, 请求的list的属性名[下标].pojo属性名
- 如果包含map, 请求的map的属性名[key].pojo属性名
提交数组,只能用数组接收,多个参数的参数名一致,参数要与controller中的参数名一致. 如果想List来接收就得加@ReqeustParam注解
【注:严格区分大小写】
不能直接提交List与map集合, 需要通过其它方式转换(fastjson)
2)请求参数细节和特殊情况
1-请求参数乱码处理
在web.xml里面配置编码过滤器
- 方法的形参和请求参数的name一致就可以
<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>
2-自定义类型转换器
默认情况下,SpringMVC已经实现一些数据类型自动转换。 内置转换器全都在: org.springframework.core.convert.support
包下 ,如遇特殊类型转换要求,需要我们自己编写自定义类型转换器。
步骤:
- 创建一个类实现Converter 接口
- 配置类型转换器
实现:
- 定义一个类,实现 Converter 接口
该接口有两个泛型,S:表示接受的类型, T:表示目标类型(需要转的类型)
public class StringToDateConverter implements Converter<String,Date> {
@Nullable
@Override
public Date convert(String s) {
try {
if(StringUtils.isEmpty(s)){
throw new RuntimeException("字符串不能为null");
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
return dateFormat.parse(s);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
}
在springmvc.xml里面配置转换器
spring 配置类型转换器的机制是,将自定义的转换器注册到类型转换服务中去
<!-- 配置类型转换器 -->
<bean id="converterService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 给工厂注入一个新的类型转换器 -->
<property name="converters">
<array>
<!-- 配置自定义类型转换器 -->
<bean class="com.itheima.web.StringToDateConverter"></bean>
</array>
</property>
</bean>
在 annotation-driven 标签中引用配置的类型转换服务
<!--配置Spring开启mvc注解-->
<mvc:annotation-driven conversion-service="converterService"></mvc:annotation-driven>
3-使用Reqeust与Response
SpringMVC 还支持使用原始 ServletAPI 对象作为控制器方法的参数。我们可以把它们直接写在控制的方法参数中使用。 支持原始 ServletAPI 对象有 :
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer
9. 常用注解
- @RequestParam
作用:
把请求中指定名称的参数给控制器中的形参赋值。
属性
value: 请求参数中的名称。
required:请求参数中是否必须提供此参数。 默认值: true。表示必须提供,如果不提供将报错。
defaultValue:默认值
使用场景:form提交,url参数使用的是?方式来提交请求
小结:
@RequestParam 只能用于接收 url 的传参 ?name=xxx, form表单的提交。使用list来接收数组类型
无法接收提交的json数据(contentType=application/json)
2.@RequestBody
作用 - 用于获取请求体内容。 直接使用得到是 key=value&key=value…结构的字符串。
- 把获得json类型的数据转成pojo对象(后面再讲)【推荐】
注意: get 请求方式不适用。
属性
required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值为 false, get 请求得到是 null。
@RequestBody 不能使用get请求, 在Controller的方法参数里,有且只有一个
3.@PathVariable
作用:
用于绑定 url 中的占位符。 例如:请求 url 中 /delete/{id}, 这个{id}就是 url 占位符。
url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。
属性:
value: 用于指定 url 中占位符名称。
required:是否必须提供占位符。
场景:获取路径中的参数
4.@RequestHeader
作用:
用于获取请求消息头。
属性:
value:提供消息头名称
required:是否必须有此消息头
从请求头中获取参数,鉴权(token) Authorization
5.@CookieValue
作用:
用于把指定 cookie 名称的值传入控制器方法参数。
属性:
value:指定 cookie 的名称。
required:是否必须有此 cookie。
10.响应数据和结果视图
1-返回页面视图
–返回页面文件名字符串
controller方法的返回的字符串会被解析成页面视图,编写代码时只需要留意文件名,无须关注在页面在哪里
–返回字符串带关键字forward
controller 方法在提供了 String 类型的返回值之后,默认就是请求转发。我们也可以加上 forward:
可以转发到页面,也可以转发到其它的controller方法
–ModelAndView
ModelAndView 是 SpringMVC 为我们提供的一个对象,该对象也可以用作控制器方法的返回值。
–Model
–返回字符串关键字redirect
contrller 方法提供了一个 String 类型返回值之后, 它需要在返回值里使用: redirect:
同样可以重定向到页面,也可以重定向到其它controller
2-转发和重定向区别
1.转发是一次请求, 重定向是两次请求
2.转发路径不会变化, 重定向的路径会改变
3.转发只能转发到内部的资源,重定向可以重定向到内部的(当前项目里面的)也可以是外部的(项目以外的)
4.转发可以转发到WEB-INF里面的资源, 重定向不可以重定向到WEB-INF里面的资
3-返回json数据
@ResponseBody注解说明
@ResponseBody用于将 Controller 的方法返回的对象,通过 HttpMessageConverter 接口转换为指定格式的数据如: json,xml 等,通过 Response 响应给客户端
用法:
在Controller类: 代表该Controller类中所有的方法都使用@ResponseBody,即都直接返回对象数据
在Controller类的方法上: 将该方法的返回值转成json对象返回给客户端
SpringMVC对json数据的处理
Springmvc 默认用 MappingJacksonHttpMessageConverter 对 json 数据进行转换,需要添加jackson依赖
另外还可以配置其它转化,如传智健康练习中使用fastjson来做json转换
11. 静态资源过滤
default-servlet-handler
使用这个标签的前提是dispatcherServlet的拦截路径是/的情况下才有用。tomcat的web.xml中自带一个defaultServlet的处理,是转门来处理html,css,js,jpg等静态资源用的。由于我们的项目的web.xml中的diaspatcherServlet拦截的url-parttern与tomcat中defaultServlet是一样,当请求过来时,优先进入dispacherServlet,因此这个标签的意思是:dispatcherServlet不对它(.html,.css,.js…)处理,而是交给tomcat来处理,而tomcat则会对它们放行。
在springmvc.xml中添加
mvc:default-servlet-handler/
resources
DispatcherServlet会拦截(url-pattern为/时)到所有的资源(除了JSP),导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截.
语法: <mvc:resources location="/css/" mapping="/css/**"/>
, location:webapp目录下,mapping:匹配请求路径的格式
在springmvc.xml中添加
<!-- 设置静态资源不过滤 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
拦截*.do
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!--拦截所有请求,除jsp外-->
<!--<url-pattern>/</url-pattern>-->
<!--只拦截*.do结尾的请求, 请求的url就得加.do
不会拦截.jsp, .html,.js, .css .jpg
不需要配置mvc:resources, default-servlet-handler
-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
【小结】
- 过滤静态资源, 因此dispatcherServlet 拦截了/ 所有除jsp外,就导致.js, .css 报404
- 方式:
- mvc:default-servlet-handler springmvc.mxl
- mvc:resources location, mapping springmvc.xml
- web.xml dispatcherServlet拦截*.do