`
yangjizhong24
  • 浏览: 399105 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

RESTful Web Services in Spring 3(上)

阅读更多

通过本文,我将介绍REST的特点,基本设计原则及其简单讲解,最后给出spring3.0下开发的RESTful Web Services 简单实例,其中许多内容是在网络上摘得,并通过自己理解写上的本人观点的博客,如有不同意见请指正。

 

 

    REST(Representational State Transfer ),有中文翻译为"具象状态传输"(也有:"代表性状态传输")。是由 Roy Thomas Fielding博士 在2000年就读加州大学欧文分校期间在学术论文中提出的一个术语。他首次系统全面地阐述了REST的架构风格和设计思想。这篇论文是Web发展史上一篇非常重要的技术文献,他也为WEB架构的设计与评判奠定了理论基础。

 

注:附件里有论文的中文版,有兴趣的朋友可以下载看看。

 

    REST 定义了一组体系架构原则,您可以根据这些,包括使用不同语言编写的客户端如何通过 HTTP 处理和传输资源状态。所以在事实上,REST 对 Web的影响非常大,由于其使用相当方便,已经普遍地取代了基于 SOAP 和 WSDL 的接口设计。在多年以后的今天,REST的主要框架已经开始雨后春笋般的出现。


    个人理解:

(一)  首先REST只是一种风格,不是一种标准
(二)  REST是以资源为中心
(三)  REST充分利用或者说极端依赖HTTP协议

 

一.对于今天正在吸引如此多注意力的最纯粹形式的 REST Web 服务,其具体实现应该遵循以下基本设计原则

1.1.显式地使用不同的 HTTP 请求方法
1.2.无状态
1.3.公开目录结构式的 URI(通过逻辑URI定位资源)。

 

1.1.显式地使用不同的 HTTP 请求方法

    我们在 Web 应用中处理来自客户端的请求时,通常只考虑 GET 和 POST 这两种 HTTP 请求方法。实际上,HTTP 还有 HEAD、PUT、DELETE 等请求方法。而在 REST 架构中,用不同的 HTTP 请求方法来处理对资源的 CRUD(创建、读取、更新和删除)操作:

    若要在服务器上创建资源,应该使用 POST 方法。 
    若要检索某个资源,应该使用 GET 方法。 
    若要更改资源状态或对其进行更新,应该使用 PUT 方法。 
    若要删除某个资源,应该使用 DELETE 方法。

 

经过这样的一番扩展,我们对一个资源的 CRUD 操作就可以通过同一个 URI 完成了:

[url]http://www.example.com/photo/logo[/url](读取)
仍然保持为 [GET] [url]http://www.example.com/photo/logo[/url]

 

[url]http://www.example.com/photo/logo/create[/url](创建)
改为 [POST] [url]http://www.example.com/photo/logo[/url]

 

[url]http://www.example.com/photo/logo/update[/url](更新)
改为 [PUT] [url]http://www.example.com/photo/logo[/url]

 

[url]http://www.example.com/photo/logo/delete[/url](删除)
改为 [DELETE] [url]http://www.example.com/photo/logo[/url]

 

从而进一步规范了资源标识的使用。


通过 REST 架构,Web 应用程序可以用一致的接口(URI)暴露资源给外部世界,并对资源提供语义一致的操作服务。这对于以资源为中心的 Web 应用来说非常重要。

 

1.2.无状态

 

在 REST 的定义中,一个 Web 应用总是使用固定的 URI 向外部世界呈现一个资源。
它认为Web是由一系列的抽象资源组成,这些抽象的资源具有不同的具体表现形式。
譬如,定义一个资源为photo,含义是照片,它的表现形式可以是一个图片,也可以是一个.xml的文件,其中包含一些描述该照片的元素,或是一个html文件。 并且这些具体的表现可以分布在不同的物理位置上。


1.3.通过逻辑URI定位资源


实现这种级别的可用性的方法之一是定义目录结构式的 URI。
此类 URI 具有层次结构,其根为单个路径,从根开始分支的是公开服务的主要方面的子路径。 根据此定义,URI 并不只是斜杠分隔的字符串,而是具有在节点上连接在一起的下级和上级分支的树。 例如,在一个收集photo的相册中,您可能定义类似如下的结构化 URI 集合:

 

http://www.example.com/photo/topics/{topic}

 

如:http://www.example.com/photo/topics/home

 

根 / photo之下有一个 /topics 节点。 该节点之下有一系列主题名称,例如生日照片,聚会照片等等,每个主题名称指向某个讨论线。 在此结构中,只需在 {topic}输入某个内容即可容易地收集讨论线程。

在某些情况下,指向资源的路径尤其适合于目录式结构。 例如,以按日期进行组织的资源为例,这种资源非常适合于使用层次结构语法。
此示例非常直观,因为它基于规则:

 

http://www.example.com/photo/2010/02/22/{topic}

 

第一个路径片段是四个数字的年份,第二个路径片断是两个数字的月份,第三个片段是两个数字的日期。这就是我们追求的简单级别。 在语法的空隙中填入路径部分就大功告成了,因为存在用于组合 URI 的明确模式:
http://www.example.com/photo/{year}/{day}/{month}/{topic}


从而不需要我们去这样去传递信息:http://www.example.com/photo?year=xxxx&day=xxx$month=xxx&topic=xxxx


二.Restful web service的优点:

 

2.1 HTTP头中可见的统一接口和资源地址

通过对于HTTP Head 的解析,我们便可以了解到当前所请求的资源和请求的方式。
这样做对于一些代理服务器的设置,将带来很高的处理效率。
REST 系统中所有的动作和要访问的资源都可以从HTTP和URI中得到,这使得代理服务器、缓存服务器和网关很好地协调工作。而RPC模型的SOAP 要访问的资源仅从 URI无法得知,要调用的方法也无法从HTTP中得知,它们都隐藏在 SOAP 消息中。
同样的,在REST系统中的代理服务器还可以通过 HTTP 的动作 (GET 、 POST)来进行控制。


2.2 返回一般的XML格式内容

一般情况下,一个RESTful Web Service将比一个传统SOAP RPC Web Service占用更少的传输带宽。

POST/Order HTTP/1.1
Host:[url]www.northwindtraders.com[/url]
Content-Type:text/xml
Content-Length:nnnn
 
<UpdatePO>
      <orderID>098</orderID>
      <customerNumber>999</customerNumber>
      <item>89</item>
      <quantity>3000</quantity>
</UpdatePO> 

 

 

POST/Order HTTP/1.1
Host:[url]www.northwindtraders.com[/url]
Content-Type:text/xml
Content-Length:nnnn
SOAPAction:"urn:northwindtraders.com:PO#UpdatePO"
 
<SOAP-ENV:Envelope
xmlns:xsi="[url]http://www.3w.org/1999/XMLSchema/instance[/url]"
xmlns:SOAP-ENV="[url]http://schemas.xmlsoap.org/soap/envelope[/url]"
xsi:schemaLocation="[url]http://www.northwindtraders.com/schema/NPOSchema.xsd[/url]">
<SOAP-ENV:Body xsi:type="NorthwindBody">
    <UpdatePO>
      <orderID>098</orderID>
      <customerNumber>999</customerNumber>
      <item>89</item>
      <quantity>3000</quantity>
    </UpdatePO>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> 

 


2.3 安全机制

REST使用了简单有效的安全模型。REST中很容易隐藏某个资源,只需不发布它的URI;而在资源上也很容易使用一些安全策略,比如可以在每个 URI 针对 4个通用接口设置权限;再者,以资源为中心的 Web服务是防火墙友好的,因为 GET的 意思就是GET, PUT 的意思就是PUT,管理员可以通过堵塞非GET请求把资源设置为只读的,而现在的基于RPC 模型的 SOAP 一律工作在 HTTP 的 POST上。而使用 SOAP RPC模型,要访问的对象名称藏在方法的参数中,因此需要创建新的安全模型。


 三. 使用REST架构

 

  对于开发人员来说,关心的是如何使用REST架构,这里我们来简单谈谈这个问题。REST带来的不仅仅是一种崭新的架构,它更是带来一种全新的Web开发过程中的思维方式:通过URL来设计系统结构。REST是一套简单的设计原则、一种架构风格(或模式),不是一种具体的标准或架构。到今天REST有很多成功的使用案例,客户端调用也极其方便。

  目前宣称支持REST的Java框架包括以下这些:
  Restlet(http://www.restlet.org/
  Cetia4(https://cetia4.dev.java.net/
  Apache Axis2(http://http://ws.apache.org/axis2/
  sqlREST(http://sqlrest.sourceforge.net/
REST-art(http://rest-art.sourceforge.net/

 

下面是我通过Spring3.0写的一个很简单的REST举例。

 

依赖包请去http://www.springsource.com获得,Spring3.0于2009年12月发布,在GOOGLE中它的新特性被广泛提及的便是完整的springmvc rest支持。

 

另:Spring3已经完全采用Java5/6开发和编译构建,因此应该是不再支持Java1.4及更早版本了

 

说了些题外话,开始正题:

 

本实例是个简单的“article service”,分服务端和客户端,现在我先说下服务端开发:

 

注:服务端源代码请在附件里下载,是个maven建的eclipse工程。

 

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" 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>Article Web Service</display-name>
  	
  	<servlet>
		<servlet-name>article</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>article</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
</web-app>

 

这里声明了名字为“article”的Spring DispatcherServlet,并匹配所有“/*” 的“article”servlet,在Spring 3里,当它发现有 “article” servlet时,它会自动在WEB-INF目录下寻找“article”-servlet.xml,我现在贴出article-servlet.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:oxm="http://www.springframework.org/schema/oxm"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">

    <context:component-scan base-package="com.informit.articleservice" />

	<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />

	<bean id="articleXmlView" 
		  class="org.springframework.web.servlet.view.xml.MarshallingView">
		<constructor-arg>
			<bean class="org.springframework.oxm.xstream.XStreamMarshaller">
				<property name="autodetectAnnotations" value="true"/>
			</bean>
		</constructor-arg>
	</bean>
</beans>

 

 

这里它做了几件事情:

 

1.Spring会扫描com.informit.articleservice包或他的子包来作为他的servlet组件
2.声明了一个articleXmlView bean 为了初始化XStreamMarshaller,这个类会把我们接口中得到结果以XML文档形式展现出来

 

通过这个配置文档,我们声明我们的类和注释后,spring自己会照顾rest,现在我们看下Spring MVC ArticleController class:

 

 

package com.informit.articleservice;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.informit.articleservice.model.Article;
import com.informit.articleservice.model.Category;
import com.informit.articleservice.service.ArticleService;

@Controller
public class ArticleController {

	@Autowired
	private ArticleService articleService;

	@RequestMapping(value = "/article/{category}/{id}", method = RequestMethod.GET)
	public ModelAndView loadArticle(@PathVariable String category, @PathVariable int id,
			@RequestParam(value = "mode", required = false) String mode) {
		// Load the article based on the mode
		Article article = null;
		System.out.println("mode:" + mode);
		if (mode != null && mode.equalsIgnoreCase("summary")) {
			article = articleService.getArticleSummary(category, id);
		} else {
			article = articleService.getArticle(category, id);
		}

		// Create and return a ModelAndView that presents the article to the caller
		ModelAndView mav = new ModelAndView("articleXmlView", BindingResult.MODEL_KEY_PREFIX + "article", article);
		return mav;
	}

	@RequestMapping(value = "/article", method = RequestMethod.GET)
	public ModelAndView loadArticleCategories() {
		List<Category> categories = articleService.loadCategories();
		ModelAndView mav = new ModelAndView("articleXmlView", BindingResult.MODEL_KEY_PREFIX + "category", categories);
		return mav;
	}

	@RequestMapping(value = "/article", method = RequestMethod.DELETE)
	public ModelAndView delArticleCategories() {
		List<Category> categories = articleService.loadCategories();
		System.out.println("delete oprate");
		ModelAndView mav = new ModelAndView("articleXmlView", BindingResult.MODEL_KEY_PREFIX + "category", categories);
		return mav;
	}

	@RequestMapping(value = "/addarticle", method = RequestMethod.POST)
	public ModelAndView addArticleCategories(Category category) {
		List<Category> categories = new ArrayList<Category>();
		System.out.println(category.getName());
		categories.add(category);
		ModelAndView mav = new ModelAndView("articleXmlView", BindingResult.MODEL_KEY_PREFIX + "category", categories);
		return mav;
	}

	@RequestMapping(value = "/addarticle/{name}", method = RequestMethod.POST)
	public ModelAndView addArticleCategoriesForName(@PathVariable String name) {
		List<Category> categories = new ArrayList<Category>();
		Category category = new Category();
		category.setName(name);
		System.out.println(name);
		categories.add(category);
		ModelAndView mav = new ModelAndView("articleXmlView", BindingResult.MODEL_KEY_PREFIX + "category", categories);
		return mav;
	}

}

 

 

ArticleController class 被@Controller注释后,他会自动作为一个Spring MVC controller class,而@RequestMapping annotation(注释)会告诉Spring有关的URI,比如“/article”。“method = RequestMethod.GET”代表以GET方式传递HTTP请求,

 

我们可以通过http://localhost:8080/articleservice/article看下效果。

 

而"/article/{category}/{id}"代表{category}和{id}为传递进来的值作为URI,如通过http://localhost:8080/articleservice/article/kk/22来把相应的值传递进方法中,“@PathVariable String category”即为category赋值,@RequestParam(value = "mode", required = false) String mode即可获得mode参数值,如:http://localhost:8080/articleservice/article/kk/22?mode=jizhong

然后处理逻辑后再ModelAndView中通过“articleXmlView”bean把loadArticle()方法的article对象或loadArticleCategories()方法的list返回

 

 

下面给出业务逻辑类:

 

package com.informit.articleservice.service;

import java.util.List;

import com.informit.articleservice.model.Article;
import com.informit.articleservice.model.Category;

public interface ArticleService {

	public Article getArticle(String category, int id);

	public Article getArticleSummary(String category, int id);

	public List<Category> loadCategories();
}

 

 

 

package com.informit.articleservice.service;

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

import org.springframework.stereotype.Service;

import com.informit.articleservice.model.Article;
import com.informit.articleservice.model.Category;

@Service("articleService")
public class ArticleServiceImpl implements ArticleService {

	@Override
	public Article getArticle(String category, int id) {
		return new Article(1, "My Article", "Steven Haines", new Date(), "A facinating article",
				"Wow, aren't you enjoying this article?");

	}

	@Override
	public Article getArticleSummary(String category, int id) {
		return new Article(1, "My Article", "Steven Haines", new Date(), "A facinating article");
	}

	public List<Category> loadCategories() {
		List<Category> categories = new ArrayList<Category>();
		categories.add(new Category("fun"));
		categories.add(new Category("work"));
		return categories;
	}

}

 

 

 

这里我列出使用的两个实体类:

 

 

package com.informit.articleservice.model;

import java.io.Serializable;
import java.util.Date;

import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias( "article" )
public class Article implements Serializable
{
	private static final long serialVersionUID = 1L;
	
	private int id;
	private String title;
	private String author;
	private Date publishDate;
	private String summary;
	private String body;
	
	public Article()
	{
	}
	
	public Article( int id, String title, String author, Date publishDate, String summary, String body )
	{
		this.id = id;
		this.title = title;
		this.author = author;
		this.publishDate = publishDate;
		this.summary = summary;
		this.body = body;
	}
	
	public Article( int id, String title, String author, Date publishDate, String summary )
	{
		this.id = id;
		this.title = title;
		this.author = author;
		this.publishDate = publishDate;
		this.summary = summary;
	}

	public int getId()
	{
		return id;
	}

	public void setId( int id )
	{
		this.id = id;
	}

	public String getTitle()
	{
		return title;
	}
	public void setTitle( String title )
	{
		this.title = title;
	}
	public String getAuthor()
	{
		return author;
	}
	public void setAuthor( String author )
	{
		this.author = author;
	}
	public Date getPublishDate()
	{
		return publishDate;
	}
	public void setPublishDate( Date publishDate )
	{
		this.publishDate = publishDate;
	}
	public String getSummary()
	{
		return summary;
	}
	public void setSummary( String summary )
	{
		this.summary = summary;
	}
	public String getBody()
	{
		return body;
	}
	public void setBody( String body )
	{
		this.body = body;
	}
	
	
}

 

 

 

package com.informit.articleservice.model;

import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias("category")
public class Category {
	private String name;

	public Category() {
	}

	public Category(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

 

 

 

 

他们被@XStreamAlias()注释了,那么他们在XML文档下的显示别名就以其属性名显示,如"title"

至此,服务端配置就完成了,您可以通过连接:

http://localhost:8080/articleservice/article

http://localhost:8080/articleservice/article/fun/1

http://localhost:8080/articleservice/article/fun/1?mode=summary


因为篇幅,下一讲我将专门写客户端调用的工程: RESTful web services using Spring's RestTemplate class

 

注:附件里提供源码,有兴趣的朋友下载看吧

 

下篇的文章地址为:http://yangjizhong.iteye.com/admin/blogs/600680

 

 

 

分享到:
评论
7 楼 Partys 2014-05-20  
Partys 写道
addArticleCategories(Category category)  这个时 浏览器requerst body是

<category>
<name>adsdfasdfasdfasdfasdfasdfasdf</name>
</category>
但是该方法中
System.out.println(category.getName());  这行打印为“NULL”


又遇到类似情况 的吗?求解!
6 楼 Partys 2014-05-20  
addArticleCategories(Category category)  这个时 浏览器requerst body是

<category>
<name>adsdfasdfasdfasdfasdfasdfasdf</name>
</category>
但是该方法中
System.out.println(category.getName());  这行打印为“NULL”
5 楼 Partys 2014-05-19  
受益匪浅
4 楼 萧_瑟 2012-04-06  
org.springframework.web.servlet.DispatcherServlet cannot be cast to javax.servlet.Servlet

哎,启动tomcat一直报这个错,网上看了些解决方法还是不行,不知道怎么办了。我没有用你的源代码,pom.xml文件加载的一些包和你的不一样,但不影响,因为你的是旧版的,有些现在是不存在的了,比如:org.springframework.web.servlet  换成了  spring-webmvc

不知道有方法解决没有?
3 楼 ricoyu 2011-01-26  
关于REST讲得很好, 不过请教一下Service层你为什么要抽象出一个接口ArticleService ? 你的ArticleService永远只会对应一个ArticleServiceImpl, 如果你要增加一个业务方法, 你必须同时在两个类里面添加, 这是毫无意义的. Interface Oriented programming并不是这么体现的.
2 楼 grandboy 2010-03-02  
我一直也没有想明白,为什么Spring不是基于JSR311标准来实现REST, 而是自己搞一套?如果一直用Spring也没有什么关系,但是要想换其他的实现方案的话,就得重新实现。不过幸好,换实现方案的情况还不是太常见,只是在有些项目里会有。还有就是学习成本的问题,像我对JSR311标准已经比较熟悉了,现在还要再学一套。
1 楼 随性而舞 2010-03-02  
我刚刚走入java领域,关于restful接口的实现,我有个疑问。

javaee6标准JAX-RS 1.1已经发布,我在新开发的项目里,是否有必要使用javaee标准的annotation而不是spring专有的annotation? 如果是,应该如何将javaee与spring集成,这方面的best practice 是什么样的.

相关推荐

    building restful web services with spring 5 2e

    Building RESTful Web Services with Spring 5 – Second Edition: Leverage the power of Spring 5.0, Java SE 9, and Spring Boot 2.0 Find out how to implement the REST architecture to build resilient ...

    Building RESTful Web Services with Spring 5(2nd) epub

    Building RESTful Web Services with Spring 5(2nd) 英文epub 第2版 本资源转载自网络,如有侵权,请联系上传者或csdn删除查看此书详细信息请在美国亚马逊官网搜索此书

    RESTful Java Web Services

    ### RESTful Java Web Services #### 一、RESTful Web服务概览 REST(Representational State Transfer)是一种软件架构风格,最初由Roy Fielding在他的博士论文中提出。它定义了一种简单且灵活的方法来创建分布式...

    Building RESTful Web Services with Go

    Building RESTful Web Services with Go:Initially, SOAP-based web services became more popular with XML. Then, since 2012,REST picked up the pace and gulped SOAP in whole. The rise of a new generation ...

    使用-Spring-3-来创建-RESTful-Web-Services

    使用 Spring 3 创建 RESTful Web Services RESTful Web Services 是一种基于 HTTP 和 REST 原理实现的 Web Service。使用 Spring 3,可以轻松地创建 Java 实现的服务器端 RESTful Web Services。本文将介绍使用 ...

    使用 Spring 3 来创建 RESTful Web Services

    **Spring 3 创建 RESTful Web Services 知识点详解** RESTful Web Services 是一种基于 Representational State Transfer(表述性状态转移)架构风格的 Web 应用设计模式,它强调资源的表述和状态转换,常用于构建...

    三步轻松实现java restful web services

    Java RESTful Web Services是开发现代Web应用程序的一种常见方式,它基于Representational State Transfer(REST)架构原则,提供了轻量级、高效且易于使用的接口。在本文中,我们将深入探讨如何分三步轻松实现Java ...

    RESTful Java Web Services (2009).pdf

    ### RESTful Java Web Services知识点概览 #### 一、RESTful架构原理与概念 - **REST(Representational State Transfer)**:一种网络应用程序的设计风格和开发方式,基于约束条件和原则,利用HTTP协议来实现...

    RESTFul+Maven+Spring 进行WebServices开发

    结合RESTful、Maven和Spring,我们可以快速地搭建和维护高质量的Web Services。RESTful提供了清晰的接口设计,Maven简化了项目管理和构建流程,而Spring框架则提供了强大的后端功能支持。在实际开发中,还需要考虑...

    Getting started with Spring Framework: covers Spring 5(epub)

    Stream API- Reactive programming using RxJava 2 and Reactor- Spring WebFlux- Reactive support in Spring Data MongoDB and Spring Security- Developing reactive RESTful web services using Spring WebFlux...

    Spring Web Services 2 Cookbook

    7. **Spring与RESTful服务**:虽然Spring Web Services主要关注SOAP,但书中可能也会涉及如何将Spring与其他组件结合,以支持RESTful风格的Web服务。 8. **实例分析与最佳实践**:书中的每个章节都会配合具体的代码...

    Java RESTful Web Service实战.pdf

    在Java中,我们常用JAX-RS(Java API for RESTful Web Services)来实现RESTful服务。JAX-RS为创建RESTful服务提供了便利的API,例如使用`@Path`注解定义资源路径,`@GET`、`@POST`等注解指定HTTP方法,以及`@...

    Spring web services 2 cookbook

    2. REST和SOAP服务:Spring Web Services支持构建RESTful Web服务,同时也支持SOAP Web服务。读者将学习如何根据需要选择合适的通信协议,并实施相应的服务。 3. 安全性:在Web服务中,安全性是一个重要的方面。...

    Spring集成Cxf暴露WebServices示例

    3. **使用JAX-WS注解**:在服务接口上使用JAX-WS注解,如`@WebService`,来指定服务的元数据,如服务名、端点地址等。同时,可以使用`@WebService`注解的`serviceName`和`endpointInterface`属性来关联服务接口。 4...

    Web Services平台架构

    在Java平台上,Spring框架也提供了强大的Web Services支持。Spring Web Services项目专注于基于合同优先的Web Services开发,强调使用WSDL来定义服务契约,然后自动生成服务实现。此外,Spring还提供了对WS-Security...

    Restful WebService + Spring

    在IT行业中,RESTful Web Service和Spring框架的集成是一个广泛使用的解决方案,特别是在构建现代、可扩展的分布式系统中。REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于...

Global site tag (gtag.js) - Google Analytics