JSON数据交互和RESTful支持
Posted shi_zi_183
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSON数据交互和RESTful支持相关的知识,希望对你有一定的参考价值。
JSON数据交互和RESTful支持
SpringMVC在数据绑定的过程中,需要对传递数据的格式和类型进行转换,它既可以转换String类型的数据,也你能够转换JSON等其他类型的数据。
JSON数据交互
JSON概述
JSON(javascript Object Notation,JS对象标记)是一种轻量级的数据交换格式。它是基于JavaScript的一个子集,使用了C、C++、C#、Java、JavaScript、Perl、Python等其他语言的约束,采用完全独立于编程语言的文本格式来存储和表示数据。这些特性使JSON成为理想的数据交互语言,它易于阅读和编写,同时也易于机器解析和生成。
与XML一样,JSON也是纯文本的数据格式。初学者可以使用JSON传输一个简单的String、Number、Boolean,也可以传输一个数组或者复杂的Object对象。
1、对象结构
对象结构以{
开始,以}
结束。中间部分由0个或多个以英文,
分隔的name/value对构成(注意name和value之间以英文:
分隔)。
{
key1:value1,
key2:value2,
...
}
其中key必须为String类型,value可以是String、Number、Object、Array等数据类型。
2、数组结构
数组结构以[
开始,以]
结束。中间部分由0个或多个以英文,
分隔的值的列表组成。
{
value1,
value2,
...
}
上述两种两种数据结构也可以分别组合构成更为复杂的数据结构。
JSON数据转换
为了实现浏览器与控制器类(Contrller)之间的数据交互,Spring提供了一个HttpMessageConverter<T>接口来完成此项目工作、该接口主要用于将请求信息中的数据转化为一个类型为T的对象,并将类型为T的对象绑定到请求方法的参数中,或者将对象转换为响应信息传递给浏览器显示。
Spring为HttpMessageConverter<T>接口提供了很多实现类,这些实现类可以对不同类型的数据进行信息转换。其中MappingJackson2HttpMessageConverter是Spring MVC默认处理JSON格式请求响应的实现类。该实现类利用Jackson开源包读写JSON数据,将Java对象转换为JSON对象和XML文档,同时也可以将JSON对象和XML对象转换为Java对象。
要使用MappingJackson2HttpMessageConverter对数据进行转换,就需要使用Jackson的开源包,开发时所需的开源包及其描述如下
1)jackson-annotations-2.8.8.jar:JSON转换注解包
2)jackson-core-2.8.8.jar:JSON转换核心包
3)jackson-databind-2.8.8.jar:JSON转换的数据绑定包。
https://mvnrepository.com/artifact/com.fasterxml.jackson.core
注解 | 说明 |
---|---|
@RequestBoby | 用于将请求体中的数据绑定到方法的形参中。该注解用在方法的形参上 |
@ResponseBody | 用于直接返回return对象。该注解用在方法上。 |
1)创建项目并导入相关JAR包。使用Eclise创建一个名为chapter14的Web项目,然后将SpringMVC相关JAR包、JSON转换包添加到项目的lib目录中,并发布到类路径下。
2)在web.xml中,对Spring MVC的前端控制器等信息进行配置。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>chapter11</display-name>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3)在src目录下,创建Spring MVC的核心配置文件springmvc-config.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: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.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/tx
http://www.springframework.org/schema/tx/spring-mvc.xsd">
<context:component-scan base-package="com.ex.controller"/>
<mvc:annotation-driven/>
<mvc:resources location="/js/" mapping="/js/**"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
不仅配置了组件扫描器和视图解析器,还配置了Spring MVC的注解驱动,和静态资源访问映射。其中<mvc:annotation-driven/>
配置会自动注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter两个Bean,并提供对读写XML和读写JSON等功能的支持。<mvc:resources location="/js/" mapping="/js/**"/>
元素用于配置静态资源的访问路径。由于在web.xml中配置的/
会将页面中引入的静态文件也进行拦截,而拦截后页面中将找不到这些静态资源文件,这样就会引起页面报错。而增加了静态资源的访问映射配置后,程序会自动地去配置路径下找静态地内容。
<mvc:resources location="/js/" mapping="/js/**"/>
中有两个重要属性location和mapping,关于这两个属性地说明
属性 | 说明 |
---|---|
location | 用于定位需要访问的本地静态资源文件路径,具体到某个文件夹 |
mapping | 匹配静态资源全路径,其中"/**"表示文件夹及其子文件夹下的某个具体文件。 |
4)在src目录下,创建一个com.ex.po包,并在包中创建一个User类,该类用于封装User类型的请求参数
package com.ex.po;
public class User {
private String username;
private Integer password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getPassword() {
return password;
}
public void setPassword(Integer password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
5)在WebContent目录下,创建页面文件index.jsp来测试JSON数据交互
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
function testJson(){
var username=$("#username").val();
var password=$("#password").val();
$.ajax({
url:"${pageContext.request.contextPath}/testJson",
type:"post",
data:Json.stringify({username:username,password:password}),
contentType:"application/json;charset=UTF-8",
dataType:"json",
success:function(data){
if(data!=null){
alert("您输入的用户名为:"+data.username+"密码为:"+data.password);
}
}
})
}
</script>
</head>
<body>
<form>
用户名:<input type="text" name="username" id="username"><br/>
密码:<input type="password" name="password" id="password"><br/>
<input type="button" value="测试" onclick="testJson()"/>
</form>
</body>
</html>
注:将jquery-1.11.3.min.js放入WebContent目录下js文件夹中。
6)在src目录下,创建一个com.ex.controller包,在该包下创建一个用于用户操作的控制器类UserController
package com.ex.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ex.po.User;
@Controller
public class UserController {
@RequestMapping("/testJson")
@ResponseBody
public User testJson(@RequestBody User user){
System.out.println(user);
return user;
}
}
@RequestBody 用于将前端请求体中的JSON格式数据绑定到形参user上
@ResponseBody 用于直接返回User对象(当返回POJO对象时,会默认转换成JSON格式数据进行响应)。
7)将chapter14项目发布到Tomcat服务器并启动,浏览器访问。
使用<bean>
标签方式的JSON转换器配置
在配置JSON转换器时,除了常用的mvc:annotation-driven
方法外,还可以使用<bean>
标签的方式进行显示的配置。
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
配置静态资源访问的方式
除了使用mvc:resources
元素可以实现对静态资源的访问外,还有另外两种静态资源访问的配置方法。
1)使用<mvc:defaule-servlet-handler>
标签
在springmvc-config.xml文件中,使用<mvc:defaule-servlet-handler>
标签
<mvc:default-servlet-handler/>
配置<mvc:defaule-servlet-handler>
后,会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler(即默认的Servlet请求处理器)。它会像一个检察员,对进入DispatcherServlet的URL进行筛选,如果发现是静态资源的请求,就将该请求转由Web服务器默认的Servlet处理,默认的Servlet就会对这些资源放行;如果不是静态资源的请求,才有DispatcherServlet继续处理。
注:一般Web服务器默认的Servlet名称是default,因此DefaultServletHttpRequestHandler可以找到它。如果使用的Web应用服务器默认的Servlet名称不是default,则需要通过default-servlet-name属性显示指定,具体方式
<mvc:default-servlet-handler default-servlet-name="Servlet 名称"/>
2)激活Tomcat默认的Servlet来处理静态文件访问
激活Tomcat默认的Servlet时,需要在web.xml中添加以下内容
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
上述代码中,配置了servlet-mapping来激活Tomcat默认的Servlet来处理静态文件,我们还可以根据需要继续追加servlet-mapping。此种方式和上一种方式本质来说是一样的,都是使用Web服务器默认的Servlet来处理静态资源文件的访问。其中servlet-name中的值也是由使用的服务器来确定的,不同服务器需要使用不同的名称。
1和3配置方式可以选择性的释放静态资源
2配置方式相对简单,只需一行代码,就可以释放所有静态资源
2和3配置方式会导致项目移植性较差,需要根据具体的Web服务器来更改Servlet名称。
3配置方式运行效率更高,因为服务器启动时已经加载了web.xml中的静态资源。
RESTful支持
Spring MVC除了支持JSON数据交换外,还支持RESTful风格的编程。
什么是RESTful
RESTful也称之为REST(Representational State Transfer),可以将他理解为一种软件架构风格或设计风格,而不是一个标准。
简单来说,RESTful风格就是把请求参数变成请求路径的一种风格,
http://.../queryItems?id=1
而采用RESTful风格
http://.../Items/1
从上述两个请求中可以看出,RESTful风格中的URL将请求参数id=1变成了请求路径的一部分,并且URL中的queryItems也变成了items(RESTful风格中的URL不存在动词形式的路径)。
RESTful请求中,使用put、delete、post和get方式分别对应添加、删除、修改、查询的操作。
案例
1)在控制器类UserController中,编写用户查询方法selectUser()
package com.ex.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ex.po.User;
@Controller
public class UserController {
@RequestMapping("/testJson")
@ResponseBody
public User testJson(@RequestBody User user){
System.out.println(user);
return user;
}
@RequestMapping(value="/user/{id}",method=RequestMethod.GET)
@ResponseBody
public User selectUser(@PathVariable("id") String id){
System.out.println("id="+id);
User user=new User();
if(id.equals("1234")){
user.setUsername("tom");
}
return user;
}
}
@RequestMapping(value="/user/{id}",method=RequestMethod.GET)
用于匹配请求路径(包括参数)和方法。其中value="/user/{id}“表示可以匹配以”/user/{id}“结尾的请求,id为请求中的动态参数;method=RequestMethod.GET表示只接受GET方式的请求。方法中的@PathVariable(“id”)用于接收并绑定请求参数,它可以将请求URL中的变量映射到方法的形参上,如果请求路径为”/user/{id}",即请求参数中的id和方法形参名称一样,则@PathVariable后面的(“id”)可以省略。
2)在WebContent目录下,编写页面文件restful.jsp,在页面中使用AJAX方式通过输入的用户编号来查询用户信息
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
function testJson(){
var id=$("#id").val();
$.ajax({
url:"${pageContext.request.contextPath}/user/"+id,
type:"GET",
dataType:"json",
success:function(data){
if(data!=null){
alert("您的用户名为:"+data.username);
}
}
})
}
</script>
</head>
<body>
<form>
编号:<input type="text" name="id" id="id">
<input type="button" value="测试" onclick="testJson()"/>
</form>
</body>
</html>
以上是关于JSON数据交互和RESTful支持的主要内容,如果未能解决你的问题,请参考以下文章
Springday05 SpringMVC访问静态资源操作请求域控制器方法返回值JSON数据交互RESTful风格文件上传异常处理拦截器
黄聪:AngularJS中的$resource使用与Restful资源交互(转)
用于 RESTFul JSON API 交互的推荐 Android HTTP 库是啥?