前言
- springMVC 是什么?
- 我们为什么学习 springMVC?
- springMVC 依赖。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
一、springMVC
1.1、MVC 模型
- 模型,视图,控制器,是一种软件设计的规范。
- 把业务逻辑,视图,数据分离开来组织代码。
- 降低视图和业务逻辑的耦合性。
1.2、springMVC 的执行过程
- 用户发送请求,DispatcherServle 控制器接收请求并拦截请求。
- http: //localhost: 8080/springMVC/hello
- http: //localhost: 8080 表示服务器域名
- hello 表示控制器
- 以上 url 表示:请求位于服务器 localhost:8080 上的 springMVC 站点的 hello 控制器。
- DispatcherServlet 调用 HandlerMapping,查找具体的 Handler。
- HandlerExecution 是具体的 Handler,主要作用是根据请求的 url 找到具体的控制器(controller),HandlerExecution 将解析后的信息返回给 DispatcherServlet。
- DispatcherServlet 调用 HandlerAdapter,HandlerAdapter 按照特定的规则(实现 controller 接口)执行 Handler。
- Handler 会让具体的控制器(controller)执行。
- 控制器(controller)执行完成后返回给 HandlerAdapter 一个 ModelAndView。
- HandlerAdapter 把 ModerAndView 返回给 DispatcherServlet。
- DispatherServlet 把 ModelAndView 传给 ViewResolver。
- ViewResolver 执行完成后返回给 DispatherServlet 一个具体的 View。
- viewResolver 获取 mv 的数据;
- 解析 mv 的视图名字;
- 拼接视图名字找到对应的视图;
- 将数据渲染到视图上。
- DispatcherServlet 根据视图解析器解析的视图结果,调用具体的视图。
- DispatcherServlet 把视图响应呈现给用户。
1.3、springMVC 的配置文件的方式
// springMVC的web.xml配置
<!--配置dispatcherServlet:springMVC的核心-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--dispatcherServlet绑定spring的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<!--启动级别-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--
/:只匹配所有的请求,不匹配jsp页面
/*:匹配所有的请求,包括jsp页面
-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
// spring-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!--处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!--视图解析器:模板引擎可以替换,Thymeleaf,Freemarker...-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--BeanNameUrlHandlerMapping:bean-->
<bean id="/hello" class="com.sywl.servlet.HelloServlet"></bean>
</beans>
1.4、springMVC 的注解配置的方式
springMVC 的 web.xml 的配置不变
// spring-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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="com.sywl.controller"/>
<!--让springMVC不处理静态资源:css,js,图片等等-->
<mvc:default-servlet-handler/>
<!--
帮助我们完成DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例的注册,这两个实例是为了让@RequestMapping注解生效
-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
1.5、springMVC 的转发和重定向
- 跳转页面通过ModelAndView
ModelAndView
设置ModelAndView对象,根据view的名称和视图解析器跳转到指定的页面。
页面:{视图解析器前缀}+viewName+{视图解析器后缀} - 通过设置ServletAPI,不需要视图解析器
- 通过HttpServletResponse进行输出:resp.getWriter().println(“Hello,Spring By Servlet API”);
- 通过HttpServletResponse实现重定向:resp.sendRedirect(“/index.jsp”);
- 通过HttpServletResponse实现转发:resp.getRequestDispatcher(“/WEB-INF/jsp/test.jsp”).forward(req,resp);
- springMVC的转发和重定向
![](https://img-blog.csdnimg.cn/img_convert/e5695821d523a62611e8aad87452f7f9.jpeg#clientId=ucdd852e3-8d1d-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u00dcf068&margin=[object Object]&originHeight=502&originWidth=775&originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u5989495d-f2b0-40c3-9ac7-ffe4210b313&title=)
![](https://img-blog.csdnimg.cn/img_convert/54b7c1674ab61d639511a8bca54ccde0.jpeg#clientId=ucdd852e3-8d1d-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u5451974a&margin=[object Object]&originHeight=478&originWidth=779&originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u2d2b074e-022c-4c09-aecc-9268d0edae4&title=)
1.6、springMVC 接收请求参数
- 前端传递的参数名和方法上的参数名相同,可以直接接收参数使用。
- 前端传递的参数名和方法上的参数名不相同,可以使用@RequestParam指定前端传递的参数名和方法上的参数名绑定。
// http://localhost:8080/add?username=xxx
@RequestMapping("/add")
public String test(@RequestParam("username") String name){
// @RequestParam限定前端传递的参数名只能是username并且和方法上的参数名name绑定。
// 如果前端传递的参数名不是username,则会报错。
return "test";
}
- 前端传递对象时,方法上可以用实体类进行接收。
(前端传递的一个对象 User, 后端 User 实体类匹配传递来的 User 对象中的字段名: 如果名字一致则接收参数,否则匹配不到)
1.7、springMVC 的数据回显
- Model: 简化版,只有简单的几个方法适用于存储数据,对新手友好。
- ModelMap: 继承了 LinkedMap,除自身方法,还继承了 LinkedMap 的方法和特性。
- ModelAndView: 可以在存储数据的同时,设置返回的逻辑视图,控制展示的跳转。
1.8、springMVC 的乱码解决
post 提交中文乱码的解决,一般配置 springMVC 过滤器就可以解决。实在解决不掉,把视频再看一遍。
配置web.xml文件
<filter>
<filter-name>encoding</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>encoding</filter-name>
<!--注意是/*-->
<url-pattern>/*</url-pattern>
</filter-mapping>
二、Restful 风格
Restful 就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。
基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
- 使用 RESTful 操作资源:可以通过不同的请求方式来实现不同的效果!比如: 请求地址一样,但是功能可以不同。
- GetMapping
- PostMapping
- DeleteMapping
- PutMapping
- 路径参数@PathVariable
// Restful:http://localhost:8080/add/a/b
@RequestMapping("/add/{a}/{b}")
public String test(@PathVariable int a,@PathVariable int b){
int sum = a+b;
return "test";
}
三、JSON
3.1、json
- json 是一种轻量级的数据交换格式。
- json 和 js 对象的关系:json 是 js 对象的字符串表示法,json 本质上就是一个字符串。
- json 和 js 对象的互相转换。
- 对象的键名也可以使用引号包裹。
var obj = JSON.parse('{"name":"zs","age":"12"}')
// {name:"zs",age:12}
var json = JSON.Stringify({name:"zs",age:12})
// '{"name":"zs","age":"12"}'
3.2、Jackson(对象转成 json 字符串)
- 导入 Jackson 包。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9.2</version>
</dependency>
- springmvc 的配置文件配置中文乱码的问题。
// spring-servlet.xml
<!--jackson乱码问题配置-->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="ObjectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
- 写工具包 JsonUtil
public class JsonUtil {
public static String getJson(Object obj){
return getJson(obj,"yyyy-MM-dd HH:mm:ss");
}
public static String getJson(Object obj, String dataFormat){
ObjectMapper mapper = new ObjectMapper();
// 不适用时间戳的格式返回
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
// 自定义日期的格式
SimpleDateFormat sdf = new SimpleDateFormat(dataFormat);
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
- 使用
@RequestMapping("/hello")
@ResponseBody
public String hello(){
User user = new User();
user.setName("张三");
user.setHobby("计算机");
user.setAge(12);
return JsonUtil.getJson(user);
}
3.3、Fastjson(对象转成 json 字符串)
- 导入 Fastjson 包。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
- 使用
@RequestMapping("/hello2")
@ResponseBody
public String hello2(){
User user = new User();
user.setName("张三");
user.setHobby("计算机");
user.setAge(12);
return JSON.toJSONString(user);
}
Fastjson 的三个主要的类
- JSONObject 代表 json 对象
- JSONObject 实现了 Map 接口. 猜想 JSONObject 底层操作是由 Map 实现的
- JSONObject 对应 json 对象, 通过各种形式的 get() 方法可以获取 json 对象中的数据, 也可利用 size(), isEmpty() 等方法获取” 键: 值” 对的个数和判断是否为空, 其本质是通过实现 Map 接口并调用接口中的方法完成的.
- JSONArray 代表 json 对象数组
- 内部是有 List 接口中的方法来完成操作的。
- JSON 代表 JSONObject 和 JSONArray 的转化
- JSON 类源码分析与使用
- 仔细观察这些方法, 主要是实现 json 对象, json 对象数组, javabean 对象, json 字符串之间的相互转化。
四、AJax
- AJAX 是 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
- AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
- Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术。
// ajax三要素:请求url,携带的数据data,回调函数callback
$.post({
url:xxx/xxx,
data:{"":"","":""},
success:function(data){
}
})
五、拦截器
5.1、概念
SpringMVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter, 用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
5.2. 拦截器和过滤器的区别
5.2.1、过滤器
- servlet 规范中的一部分,在任何的 Javaweb 工程中都可以使用。
- 在中配置了 /*,可以对所有要访问的资源进行拦截。
5.2.2、拦截器
- 拦截器是 springMVC 框架自己的,只有使用了 springMVC 框架的工程才能使用。(最早在 struct 框架中就有)
- 拦截器只会拦截访问的控制器方法,如果访问的是 html/css/js/jsp/image 则不会进行拦截。
- 拦截器是 AOP 思想的具体应用。
5.3、拦截器配置和使用
<!--拦截器配置-->
<mvc:interceptors>
<mvc:interceptor>
<!--包括这个请求下的所有请求-->
<mvc:mapping path="/**"/>
<bean class="com.sywl.config.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
// 自定义类实现Interceptor接口,可以重写preHandle方法
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
// return true; 放行,执行下一个拦截器
// return false; 不放行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 处理前
return false;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 处理后,可以写拦截日志
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 清理
}
}
六、文件上传和下载
6.1、前端表单要求
为了能上传文件,必须将表单的 method 设置为 POST,并将 enctype 设置为 multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器。
enctype 属性说明:
- application/x-www=form-urlencoded: 默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。
- multipart/form-data: 这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
- text/plain: 除了把空格转换为”+” 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。
<form action="" enctype="multipart/form-data" method="post">
<input type="file" name-"file"/>
<input type="submit">
</form>
6.2、后端的要求
- 导入包
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.2</version>
</dependency>
- springMVC 文件上传配置
//spring-servet.xml配置
<!--文件上传配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--请求的编码格式,必须和pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1-->
<property name="defaultEncoding" value="utf-8"/>
<!--上传文件大小上限,单位是字节-->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>