`
kingxss
  • 浏览: 972009 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring RESTful服务接收和返回JSON最佳实践

阅读更多

个人学习参考所用,勿喷!  

 

返回JSON

1) 用Maven构建web项目:

构建过程参考limingnihao的blog(写得相当的详细!!!):使用Eclipse构建Maven的SpringMVC项目

注解@ResponseBody可以将结果(一个包含字符串和JavaBean的Map),转换成JSON。由于Spring是采用对JSON进行了封装的jackson来生成JSON和返回给客户端,所以这里需要添加jackson的相关包。项目的pom.xml配置如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.watson</groupId>
	<artifactId>rest-spring</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>rest-spring Maven Webapp</name>
	<url>http://maven.apache.org</url>
	
	<dependencies>
		<!-- 省略其他配置,具体可以参考附件-->
		......
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
			<version>1.4.2</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
			<version>1.4.2</version>
		</dependency>
	</dependencies>
</project>
  

2) 在web.xml配置Spring的请求处理的Servlet,具体设置:

<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<display-name>Spring-Rest</display-name>
	<servlet>
		<servlet-name>rest</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/rest-servlet.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>rest</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

 

3) 在rest-servlet.xml中配置如下:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" 
	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-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
 
	<context:component-scan base-package="com.mkyong.common.controller" />
	<mvc:annotation-driven />

</beans>

 

   为了解决乱码问题,需要添加如下配置,并且这里可以显示的添加MappingJacksonHttpMessageConverter这个转换器。

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
	<property name="messageConverters">
		<list>
			<bean class="org.springframework.http.converter.StringHttpMessageConverter">
				<property name="supportedMediaTypes">
					<list>
						<value>text/plain;charset=UTF-8</value>
					</list>
				</property>
			</bean>
			<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
		</list>
	</property>
</bean>
 

 

4) 编写自己的服务组件类,使用MVC的annotation风格,使用 @ResponseBody处理返回值。具体代码如下:

@RequestMapping("/jsonfeed")
public @ResponseBody Object getJSON(Model model) {
	List<TournamentContent> tournamentList = new ArrayList<TournamentContent>();
	tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "World Cup", "www.fifa.com/worldcup/"));
	tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "U-20 World Cup", "www.fifa.com/u20worldcup/"));
	tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "U-17 World Cup", "www.fifa.com/u17worldcup/"));
	tournamentList.add(TournamentContent.generateContent("中超", new Date(), "中超", "www.fifa.com/confederationscup/"));
	model.addAttribute("items", tournamentList);
	model.addAttribute("status", 0);
	
	return model;
}

 

 5)将运行项目,在浏览器中输入http://[host]:[port]/[appname]/jsonfeed.json,例如楼主的实例中输入如下:http://localhost:7070/rest-spring/jsonfeed/,得到结果为:

{"status":0,"items":[{"name":"World Cup","id":8,"link":"www.fifa.com/worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"U-20 World Cup","id":9,"link":"www.fifa.com/u20worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"U-17 World Cup","id":10,"link":"www.fifa.com/u17worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"Confederations Cup","id":11,"link":"www.fifa.com/confederationscup/","author":"FIFA","publicationDate":1334559460940}]}

 

这里我们也可以利用Spring3MVC中对试图和内容协商的方法来处理返回JSON的情况,下面步骤接上面第2步:

3) 在rest-servlet.xml中对相关进行具体的设置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context-3.0.xsd 
		http://www.springframework.org/schema/mvc 
		http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<!-- 自动搜索@Controller标注的类,包括其下面的子包 -->
	<context:component-scan base-package="com.watson.rest" />

	<!-- 根据客户端的不同的请求决定不同的view进行响应, 如 /blog/1.json /blog/1.xml -->
	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
		<!-- 设置为true以忽略对Accept Header的支持 -->
		<property name="ignoreAcceptHeader" value="true" />
		
		<!-- 在没有扩展名时即: "/blog/1" 时的默认展现形式 -->
		<property name="defaultContentType" value="text/html" />

		<!-- 扩展名至mimeType的映射,即 /blog.json => application/json -->
		<property name="mediaTypes">
			<map>
				<entry key="html" value="text/html" />
				<entry key="pdf" value="application/pdf" />
				<entry key="xsl" value="application/vnd.ms-excel" />
				<entry key="xml" value="application/xml" />
				<entry key="json" value="application/json" />
			</map>
		</property>
	
		<!-- 用于开启 /blog/123?format=json 的支持 -->
		<property name="favorParameter" value="false" />
		<property name="viewResolvers">
			<list>
				<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
				<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
					<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
					<property name="prefix" value="/pages" />
					<property name="suffix" value=".jsp"></property>
				</bean>
			</list>
		</property>
		<property name="defaultViews">
			<list>
				<!-- for application/json -->
				<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
				<!-- for application/xml -->
				<!-- 
				<bean class="org.springframework.web.servlet.view.xml.MarshallingView"> 
					<property name="marshaller"> 
						<bean class="org.springframework.oxm.xstream.XStreamMarshaller"/> 
					</property> 
				</bean> 
				-->
			</list>
		</property>
	</bean>
</beans>

 4)编写自己的服务组件类,使用MVC的annotation风格,这里可以不再使用@ResponseBody断言。具体代码如下:
//FINAL 
package com.watson.rest.json;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.watson.rest.feeds.TournamentContent;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Controller
public class FeedController {
    @RequestMapping("/jsonfeed")
    public String getJSON(Model model) {
        List<TournamentContent> tournamentList = new ArrayList<TournamentContent>();
        tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "World Cup", "www.fifa.com/worldcup/"));
        tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "U-20 World Cup", "www.fifa.com/u20worldcup/"));
        tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "U-17 World Cup", "www.fifa.com/u17worldcup/"));
        tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "Confederations Cup", "www.fifa.com/confederationscup/"));
        model.addAttribute("items", tournamentList);
        model.addAttribute("status", 0);
        return "jsontournamenttemplate";
    }
}

这里的TournamentContent是自定义的POJO类:
public class TournamentContent {
    private static int idCounter = 0;
    private String author;
    private Date publicationDate;
    private String name;
    private String link;
    private int id;

    public static TournamentContent generateContent(String author, Date date, String name, String link) {
        TournamentContent content = new TournamentContent();
        content.author = author;
        content.publicationDate = date;
        content.name = name;
        content.link = link;
        content.id = idCounter++;

        return content;
    }
	
	//省略getter、setter
}

5)将运行项目,在浏览器中输入http://[host]:[port]/[appname]/jsonfeed.json,例如楼主的实例中输入如下:http://localhost:7070/rest-spring/jsonfeed.json,得到结果为:
{"status":0,"items":[{"name":"World Cup","id":8,"link":"www.fifa.com/worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"U-20 World Cup","id":9,"link":"www.fifa.com/u20worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"U-17 World Cup","id":10,"link":"www.fifa.com/u17worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"Confederations Cup","id":11,"link":"www.fifa.com/confederationscup/","author":"FIFA","publicationDate":1334559460940}]}

至此,Spring RESTful服务返回JSON的实践基本完成(因为这里对EXCEPTION的处理还够)。个人认为第一种方式更加适合一般的使用,特别是显示的添加MappingJacksonHttpMessageConverter这个转换器和对乱码的处理。

接收JSON
使用 @RequestBody 注解前台只需要向 Controller 提交一段符合格式的 JSON,Spring 会自动将其拼装成 bean。
1)在上面的项目中使用第一种方式处理返回JSON的基础上,增加如下方法:
@RequestMapping(value="/add",method=RequestMethod.POST)
@ResponseBody
public Object addUser(@RequestBody User user)
{
	System.out.println(user.getName() + " " + user.getAge());
	return new HashMap<String, String>().put("success", "true");
}
 这里的POJO如下:
public class User {
	private String name;
	private String age;

	//getter setter
}
 
2)而在前台,我们可以用 jQuery 来处理 JSON。从这里,我得到了一个 jQuery 的插件,可以将一个表单的数据返回成JSON对象:
$.fn.serializeObject = function(){
    var o = {};
    var a = this.serializeArray();
    $.each(a, function(){
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        }
        else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};
 
   以下是使用 jQuery 接收、发送 JSON 的代码:
$(document).ready(function(){
    jQuery.ajax({
        type: 'GET',
        contentType: 'application/json',
        url: 'jsonfeed.do',
        dataType: 'json',
        success: function(data){
            if (data && data.status == "0") {
                $.each(data.data, function(i, item){
                    $('#info').append("姓名:" + item.name +",年龄:" +item.age);
                });
            }
        },
        error: function(){
            alert("error")
        }
    });
    $("#submit").click(function(){
        var jsonuserinfo = $.toJSON($('#form').serializeObject());
        jQuery.ajax({
            type: 'POST',
            contentType: 'application/json',
            url: 'add.do',
            data: jsonuserinfo,
            dataType: 'json',
            success: function(data){
                alert("新增成功!");
            },
            error: function(){
                alert("error")
            }
        });
    });
});
 
但是似乎用Spring这套东西真是个麻烦的事情,相对Jersey对RESTful的实现来看,确实有很多不简洁的地方。

 

 

参考:

官方文档:http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch18.html

badqiu的BOLG: 《spring REST中的内容协商(同一资源,多种展现:xml,json,html)》

liuweifeng的BOLGhttp://blog.liuweifeng.net/archives/407

Gary Mark等的书籍:《Spring Recipes》2ed

 

分享到:
评论
6 楼 戢_时光 2015-07-21  
5 楼 Partys 2014-12-12  
wlkfec 写道
有一个小问题,就是配置默认的视图MappingJacksonJsonView的时候,报错:Could not instantiate bean class [org.springframework.web.servlet.view.json.MappingJacksonJsonView]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/codehaus/jackson/Versioned  可是查看文档,这个类本来就是一个无参数的构造方法,这是什么情况 

jackson-all-1.8.10.jar 缺少这个包
4 楼 kingxss 2014-02-11  
wlkfec 写道
有一个小问题,就是配置默认的视图MappingJacksonJsonView的时候,报错:Could not instantiate bean class [org.springframework.web.servlet.view.json.MappingJacksonJsonView]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/codehaus/jackson/Versioned  可是查看文档,这个类本来就是一个无参数的构造方法,这是什么情况 

你好,这是个没有找到类的BUG,很常见。原因是没有加入需要的jar,或者jar的版本不对。
3 楼 wlkfec 2014-02-09  
有一个小问题,就是配置默认的视图MappingJacksonJsonView的时候,报错:Could not instantiate bean class [org.springframework.web.servlet.view.json.MappingJacksonJsonView]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/codehaus/jackson/Versioned  可是查看文档,这个类本来就是一个无参数的构造方法,这是什么情况 
2 楼 z_04915231 2013-12-10  
1 楼 lc7183627 2013-10-11  
我怎么缺一些类?

相关推荐

    Spring restful Json

    在IT行业中,Spring RESTful JSON 是一种常见的技术组合,它结合了Spring框架的RESTful服务设计和JSON数据格式,用于构建高效、灵活的Web服务。本文将深入探讨Spring RESTful JSON的相关知识点,包括其概念、核心...

    spring 发布restful 服务

    4. **数据转换器**:Spring MVC默认支持JSON和XML的自动转换,通过Jackson库处理JSON,JAXB处理XML。如果需要自定义序列化和反序列化,可以配置自定义的MessageConverter。 5. **安全控制**:对于RESTful服务,通常...

    spring3 mvc restful freemarker jquery json

    JSON由于其简洁的结构和与JavaScript的天然兼容性,成为了Web服务中常见的数据交换格式。在Spring3 MVC中,可以使用Jackson或Gson等库将Java对象转换为JSON字符串,然后通过Ajax请求传递给客户端,客户端再使用...

    spring mvc(整合了json)

    Spring MVC 是一个基于 Java 的轻量级 Web 开发框架,它是 Spring 框架的一部分,主要用于构建 MVC(Model...在大型项目中,结合 RESTful API 设计原则,Spring MVC 与 JSON 的结合更是成为了现代 Web 开发的标准实践。

    Spring mvc实现Restful返回json格式数据实例详解

    综上所述,Spring MVC通过上述技术实现RESTful服务返回JSON数据的流程如下: 1. 开发者在Spring MVC的控制器中使用@RequestMapping和@RequestBody等注解来定义服务。 2. 当客户端发送RESTful风格的请求时,控制器中...

    spring4 restful web

    在“Spring4RestWS”这个压缩包中,可能包含了Spring 4搭建RESTful Web服务的相关示例代码、配置文件和文档,可以帮助学习者快速理解和实践上述知识点。通过实际操作和理解这些示例,可以深入掌握Spring 4构建...

    spring4.0的restful webservice构建和发布

    在本项目中,我们主要探讨的是如何利用Spring框架的4.0版本来构建RESTful Web服务并进行发布。...下面将详细阐述涉及的三个核心知识点:...通过学习和实践这些内容,开发者能够更高效地构建可扩展、易于维护的后端服务。

    java jersey spring 集成 开发restful API 服务

    本资源主要介绍如何将Java的Jersey框架与Spring框架集成,以创建高效的RESTful服务,并返回JSON格式的数据。 首先,让我们了解Java Jersey。Jersey是Java官方的JAX-RS(Java API for RESTful Web Services)实现,...

    Spring+restful.zip

    这通常包括Spring MVC的核心库,如spring-webmvc,以及与RESTful相关的库,例如Jackson或Gson用于JSON序列化和反序列化,还有可能包含Spring Boot Starter Web,简化了Spring MVC和RESTful的集成。 在标签中,"java...

    使用spring构建RESTful的Web服务

    构建RESTful Web服务时,选择合适的技术栈(如Spring框架)和最佳实践(如使用Maven/Gradle进行构建管理)非常重要。同时还需要关注诸如性能优化、安全性等方面的问题,确保所构建的服务既高效又安全。

    WMS源码 包含VUE前端源码、后端java spring restful api 源码

    其次,后端部分采用的是Java Spring框架,这是一个功能强大的企业级应用开发框架,其Spring Boot简化了初始化和配置过程,而Spring RESTful API则提供了创建RESTful服务的能力。RESTful API是目前广泛使用的Web服务...

    Jersey+Spring集成,后台接受或返回Json数据

    在Java世界中,Jersey和Spring是两个非常重要的框架,它们分别用于构建RESTful Web服务和企业级应用程序。本文将详细介绍如何将Jersey与Spring进行集成,以便在后台处理JSON数据。我们将探讨以下知识点: 1. **...

    json在spring中的应用

    5. **Spring Data REST**:Spring Data REST是Spring的一个扩展,它能自动将Spring Data JPA或MongoDB等持久层操作暴露为RESTful服务,返回JSON格式的数据。这大大简化了构建Web服务的工作。 6. **类型安全的模型...

    json接口的spring实例(含httpclient、加密解密)

    Spring框架提供了丰富的支持来创建RESTful API,这些API可以返回或接收JSON格式的数据。在`testJsonServer`项目中,你需要配置Spring MVC,创建一个Controller类,定义处理HTTP请求的方法,这些方法通常会使用`@...

    CXF Restful服务简单例子

    这些文件可以帮助我们了解和实践CXF RESTful服务的完整流程,从编写服务类到部署运行,以及可能的测试脚本。\n\n总的来说,Apache CXF框架简化了RESTful服务的开发,使得我们可以快速构建高效、可扩展的Web服务。...

    spring3.0支持restful的demo

    在本示例中,我们关注的是Spring框架的3.0版本如何支持RESTful风格的Web服务。REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,它基于HTTP协议,强调简洁、无状态和可缓存性。...

    Spring mvc RESTful demo

    **Spring MVC RESTful 示例** Spring MVC 是 Spring 框架的一部分,它主要用于构建 Web 应用程序,尤其是处理 HTTP 请求和响应。...总之,Spring MVC 提供了强大的工具和库来构建高质量、高效的 RESTful Web 服务。

    springmvc之restful风格CRUD

    在IT行业中,Spring MVC是一个广泛使用的Java Web框架...理解并实践这些概念,对于提升Spring MVC的使用技能以及构建高质量的Web服务至关重要。记得在实际开发中根据项目需求进行调整和优化,保持代码简洁和可维护性。

    spring-json项目

    【Spring-JSON项目】是一个基于Eclipse开发的项目,它主要关注的是如何在Spring框架中有效地集成和使用JSON...通过研究和实践这个项目,开发者可以掌握如何构建RESTful API,处理JSON请求,以及优化Web服务性能。

Global site tag (gtag.js) - Google Analytics