三、Json数据交互和Restful支持
1、什么是JSON?
- JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,目前使用特别广泛。
- 采用完全独立于编程语言的文本格式来存储和表示数据。
- 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。看看他的要求和语法格式:
- 对象表示为键值对,数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
==注意:如果使用JSON存储单个数据(如”abc”),一定要使用数组的形式,不要使用 Object形式,因为 Object形式必须是”名称:值”的形式.==
JSON 键值对是用来保存 JavaScript 对象的一种方式,和 JavaScript 对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号 “” 包裹,使用冒号 : 分隔,然后紧接着值:
1 | {"name": "QinJiang"} |
很多人搞不清楚 JSON 和 JavaScript 对象的关系,甚至连谁是谁都不清楚。其实,可以这么理解:
JSON 是 JavaScript 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
1 | var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的 |
JSON 和 JavaScript 对象互转
要实现从JSON字符串转换为JavaScript 对象,使用 JSON.parse() 方法:
1 | var obj = JSON.parse('{"a": "Hello", "b": "World"}'); |
要实现从JavaScript 对象转换为JSON字符串,使用 JSON.stringify() 方法:
1 | var json = JSON.stringify({a: 'Hello', b: 'World'}); |
2、Spring的json数据交互
Spring提供了一个 HttpMessage Converter<T>
接口来实现浏览器与控制器类( Controller)之间的数据交互.
MappingJackson2HttpMessageConverter
:SpringMVC默认处理JSON格式请求响应的实现类。
可以将Java对象转换为JSON对象和XML对象
也可以将JSON对象和XML对象转换为Java对象

3、注解开发

只需要配置<mvc:annotation-driven />
使用@RequestBody和@ResponseBody
使用实例:
1 | "/testJson") ( |
外部JSON—>@RequestBody—>转化为user —>return user—>@ResponseBody—>转化为JSON
4、显示开发(很少使用)
5、静态资源处理
三种方法:
- 配置
<mvc:resources location="" mapping="" />
- (推荐)使用
<mvc:default-servlet-handler/>
- (不推荐)配置web.XML使用Tomcat(或者其他web容器)实现


1 | <mvc:resources location="/,classpath:/META-INF/publicResources/" mapping="/resources/**"/> |
以上配置将Web根路径”/“及类路径下 /META-INF/publicResources/ 的目录映射为/resources路径。假设Web根路径下拥有images、js这两个资源目录,在images下面有bg.gif图片,在js下面有test.js文件,则可以通过 /resources/images/bg.gif 和 /resources/js/test.js 访问这二个静态资源。
假设WebRoot还拥有images/bg1.gif 及 js/test1.js,则也可以在网页中通过 /resources/images/bg1.gif 及 /resources/js/test1.js 进行引用。
6、RESTful支持
==简单来说,RESTful风格就是把请求参数变成请求路径的一种风格。==
Web应用程序最重要的REST原则是,客户端和服务器之间的交互在请求之间是无状态的
从客户端到服务器的每个请求都必须包含理解请求所必需的信息.
例如:购买商品,你给出商品信息,服务器给你小票,之前和之后不会再保留任何相关信息。

动词也变成了名词
==主要是使用@PathVariable
==
例子:
1 | "/user/{id}") ( |
四、拦截器和文件上传下载
1、拦截器
(1)什么是拦截器?
Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。
例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
拦截器与过滤器的比较
相似
- 都有优先处理请求的权利,都可以决定是否将请求转移到请求的实际处理的控制器处。
- 都可以对请求或者会话当中的数据进行加工。
不同
- 拦截器可以做前置处理也可以做后置处理,还可以进行完成处理,控制的 更加细致,而过滤器只负责前面的过滤行为而已。
- 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的
- 过滤器优先执行,还是拦截器优先呢?———-过滤器优先。
- 过滤器是servlet规范里面的组件。任何java web工程都可以使用
- 拦截器都是框架自己而外添加的组件。
==三种拦截器的执行时间段:==
preHandle
:在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当其返回值为false时,会中断后续的所有操作。
postHandle
:该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。
afterCompletion
:该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。
(2)如何实现?
1、通常拦截器类可以通过两种方式来定义。
- 通过实现
HandlerInterceptor
接口,或继承HandlerInterceptor
接口的实现类(如HandlerInterceptorAdapter)来定义。 - 通过实现
WebRequestInterceptor
接口,或继承WebRequestInterceptor
接口的实现类来定义。
2、在Spring MVC的配置文件中进行配置。
1 | <mvc:interceptors> |
注意:<mvc:interceptor>
中的子元素必须按照上述代码的配置顺序进行编写,否则文件会报错。
(3)单个和多个拦截器执行的流程


==多个:pre顺序执行;post和after反序执行==
==注意:顺序是按照XML中配置的顺序。正序就是XML中的顺序,逆序就是XML中的反顺序==
例如:
1 | <!-- 配置拦截器 --> |
(4)应用:常用来登录验证
若访问本站点下除了登录页面的其他页面则进行拦截判断是否登录。登录则继续访问否则转发到登录页面。
1 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) |
1 | <!-- 配置拦截器 --> |
2、文件上传和下载
(1)上传
==1、前端配置==
多数文件上传都是通过表单形式提交给后台服务器的,因此,要实现文件上传功能,就需要提供一个文件上传的表单,而该表单必须满足以下3个条件
- form表单的method属性设置为post;
- form表单的enctype属性设置为multipart/form-data;
- 提供
<input type="file" name="filename" />
的文件上传输入框。- multiple属性是HTML5中新属性,可实现多文件上传。
1 | <form action="uploadUrl" method="post" enctype="multipart/form-data"> |
- application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。
- multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
- text/plain:除了把空格转换为 “+” 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。
==2、导入jar包==
1 | <dependency> |
==3、MultipartResolver配置==
当form表单的enctype属性为multipart/form-data时,浏览器就会采用二进制流来处理表单数据,服务器端就会对文件上传的请求进行解析处理。Spring MVC通过MultipartResolver实现文件上传功能。MultipartResolver是一个接口对象,需要通过它的实现类CommonsMultipartResolver
来完成文件上传工作。
1 | <bean id="multipartResolver" |
maxUploadSize:上传文件最大长度(以字节为单位);
maxInMemorySize:缓存中的最大尺寸;
defaultEncoding:默认编码格式;
resolveLazily:推迟文件解析,以便在Controller中捕获文件大小异常。
注意:因为MultipartResolver接口的实现类CommonsMultipartResolver内部 是引用multipartResolver字符串获取该实现类对象并完成文件解析的,所以在配置CommonsMultipartResolver时
必须指定该Bean的id为multipartResolver
。
==4、使用MultipartFile接受前段传来的数据流,使用其相应方法对数据进行操作==`
1 | "/file") ( |
(2)下载
==1、前端设置==
在客户端页面使用一个文件下载的超链接,该链接的href属性要指定后台文件下载的方法以及文件名(需要先在文件下载目录中添加了一个名称为“1.jpg”的文件)。
前端JSPdownload.jsp
:
<a href="${pageContext.request.contextPath }/download?filename=<%=URLEncoder.encode("壁纸.jpg", "UTF-8")%>">中文名称文件下载 </a>
==2、后端使用ResponseEntity处理==
在后台使用Spring MVC提供的ResponseEntity类型对象完成文件下载,使用它可以很方便的定义返回的HttpHeaders对象和HttpStatus对象,通过对这两个对象的设置,即可完成下载文件时所需的配置信息。
文件下载中的ResponseEntity对象有些类似前面章节中的@ResponseBody注解,它用于直接返回结果对象。
响应头信息中的MediaType代表的是Interner Media Type(即互联网媒体类型),也叫做MIME类型,MediaType.APPLICATION_OCTET_STREAM的值为application/octet-stream,即表示以二进制流的形式下载数据;
HttpStatus类型代表的是Http协议中的状态,示例中的HttpStatus.OK表示200,即服务器已成功处理了请求。
1 | "/down") ( |
==3、中文名文件乱码问题解决==
为了解决浏览器中文件下载时中文名称的乱码问题,可以在前端页面发送请求前先对中文名进行统一编码,然后在后台控制器类中对文件名称进行相应的转码。


1 | @RequestMapping("/download") |