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支持的主要内容,如果未能解决你的问题,请参考以下文章

SpringMVC的JSON数据交互和RESTful支持

Springday05 SpringMVC访问静态资源操作请求域控制器方法返回值JSON数据交互RESTful风格文件上传异常处理拦截器

黄聪:AngularJS中的$resource使用与Restful资源交互(转)

用于 RESTFul JSON API 交互的推荐 Android HTTP 库是啥?

SpringBoot实现Restful service前后端数据交互篇

restful