Spring MVC是在MVC设计思想的基础上产生的一种框架,可以理解为Spring的一个子模块,相当于Spring AOP这种
一.Spring MVC主要组件
1.DispatcherServlet
控制中心,控制其它组件执行,统一调度,降低组件之间的耦合性,提高每个组件的扩展性。
2.HandlerMapping
通过扩展处理器映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3.HandlAdapter
通过扩展处理器适配器,支持更多类型的处理器;通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,开发人员只需要开发具体的【Handle组件】即可
4.ViewResolver
通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、freemarker、pdf、excel等,开发人员只需要开发具体的【view组件】,如jsp页面等等。
二、配置
web.xml中添加
<!-- 定义DispatcherServlet -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 默认/WEB-INF/[servlet名字]-servlet.xml加载上下文,
如果配置了contextConfigLocation参数,
将使用classpath:/mvc-dispatcher-servlet.xml加载上下文
-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 拦截匹配的请求,/表示拦截所有出了jsp文件,这里所有请求采用名字为mvc-dispatcher的DispatcherServlet处理 -->
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 扫描 controller -->
<context:component-scan base-package="com.my.test.controller" />
<mvc:default-servlet-handler />
<!-- 配置静态资源,直接映射到对应的文件夹,DispatcherServlet 不处理 -->
<mvc:resources mapping="/static/**" location="/static/" />
<!-- 注解驱动 -->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<ref bean="fastJsonHttpMessageConverter" />
<ref bean="stringHttpMessageConverter" />
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- StringHttpMessageConverter编码为UTF-8,防止乱码 -->
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
<property name="supportedMediaTypes">
<list>
<bean class="org.springframework.http.MediaType">
<constructor-arg index="0" value="text" />
<constructor-arg index="1" value="plain" />
<constructor-arg index="2" value="UTF-8" />
</bean>
<bean class="org.springframework.http.MediaType">
<constructor-arg index="0" value="*" />
<constructor-arg index="1" value="*" />
<constructor-arg index="2" value="UTF-8" />
</bean>
</list>
</property>
</bean>
<!--JSP视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="contentType" value="text/html;charset=UTF-8"/>
</bean>
</beans>
三、返回值处理器
所有经过Servlet程序返回到客户端的数据,都需要通过HttpServletResponse对象的响应体去返回。
1.有ResponseBody注解
- 根据返回值类型,匹配合适的HTTPMessageConverter
- 通过HTTPMessageConverter对返回值进行处理
- 1)MappingJacksonHTTPMessageConverter:处理POJO类型(需要类型转换用到(Jackson jar包;传输媒体类型application/json;编码charset=utf8
- 2)StringHTTPMessageConverter:处理String类型,不需要类型转换(传输媒体类型text/plain;编码charset=utf8)
2.无ResponseBody注解
String返回值表示意思
- 逻辑视图名称---比如test.jsp 则此处写test
- 重定向 则写direct:url
- 请求转发则forwar:url
四、参数绑定
1.直接在url中通过问号传简单参数
如http://localhost:8080/springmvc/test/queryinfo?id=1&name=laowang
controller方法接收
@RequestMapping(“queryinfo”)
public String queryinfo(int id,String name)
将URL中的请求参数,进行类型转换(String或其他类型),将转换之后的值再赋值给Controller方法【形参】中 ,请求参数的key,需要和Controller方法形参名称一致(类型如果不匹配会报错)
2.@RequestParam注解
相当于request.getParameter(请求参数的key),将获取的值,绑定到该注解修饰的参数中,有3个属性
- value:URL请求参数的key
- required:true/false,表示该URL是否必须要带有该参数,默认是true
- default:如果required设置为true,但是URL中有没有指定的key,则默认取该值去进行参数绑定
3.直接在url中通过问号传POJO参数
- 使用一个POJO类型的参数作为Controller方法的形参,进行参数绑定
- 请求参数的key,需要和一个POJO类型的属性名称一致
- 如果参数的key出现.这种方式(address.provinceName),需要POJO类型中嵌套POJO类型的属性进行接收请求参数(User#Address(address)#provinceName)。
@RequestMapping(value="saveUser")
public String saveUser(User user,Model model) {
model.addAttribute("msg", "接收到的参数:"+user.toString());
return "list";
}
a.带日期类型参数处理
1)自定义一个日期转换类
public class DateConverter implements Converter<String, Date>{
@Override
public Date convert(String source) {
// 使用Java中 SimpleDateFormat API完成日期转换
String pattern = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern );
try {
return dateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
2)将Converter注册到处理器适配器中
<!-- 注解驱动 -->
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters register-defaults="true">
<ref bean="fastJsonHttpMessageConverter" />
<ref bean="stringHttpMessageConverter" />
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 配置ConversionService -->
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.my.test.converter.DateConverter"></bean>
</set>
</property>
</bean>
b.集合或者类型参数
- 直接使用List集合或者数组作为形参,数组不会报错(传值如id=1&id=2&id=3),List集合会报错
- 直接使用POJO类型作为形参,并且该POJO类型拥有一个List集合属性或者数组属性,这种情况下List和数组都可以成功接收参数
- 请求参数key和形参名称或者属性名称要一致
@RequestMapping(value="saveDept")
public String saveDept(Dept dept,Model model) {
model.addAttribute("msg", "接收到的参数:"+dept.getList());
return "list";
}
public class Dept {
private String name;
private List<Integer> list;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Integer> getList() {
return list;
}
public void setList(List<Integer> list) {
this.list = list;
}
}
c.pojo元素类型的集合或数组
- 直接使用List集合或者数组作为形参,都会报错
- 必须使用POJO类型作为形参,并且该POJO类型拥有一个List集合属性或者数组属性。这种情况下List和数组都可以成功接收参数
- 请求参数key和属性名称要一致。
Get请求形式userlist[0].id=1&userlist[0].name=zhangsan&userlist[1].id=2&userlist[1].name=laowang
d.Map集合
- 需要使用POJO形参来接收,POJO类型中要有一个Map类型的参数
- Map类型的属性名称,要和请求参数的[]前面的名称一致
- Map的key要唯一,Map的value是一个POJO类型
Get形式userlist['user1'].id=1&userlist['user1'].name=zzy&userlist['user2'].id=2&userlist['user2'].name=zyi
e.文件类型
- form表单需要设置enctype=multipart/form-data
- commons-fileupload、commons-io依赖包
- MultipartResolver:解析文件类型的参数,绑定到MultipartFile类型的参数中,需要在springmvc.xml配置,MultipartFile通过该参数,可以获取文件数据,包括文件名称和文件内容
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件限制,字节单位-->
<property name="maxUploadSize" value="10485760"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>