Spring Restful Web服务示例 - 使用JSON/Jackson和客户端程序

Spring是最广泛使用的Java EE框架之一。我们之前已经看到了如何使用Spring MVC来创建基于Java的Web应用程序。今天我们将学习使用Spring MVC 创建Spring Restful Web Services,然后使用Rest客户端进行测试。最后,我们还将研究如何使用Spring RestTemplate API调用Spring Restful Web服务。

目录[ 隐藏 ]

  • 1 Spring REST

    • 1.1 Spring REST配置XML文件
    • 1.2 Spring REST模型类
    • 1.3 Spring Restful Web服务端点
    • 1.4 Spring Restful Web服务控制器类
    • 1.5 Spring Rest客户端程序

Spring REST

我们将使用Spring最新版本4.0.0.RELEASE并利用Spring Jackson JSON集成在其余的调用响应中发送JSON响应。本教程是在Spring STS IDE中开发的,用于轻松创建Spring MVC框架代码,然后扩展为实现Restful架构。

在STS中创建一个新的Spring MVC项目,我们的最终项目将如下图所示。我们将逐一研究每个组件。

Spring REST配置XML文件

我们的pom.xml文件如下所示。


<?xml version="1.0" encoding="UTF-8"?>
<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.journaldev</groupId><artifactId>SpringRestExample</artifactId><name>SpringRestExample</name><packaging>war</packaging><version>1.0.0-BUILD-SNAPSHOT</version><properties><java-version>1.6</java-version><org.springframework-version>4.0.0.RELEASE</org.springframework-version><org.aspectj-version>1.7.4</org.aspectj-version><org.slf4j-version>1.7.5</org.slf4j-version><jackson.databind-version>2.2.3</jackson.databind-version></properties><dependencies><!-- Jackson --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.databind-version}</version></dependency><!-- Spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${org.springframework-version}</version><exclusions><!-- Exclude Commons Logging in favor of SLF4j --><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${org.springframework-version}</version></dependency><!-- AspectJ --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>${org.aspectj-version}</version></dependency><!-- Logging --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${org.slf4j-version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>${org.slf4j-version}</version><scope>runtime</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${org.slf4j-version}</version><scope>runtime</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.15</version><exclusions><exclusion><groupId>javax.mail</groupId><artifactId>mail</artifactId></exclusion><exclusion><groupId>javax.jms</groupId><artifactId>jms</artifactId></exclusion><exclusion><groupId>com.sun.jdmk</groupId><artifactId>jmxtools</artifactId></exclusion><exclusion><groupId>com.sun.jmx</groupId><artifactId>jmxri</artifactId></exclusion></exclusions><scope>runtime</scope></dependency><!-- @Inject --><dependency><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version></dependency><!-- Servlet --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!-- Test --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.7</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><artifactId>maven-eclipse-plugin</artifactId><version>2.9</version><configuration><additionalProjectnatures><projectnature>org.springframework.ide.eclipse.core.springnature</projectnature></additionalProjectnatures><additionalBuildcommands><buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand></additionalBuildcommands><downloadSources>true</downloadSources><downloadJavadocs>true</downloadJavadocs></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.5.1</version><configuration><source>1.6</source><target>1.6</target><compilerArgument>-Xlint:all</compilerArgument><showWarnings>true</showWarnings><showDeprecation>true</showDeprecation></configuration></plugin><plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>1.2.1</version><configuration><mainClass>org.test.int1.Main</mainClass></configuration></plugin></plugins></build>
</project>

STS工具为我们生成pom.xml文件。但是,我已经将Spring Framework,AspectJ,SLF4J和Jackson版本更新到了今天的最新版本。大多数部分是常见的并且是自动生成的,需要注意的重要一点是我在依赖项中添加了Jackson JSON库,因为我们将使用它将对象转换为JSON,反之亦然。


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><!-- The definition of the Root Spring Container shared by all Servlets and Filters --><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/root-context.xml</param-value></context-param><!-- Creates the Spring Container shared by all Servlets and Filters --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- Processes application requests --><servlet><servlet-name>appServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>appServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>

此文件是自动生成的,我没有更改任何内容。但是,如果要更改上下文配置文件及其位置,可以在web.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"><!-- Root Context: defines shared resources visible to all other web components --></beans>

这个文件包含所有Web组件都可见的共享资源,我们将开发一个简单的休息服务,这就是我没有在这里做任何改变的原因。


<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:beans="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --><!-- Enables the Spring MVC @Controller programming model --><annotation-driven /><!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --><resources mapping="/resources/**" location="/resources/" /><!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --><beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><beans:property name="prefix" value="/WEB-INF/views/" /><beans:property name="suffix" value=".jsp" /></beans:bean><!-- Configure to plugin JSON as request and response in method handler --><beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><beans:property name="messageConverters"><beans:list><beans:ref bean="jsonMessageConverter"/></beans:list></beans:property></beans:bean><!-- Configure bean to convert JSON to POJO and vice versa --><beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></beans:bean>  <context:component-scan base-package="com.journaldev.spring.controller" /></beans:beans>

大部分零件是自动生成的,包含锅炉板配置。需要注意的重要但点是注解驱动的元素,以支持基于注释配置和封堵MappingJackson2HttpMessageConverterRequestMappingHandlerAdaptermessageConverters让杰克逊API踢和JSON转换为Java Bean和反之亦然。通过这种配置,我们将在请求体中使用JSON,我们将在响应中接收JSON数据。

Spring REST模型类

让我们编写一个简单的POJO类,它将作为Restful Web服务方法的输入和输出。


package com.journaldev.spring.model;import java.io.Serializable;
import java.util.Date;import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;public class Employee implements Serializable{private static final long serialVersionUID = -7788619177798333712L;private int id;private String name;private Date createdDate;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@JsonSerialize(using=DateSerializer.class)public Date getCreatedDate() {return createdDate;}public void setCreatedDate(Date createdDate) {this.createdDate = createdDate;}}

唯一需要注意的重点是使用@JsonSerialize注释将DateSerializer类用于从Java类型到JSON格式的Date转换,反之亦然。

Spring Restful Web服务端点

我们将拥有以下其他Web服务端点。

SL. NO URI HTTP METHOD DETAILS
1 /rest/emp/dummy GET Health Check service, to insert a dummy data in the Employees data storage
2 /rest/emp/{id} GET To get the Employee object based on the id
3 /rest/emps GET To get the list of all the Employees in the data store
4 /rest/emp/create POST To create the Employee object and store it
5 /rest/emp/delete/{id} PUT To delete the Employee object from the data storage based on the id

我们有一个类将所有这些URI定义为String常量。


package com.journaldev.spring.controller;public class EmpRestURIConstants {public static final String DUMMY_EMP = "/rest/emp/dummy";public static final String GET_EMP = "/rest/emp/{id}";public static final String GET_ALL_EMP = "/rest/emps";public static final String CREATE_EMP = "/rest/emp/create";public static final String DELETE_EMP = "/rest/emp/delete/{id}";
}

Spring Restful Web服务控制器类

我们的EmployeeController类将发布上面提到的所有Web服务端点。让我们看一下类的代码,然后我们将详细了解每个方法。


package com.journaldev.spring.controller;import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.journaldev.spring.model.Employee;/*** Handles requests for the Employee service.*/
@Controller
public class EmployeeController {private static final Logger logger = LoggerFactory.getLogger(EmployeeController.class);//Map to store employees, ideally we should use databaseMap<Integer, Employee> empData = new HashMap<Integer, Employee>();@RequestMapping(value = EmpRestURIConstants.DUMMY_EMP, method = RequestMethod.GET)public @ResponseBody Employee getDummyEmployee() {logger.info("Start getDummyEmployee");Employee emp = new Employee();emp.setId(9999);emp.setName("Dummy");emp.setCreatedDate(new Date());empData.put(9999, emp);return emp;}@RequestMapping(value = EmpRestURIConstants.GET_EMP, method = RequestMethod.GET)public @ResponseBody Employee getEmployee(@PathVariable("id") int empId) {logger.info("Start getEmployee. ID="+empId);return empData.get(empId);}@RequestMapping(value = EmpRestURIConstants.GET_ALL_EMP, method = RequestMethod.GET)public @ResponseBody List<Employee> getAllEmployees() {logger.info("Start getAllEmployees.");List<Employee> emps = new ArrayList<Employee>();Set<Integer> empIdKeys = empData.keySet();for(Integer i : empIdKeys){emps.add(empData.get(i));}return emps;}@RequestMapping(value = EmpRestURIConstants.CREATE_EMP, method = RequestMethod.POST)public @ResponseBody Employee createEmployee(@RequestBody Employee emp) {logger.info("Start createEmployee.");emp.setCreatedDate(new Date());empData.put(emp.getId(), emp);return emp;}@RequestMapping(value = EmpRestURIConstants.DELETE_EMP, method = RequestMethod.PUT)public @ResponseBody Employee deleteEmployee(@PathVariable("id") int empId) {logger.info("Start deleteEmployee.");Employee emp = empData.get(empId);empData.remove(empId);return emp;}}

为简单起见,我将所有员工的数据存储在HashMap empData中。@RequestMapping注释用于将请求URI映射到处理程序方法。我们还可以指定客户端应用程序应该使用的HTTP方法来调用rest方法。

@ResponseBody注释用于映射响应主体中的响应对象。一旦处理程序方法返回响应对象,MappingJackson2HttpMessageConverter就会启动并将其转换为JSON响应。

@PathVariable注释是从其余URI中提取数据并将其映射到方法参数的简单方法。

@RequestBody注释用于将请求主体JSON数据映射到Employee对象,同样这是由MappingJackson2HttpMessageConverter映射完成的。

其余代码简单且易于理解,我们的应用程序已准备好进行部署和测试。只需导出为WAR文件并将其复制到servlet容器Web应用程序目录中。如果您在STS中配置了服务器,则只需在服务器上运行它即可部署它。

我正在使用WizTools RestClient来调用其余的调用,但您也可以使用Chrome扩展名Postman。

下面的屏幕截图显示了我们的应用程序及其输出所公开的其余API的不同调用。

健康检查 - 获取虚拟员工休息呼叫

创建员工POST休息调用:确保请求Content-Type设置为“application / json”,否则您将获得HTTP错误代码415。

获得员工休息呼叫

删除员工休息呼叫

让所有员工休息

Spring Rest客户计划

休息客户端可以测试我们的休息Web服务,但大多数时候,我们需要通过我们的程序调用休息服务。我们可以使用Spring RestTemplate轻松调用这些方法。下面是一个使用RestTemplate API调用我们的应用程序休息方法的简单程序。


package com.journaldev.spring;import java.util.LinkedHashMap;
import java.util.List;import org.springframework.web.client.RestTemplate;import com.journaldev.spring.controller.EmpRestURIConstants;
import com.journaldev.spring.model.Employee;public class TestSpringRestExample {public static final String SERVER_URI = "http://localhost:9090/SpringRestExample";public static void main(String args[]){testGetDummyEmployee();System.out.println("*****");testCreateEmployee();System.out.println("*****");testGetEmployee();System.out.println("*****");testGetAllEmployee();}private static void testGetAllEmployee() {RestTemplate restTemplate = new RestTemplate();//we can't get List<Employee> because JSON convertor doesn't know the type of//object in the list and hence convert it to default JSON object type LinkedHashMapList<LinkedHashMap> emps = restTemplate.getForObject(SERVER_URI+EmpRestURIConstants.GET_ALL_EMP, List.class);System.out.println(emps.size());for(LinkedHashMap map : emps){System.out.println("ID="+map.get("id")+",Name="+map.get("name")+",CreatedDate="+map.get("createdDate"));;}}private static void testCreateEmployee() {RestTemplate restTemplate = new RestTemplate();Employee emp = new Employee();emp.setId(1);emp.setName("Pankaj Kumar");Employee response = restTemplate.postForObject(SERVER_URI+EmpRestURIConstants.CREATE_EMP, emp, Employee.class);printEmpData(response);}private static void testGetEmployee() {RestTemplate restTemplate = new RestTemplate();Employee emp = restTemplate.getForObject(SERVER_URI+"/rest/emp/1", Employee.class);printEmpData(emp);}private static void testGetDummyEmployee() {RestTemplate restTemplate = new RestTemplate();Employee emp = restTemplate.getForObject(SERVER_URI+EmpRestURIConstants.DUMMY_EMP, Employee.class);printEmpData(emp);}public static void printEmpData(Employee emp){System.out.println("ID="+emp.getId()+",Name="+emp.getName()+",CreatedDate="+emp.getCreatedDate());}
}

大多数程序都很容易理解,但是当调用rest方法返回Collection时,我们需要使用,LinkedHashMap因为JSON到对象转换不知道Employee对象并将其转换为集合LinkedHashMap。我们可以编写一个实用工具方法来转换LinkedHashMap为我们的Java Bean对象。

当我们运行上面的程序时,我们在控制台中获得以下输出。


ID=9999,Name=Dummy,CreatedDate=Tue Mar 04 21:02:41 PST 2014
*****
ID=1,Name=Pankaj Kumar,CreatedDate=Tue Mar 04 21:02:41 PST 2014
*****
ID=1,Name=Pankaj Kumar,CreatedDate=Tue Mar 04 21:02:41 PST 2014
*****
2
ID=1,Name=Pankaj Kumar,CreatedDate=1393995761654
ID=9999,Name=Dummy,CreatedDate=1393995761381

另一点是RestTemplateput方法没有设置响应对象的选项,因为PUT方法应该用于在服务器上存储某些东西,而简单的HTTP 200状态代码就足够了。

下载Spring Restful Webservice项目

这就是Spring Restful Web应用程序教程的全部内容。从上面的链接下载示例项目并使用它来了解更多信息。

更新:由于有很多请求提供类似的XML示例以及支持XML和JSON,我已经在Spring REST XML JSON示例中扩展了此应用程序,以支持XML和JSON请求和响应。我强烈建议你通过它来看看弹簧框架的美感以及实现这一目标是多么容易。

转载来源:https://www.journaldev.com/2552/spring-rest-example-tutorial-spring-restful-web-services

Spring Restful Web服务示例 - 使用JSON/Jackson和客户端程序相关推荐

  1. Spring Restful Web服务示例 - 使用JSON,Jackson和客户端程序

    Spring Restful Web服务示例 - 使用JSON,Jackson和客户端程序 Spring是最广泛使用的Java EE框架之一.我们之前已经看到了如何使用Spring MVC来创建基于J ...

  2. Spring RESTful Web服务中的异常处理

    1.简介 我们可能已经在Spring中遇到了几种处理RESTful Web服务应用程序中异常的方法. 在本文中,我们将尝试探索可以采取的最佳方法来实现有效的异常处理. 2.问题陈述 让我们创建一个简单 ...

  3. 使用 Jersey 和 Apache Tomcat 构建 RESTful Web 服务

    http://www.ibm.com/developerworks/cn/web/wa-aj-tomcat/ 使用 Jersey 和 Apache Tomcat 构建 RESTful Web 服务 Y ...

  4. jersey tomcat MySQL_基于jersey和Apache Tomcat构建Restful Web服务(一)

    基于jersey和Apache Tomcat构建Restful Web服务(一) 现如今,RESTful架构已然成为了最流行的一种互联网软件架构,它结构清晰.符合标准.易于理解.扩展方便,所以得到越来 ...

  5. restful api_将Spring MVC RESTful Web服务迁移到Spring 4

    restful api 1引言 Spring 4为MVC应用程序带来了一些改进. 在这篇文章中,我将重点介绍宁静的Web服务,并通过采用Spring 3.2实现的项目并将其升级到Spring 4来尝试 ...

  6. Spring 3 RESTful Web服务

    Spring 3提供了对RESTful Web服务的支持. 在本教程中,我们将向您展示如何在Spring中实现RESTful Web服务 ,或者如何将现有的Spring服务公开为RESTful Web ...

  7. 将Spring MVC RESTful Web服务迁移到Spring 4

    1引言 Spring 4为MVC应用程序带来了一些改进 . 在这篇文章中,我将重点介绍宁静的Web服务,并通过采用Spring 3.2实现的项目并将其升级到Spring 4来尝试这些改进.以下几点总结 ...

  8. Spring Boot 构建RESTful Web服务

    Spring Boot 构建RESTful Web服务 本指南将引导您完成使用Spring 创建" Hello World" RESTful Web服务的过程. 你会建立什么 您将 ...

  9. 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务

    Spring,构建 Java™ 平台和 Enterprise Edition (Java EE) 应用程序的著名框架,现在在其模型-视图-控制器(Model-View-Controller ,MVC) ...

最新文章

  1. 1036: [ZJOI2008]树的统计Count
  2. 2、Ktor学习-自动重新加载;
  3. Effective stl---笔记
  4. 前端三十二:超链接(a标签)
  5. aMCMC for Horseshoe: algorithms
  6. Mybatis笔记一:java.lang.NoClassDefFoundError: org/apache/ibatis/mapping/DatabaseIdProvider
  7. 编写高质量代码:改善Java程序的151个建议(第3章:类、对象及方法___建议36~40)
  8. [css] 使用css写一个垂直翻转图片的效果
  9. react做h5 例子_使用React写一个网站的心得体会
  10. 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现
  11. 计算机知识提炼,2017计算机考研:操作系统复习策略及重要知识点提炼
  12. 联想笔记本重装系统声卡驱动未安装报错代码28,声音图标显示红叉没有声音
  13. 把一个人的特点写具体作文_把一个人的特点写具体作文400字
  14. 斯特林数 java实现_关于斯特林数
  15. 100%可用的总裁主题授权版 WordPress付费资源素材下载主题
  16. 无悔追梦人 追梦五年
  17. d3.js 刷新折线图(包括坐标轴及路径的刷新及信息点提示)
  18. ubuntu 18.04 安装gdb
  19. 英雄联盟(LOL)外挂原理(仅供学术交流)
  20. Google Adsense优化SEO选词技巧

热门文章

  1. ubuntu 14.04.03 LTS(64bit) 安装PyCharm
  2. SpringBoot—项目启动时几种初始化操作及SpringApplication类详解
  3. SpringBoot—JPA和JDBC常用配置说明
  4. SpringBoot—单元测试模板(controller层和service层)
  5. 【OpenGL】理解GL_TRIANGLE_STRIP等绘制三角形序列的三种方式
  6. 案例 项目经理评分 c# 1613922661
  7. 演练 网站的头部导航栏的制作 1014 HTML
  8. javascript 西瓜一期 14 回顾 字符与编码 进制转换 数据保存
  9. linux-安装树形查看工具-tree
  10. python-容器数据类型-知识小结