1.MVC是什么?
MVC用于解耦各个模块。
2.SpringMVC是什么?
①SpringMVC的核心在于其流程。
②SpringMVC是一种基于Servlet的技术,它提供了核心控制器DispatcherServlet和相关的组件。
③SpringMVC从某个角度看是一个消息传递和处理的框架。
3.控制器的开发:
①获取请求参数(@RequestParam,@SessionAttribute):建议不要使用Servlet容器所给予的API,因为这样控制器会依赖于Servlet容器。
②处理业务逻辑
③绑定模型和视图
4.控制器接收各类请求参数:
①接收普通请求参数:通过参数名称和HTTP请求参数的名称保持一致来获取参数。如果参数多,就使用POJO。
②使用@RequestParam注解获取参数:用来给Http传过来的参数给一个别名。默认请求参数不为空。required=true。
③使用URL传递参数:一些网站使用URL的形式传递参数,这符合RESTFul风格。@PathVariable和@RequestMapping两个注解共同完成。
④传递JSON参数:1.JSON数据需要和对应参数的POJO保持一致。2.需要告知请求的参数类型为JSON。(contentType:“application/json”)3.将JSON转化为字符串传递。
data:JSON.stringify(data) 4.使用@RequestBody接收参数。
⑤接收列表数据和表单序列化:通过JSON的字符串化将参数传递到后台。通过@ResponseBody将对应的JSON数据转换出来。
5.重定向:
①SpringMVC有一个约定,当返回的字符串带有redirect的时候,它就会认为需要的是一个重定向,而事实上,不仅可以通过返回字符串来实现重定向,也可以通过返回视图来实
现重定向。
②在URL重定向的过程中,并不能有效传递对象。HTTP的重定向参数是以字符串传递的。这个时候SpringMVC提供了一个方法——flash属性,你需要提供的数据模型就是一个
RedirectAttribute。
③使用addFlashAttribute方法后,SpringMVC会将数据保存到Session中,重定向后就将其消除,这样就能够传递数据给下一个地址了。
④流程是:使用addRedirectAttribute方法保存数据模型->返回重定向字符串或视图->保存到Session中->执行重定向->读取数据并清除Session保存的数据->调用重定向指定方
法或者页面。
6.保存并获取属性参数:
①SpringMVC给予了支持,主要注解3个:@RequestAttribute、@SessionAttribute和@SessionAttributes(配置一个字符串数组,这个数组对应的是数据模型对应的键值对,
然后将这些键值对保存到Session中)。没有@RequestAttributes是因为在请求的范围中,SpringMVC更希望你使用它所提供的数据模型。它的数据模型本身就是在请求的生命
周期中存在的。
②@SessionAttributes只能对类进行标注,不能对方法或者参数注解。
@SessionAttributes(names={}, types={}) //可以配置数据模型的名称和类型,两者取或关系
③注解@CookieValue(value="", required="", defaultValue="")和注解@RequestHeader(value="", required="", defaultValue="")。
value:参数名,default""。
required:是否请求头中必须带有value指定的参数。
defaultValue:如果value指定的参数值不存在或者为空,那么将使用默认值。
7.拦截器:
①拦截器是SpringMVC中强大的控件,它可以在进入处理器之前做一些操作,或者在处理器完成后进行操作,甚至是在渲染视图后进行操作。
②Spring要求拦截器实现接口org.springframework.web.servlet.HandlerInterceptor:
preHandle:在处理器之前执行的前置方法,返回一个boolean值,会影响后面SpringMVC的流程。
postHandle:在处理器之后执行的后置方法,处理器的逻辑完成后运行它。
afterCompletion:无论是否产生异常都会在渲染视图后执行的方法。
③mvc:annotation-driven或@EnableWebMvc系统会初始化拦截器ConversionServiceExposingInterceptor,它是一个一开始就被SpringMVC系统默认加载的拦截器,它的
主要作用是根据配置在控制器上的注解来完成对应的功能。SpringMVC提供的公共拦截器HandlerInterceptorAdapter,这两个注解,Spring之所以那么做,使为了提供适配器,
就是当只想实现3个拦截器方法中的一到两个时,那么只要继承它,根据需要覆盖掉原有的方法就可以了。即:
注册了一个RequestMappingHandlerMapping、一个RequestMappingHandlerAdapter、以及一个ExceptionHandlerExceptionResolver 以支持使用注解Controller的注解方
法(如@RequestMapping、@ExceptionHandler)来处理request。
④多个拦截器,是责任链模式。
8.验证表单:
①使用JSR303注解验证输入内容。
②使用验证器验证复杂的规则:@Valid。
③两者不能同时使用。不过可以在使用JSR303注解方式得到基本的检验信息后,再使用自己的方法进行验证。
9.数据模型:
①从控制器获取数据后,会装载数据到数据模型和视图中,然后将视图名称转发到视图解析器中,通过解析器解析后得到最终视图,最后将数据模型渲染到视图中,展示最终的结果
给用户。
②Model和ModelMap都可以作为数据模型。
10.视图和视图解析器?
①视图分为逻辑视图和非逻辑视图。逻辑视图需要一个视图解析器,以定位真实视图。非逻辑视图直接将数据模型渲染便结束了。
②View接口重要的方法:getContentType方法和render方法。
getContentType():标明给用户什么类型的文件响应,可以是HTML、JSON、PDF等。
render(Map <String, ?>model, HttpServletRequest request, HttpServletResponse response) throws Exception
:是一个渲染视图的方法,通过它就可以渲染视图
了。
③在SpringMVC中实现视图的类很多,比如JSTL视图JstlView,JSON视图MappingJackson2JsonView,PDF视图AbstractPdfView等。由于视图类众多,所以本书只讨论
JstlView、InternalResourceView和MappingJackson2JsonView等几种最常用的视图。JstlView和InternalResourceView是父子关系。主要是为了JSP的渲染而服务的,我们可
以使用JSTL标签库,也可以使用SpringMVC所定义的标签库。
④Excel视图的使用:导出数据库的数据。
11.SpringMVC的文件上传:是通过MultipartResolver(Multipart解析器)处理的。
①MultipartResolver是一个接口有两个实现类。
CommonsMultipartResolver:依赖于Apache下的jakarta Common FileUpload项目解析Multipart请求,可在Spring各版本使用,只是它要依赖第三方包才得以实
现。
StandardServletMultipartResolver:是Spring3.1版本后的产物,它依赖于Servlet3.0或更高版本的实现,它不依赖于第三方包。
②提交上传文件表单:一般而言,文件提交会以POST请求为主,所以先来建一个表单,使用它可以上传文件。
12.SpringMVC的数据转换和格式化?
①在SpringMVC的流程中我们谈到处理器,就可以知道处理器并非控制器,但是它包含了控制器的逻辑,在运行控制器之前,它就会使用这些转换器把HTTP的数据转换为对应的
类型,用以填充控制器的参数,这就是为什么可以在控制器保持一定的规则下就能够得到参数的原因。当控制器返回数据模型后,再通过SpringMVC后面对应的流程渲染数据,
然后显示给客户端。
②对于转换器而言,在Spring中分为两大类,一种是由Converter接口所定义的,另外一种是GenericConverter(集合转换器),它们都可以使用注册机注册。它们都是来自
Spring Core项目而非Spring MVC项目,它的作用范围是Java内部各种类型之间的转换。
②一对一转换器(Conventer):有时候我们响应进行自定义转换规则,只要实现接口Converter,然后注册给对应的转换服务类就可以了。
③数组和集合转换器(GenericConventer):它能够满足数组和集合转换的要求。
④使用格式化器(Formatter):扩展了两个接口Printer和Parser。
通过print方法能将结果按照一定的格式输出字符串。
通过parse方法能够将满足一定格式的字符串转换为对象。
常用的两个注解@DateTimeFormat和@NumberFormat 。(Formatter)
13.为控制器添加通知:不常用。
14.处理异常:Spring中一部分异常默认的映射码非常有用具体见org.springframework.http.HttpStatus。
15.国际化。
16.通过注解配置方式初始化:
①继承一个AbstractAnnotationConfigDispatcherServletInitializer。
②实现3个抽象方法。IoC+DispatcherServlet+ServletMapping。
③参照xml配置写注解。注意些许差别。
17.mvc:annotation-driven and @EnableWebMvc?
对于SpringMVC,在XML配置了mvc:annotation-driven,或者Java配置的注解上加入@EnableWebMvc的时候,SpringIoC容器会自定义生成一个关于转换器和格式化器类的
实例——FormattingConversionServiceFactoryBean,这样就可以从SpringIoC容器中获取这个对象了。它是一个工厂(Factory),对于工厂而言,需要生成它的产品。它的产
品主要就是DefaultFormattingConversionService类对象,类对象继承了一些类,并实现了许多接口。
18.SpringMVC中处理器和控制器的区别?
在SpringMVC的流程中我们谈到的处理器,这个处理器并非控制器,但是它包含了控制器的逻辑,在运行控制器之前,它就会使用这些转换器把HTTP的数据转换为对应的类型,
用以填充控制器的参数,这就是为什么可以在控制器保持一定的规则下就能够得到参数的原因。当控制器返回数据模型后,再通过SpringMVC后面对应的流程渲染数据,然后显
示给客户端。
19.转换器?
在Spring中分为两大类,一种是由Converter接口所定义的,另外一种是GenericConverter,它们都可以使用注册机注册。它们都来自SpringCore项目,而非SpringMVC项目,
它的作用范围是Java内部各种类型之间的转换。
20.HttpMessageConverter?
①HttpMessageConvertre是定义从HTTP接收请求信息和应答给用户的。
②HttpMessageConverter是一个比较广的设置,虽然SpringMVC实现它的类有很多种,但是真正在工作和学习种使用得比较多的只有
MappingJackson2HttpMessageConverter,这是一个关于JSON消息的转换类,通过它能够把控制器返回的结果在处理器内转换为JSON数据。
③使用之前需要配置,先注册MappingJackson2HttpMessageConverter。
21.实用代码
/**用XML配置/
/web.xml配置初始化SpringIoC容器和配置DispatcherServlet/
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<!-- 配置Spring IoC配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<!-- 配置ContextLoaderListener用以初始化SpringIoC容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 字符过滤器 -->
<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>
<!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
<!-- MultipartResolver参数 单个文件5MB,总10MB -->
<multipart-config>
<location>filename</location>
<max-file-size>5242880</max-file-size>
<max-request-size>10485760</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
/******************dispatcher-servlet.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- 使用注解驱动 -->
<mvc:annotation-driven />
<!-- 定义扫描装载的包 -->
<context:component-scan base-package="com.*" />
<!-- 定义视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp">
</bean>
<!-- MappingJackson2HttpMessageConverter -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 如果有配置数据库事务,需要开启注解事务,需要开启这段代码 -->
<!--
<tx:annotation-driven transaction-manager="transactionManager"/>
-->
</beans>
/***********************用注解来配置**********************/
/******WebAppInitializer******/
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
// SpringIoC环境配置
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO 自动生成的方法存根
//配置Spring IoC资源
return new Class<?>[] {RootConfig.class};
}
// DispatcherServlet环境配置
@Override
protected Class<?>[] getServletConfigClasses() {
// TODO 自动生成的方法存根
//加载Java配置类
return new Class<?>[] {WebConfig.class};
}
//DispatcherServlet拦截请求配置
@Override
protected String[] getServletMappings() {
// TODO 自动生成的方法存根
return new String[]{"*.do"};
}
//配置上传文件的限制
@Override
protected void customizeRegistration(Dynamic dynamic){
//文件上传路径
String filepath = "";
//5MB
Long singleMax = (long)(5*Math.pow(2,20));
//10MB
Long totalMax = (long)(10*Math.pow(2,20));
//配置MultipartResolver,限制请求,单个文件5MB,总文件10MB
dynamic.setMultipartConfig(new MultipartConfigElement(filepath, singleMax, totalMax, 0));
}
}
/*****RootConfig*****/
@Configuration
@ComponentScan(basePackages="com.ssm.chapter22.service",includeFilters={@Filter(type=FilterType.ANNOTATION, value={Service.class})})
@EnableTransactionManagement
public class RootConfig implements TransactionManagementConfigurer{
private DataSource dataSource = null;
//配置数据库
@Bean(name="dataSource")
public DataSource initDataSource(){
if(dataSource != null){
return dataSource;
}
Properties props = new Properties();
props.setProperty("driverClassName", "com.mysql.jdbc.Driver");
props.setProperty("url", "");
props.setProperty("username", "");
props.setProperty("password", "");
props.setProperty("maxTotal", "200");
props.setProperty("maxIdle", "20");
props.setProperty("maxWaitMillis", "30000");
try{
dataSource = BasicDataSourceFactory.createDataSource(props);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return dataSource;
}
//配置SqlSessionFactoryBean
@Bean(name="sqlSessionFactory")
public SqlSessionFactoryBean initSqlSessionFactory(){
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(initDataSource());
//配置MyBatis配置文件
Resource resource = new ClassPathResource("mybatis-config.xml");
sqlSessionFactory.setConfigLocation(resource);
return sqlSessionFactory;
}
//MapperScannerConfigurer
@Bean
public MapperScannerConfigurer initMapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.ssm.chapter22.dao");
msc.setSqlSessionFactoryBeanName("sqlSessionFactory");
msc.setAnnotationClass(Repository.class);
return msc;
}
//实现接口方法,注册注解事务,当@Transactional使用的时候产生数据库事务
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
// TODO 自动生成的方法存根
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(initDataSource());
return transactionManager;
}
}
/*****WebConfig*****/
@Configuration
@ComponentScan(basePackages="com.ssm.chapter22.controller", includeFilters={@Filter(type=FilterType.ANNOTATION, value=Controller.class)})
@EnableWebMvc
public class WebConfig {
@Bean(name="internalResourceViewResolver")
public ViewResolver initViewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
//初始化RequestMappingHandlerAdapter,并加载Http的Json转换器
@Bean(name="requestMappingHandlerAdapter")
public HandlerAdapter initRequestMappingHandlerAdapter(){
//创建RequestMappingHandlerAdapter适配器
RequestMappingHandlerAdapter rmhd = new RequestMappingHandlerAdapter();
//Http JSON转换器
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
//http类型支持JSON类型
MediaType mediaType = MediaType.APPLICATION_JSON_UTF8;
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(mediaType);
//加入转换器的支持类型
jsonConverter.setSupportedMediaTypes(mediaTypes);
//往适配器加入JSON转换器
rmhd.getMessageConverters().add(jsonConverter);
return rmhd;
}
}