精华内容
下载资源
问答
  • restful编码规范

    2020-12-09 18:29:11
    动词 描述 GET(select) 从服务器取出一个/多个资源 POST(create) 在服务器新建一个资源 ...对象范围 使用位置 详细参数 例子 @Api 协议集描述 controller类上 value:URL路径值 description:对ap

    1、HTTP动词
    动词
    描述
    GET(select) 从服务器取出一个/多个资源
    POST(create)
    在服务器新建一个资源
    PATCH(update)
    在服务器更新资源(客户端提供改变的属性)
    PUT(update) 在服务器更新资源(客户端提供改变后的完整资源)
    DELETE(delete)
    从客户端删除资源
    image.png

    2、swagger规范
    注解
    对象范围 使用位置 详细参数 例子
    @Api 协议集描述
    controller类上
    value:URL路径值

    description:对api资源的详细描述

    image.png
    @ApiOperation
    协议描述
    controller方法上
    value:接口操作简洁

    notes:接口描述

    image.png

    image.png

    @ApiResponses response集
    controller方法上

    @ApiResponse
    response
    @ApiResponses里面
    用于表示一组响应,一般用于表达错误的响应信息;

    image.png
    @ApiParam
    参数描述
    在Rest接口上、Rest接口参数前面

    @ApiImplicitParams 非对象参数集
    controller方法上

    @ApiImplicitParam 非对象参数
    @ApiImplicitParams方法里面
    name:属性名称

    value:属性介绍

    required:是否属性必填

    dataType:数据类型

    image.png

    多个参数,需要使用@ApiImplicitParams包裹;

    @ApiModel 描述返回对象的意义
    出入对象上 value:实体类的描述
    @ApiModelProperty 对象属性 出入对象的字段上 value:字段介绍
    注:@ApiImplicitParam比@ApiParam使用范围更广,非JAX-RS场合,只能使用@ApiImplicitParam。

    3、状态码
    服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。

    200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。

    201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。

    202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)

    204 NO CONTENT - [DELETE]:用户删除数据成功。

    400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。

    401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。

    403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。

    404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。

    406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。

    410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。

    422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。

    500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

    4、返回结果
    针对不同操作,服务器向用户返回的结果应该符合以下规范。

    GET /collection:返回资源对象的列表(数组)

    GET /collection/resource:返回单个资源对象

    POST /collection:返回新生成的资源对象

    PUT /collection/resource:返回完整的资源对象

    PATCH /collection/resource:返回完整的资源对象

    DELETE /collection/resource:返回一个空文档

    5、过滤信息
    如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。

    下面是一些常见的参数。

    https://api.example.com/v1/zoos?limit=10:指定返回记录的数量

    https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置

    https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数

    https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序

    https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件

    参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的。

    6、代码实例
    (1)controller

    @Api

    @ApiOperation

    @ApiParam

    @ApiImplicitParams、@ApiImplicitParam

    @ApiResponses、@ApiResponse

    (2)出入参

    @ApiModel

    @ApiModelProperty

    展开全文
  • RESTful webservice

    2014-03-06 23:36:41
    JAX-RS (JSR-311) 是为 Java EE 环境下 RESTful 服务能力提供一种规范。它能提供对传统基于 SOAP Web 服务一种可行替代。 在本文中,了解 JAX-RS 主要组件。本文用一个例子展示了一个企业如何使用 ...
    

    JAX-RS (JSR-311) 是为 Java EE 环境下的 RESTful 服务能力提供的一种规范。它能提供对传统的基于 SOAP 的 Web 服务的一种可行替代。

    在本文中,了解 JAX-RS 的主要组件。本文用一个例子展示了一个企业如何使用 JAX-RS 内的功能以一种 Restful 的方式公开员工的联系信息。


    背景

    多年来,开发人员使用各种工具在其 Java 应用程序内创建 RESTful 服务。由于 REST 架构的简单性,主要需求 — 接收 HTTP 消息和头部的能力 — 可以由一个简单的 Java Web 容器实现。

    Java servlets 常被用来开发 RESTful 应用程序。如何使用 servlet 并没有固定的模式。通常,servlet 会接受请求并自己解析这个 HTTP 请求 URI,以将此请求与一个已知资源相匹配。对于 REST 服务开发,这个简单的 servlet 模型以更为正式的 API 得到扩展。但是,因为这些 API 是在 servlet 模型之上开发的,所以这些 API 中没有一个是作为正式的标准开发的。

    随着 REST 越来越多地被采用为一种架构,Java Community Process (JCP) 计划在未来的 Java Enterprise Edition 6 发布版中包括对 REST 的正式支持。JSR-311 也已创建好,并已有了 JAX-RS 1.0 规范,提供了一种新的基于注释的方式来开发 RESTful 服务。与 servlet 模型相比,JAX-RS 注释让您能集中于您的资源和数据对象。并且,您不必再开发通讯层(通过 servlet)。


    Java 资源

    JAX-RS 建立了一种特殊的语言来描述资源,正如由其编程模型所表示的。有五种主要条目:根资源、子资源、资源方法、子资源方法以及子资源定位器。

    根资源

    根资源是由 @Path 注释的 Java 类。@Path 注释提供了一个 value 属性,用来表明此资源所在的路径。value 属性可以是文本字符、变量或变量外加一个定制的正则表达式。清单 1 给出了一个例子。

    清单 1. JAX-RS 根资源
    package com.ibm.jaxrs.sample.organization;
    
    import javax.ws.rs.Path;
    
    @Path(value="/contacts")
    public class ContactsResource {
    	...
    }

    子资源

    子资源是作为 subresource locator 调用的结果返回的 Java 类。它们类似于根资源,只不过它们不是由 @Path 注释的,因它们的路径是由子资源定位器给出的。子资源通常包含由 HTTP 请求方法指示符(designator)注释的方法以便服务此请求。如果它们不包含如此注释的方法,那么它们将会通过指派给合适的子资源定位器来进一步解析此资源处理请求。

    清单 2. JAX-RS 子资源
    package com.ibm.jaxrs.sample.organization;
    
    import javax.ws.rs.GET;
    
    public class Department {
    	
    
    	
    	@GET
    	public String getDepartmentName() {
    		...
    	}
    	
    
    	
    }

    如上所示的清单 2 展示了由 ContactsResource.getContactDepartment 方法返回的子资源。在这个例子中,如果一个 HTTP GET 请求被发送给 /contact/{contactName}/department 路径,那么 Department 子资源内的 getDepartmentName 资源方法就会处理此请求。

    资源方法

    资源方法是根资源或子资源内绑定到 HTTP 方法的 Java 方法。绑定是通过诸如 @GET 这样的注释完成的。

    清单 3. JAX-RS 资源方法
    package com.ibm.jaxrs.sample.organization;
    
    import java.util.List;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    
    @Path(value="/contacts")
    public class ContactsResource {
    	
    	
    	
    	@GET
    	public List<ContactInfo> getContacts() {
    		...
    	}
    	
    
    }

    在清单 3 的例子中,发送到 /contacts 路径的 HTTP GET 请求将会由 getContacts() 资源方法处理。

    子资源方法

    子资源方法非常类似于资源方法;惟一的区别是子资源方法也是由 @Path 注释的,此注释进一步限定了该方法的选择。

    清单 4. JAX-RS 子资源方法
    package com.ibm.jaxrs.sample.organization;
    
    import java.util.List;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    
    @Path(value="/contacts")
    public class ContactsResource {
    	
    	@GET
    	public List<ContactInfo> getContacts() {
    		...
    	}
    	
    	
    	
    	@GET
    	@Path(value="/ids")
    	public List<String> getContactIds() {
    		...
    	}
    	
    
    }

    在清单 4 中,发送到 /contacts/ids 路径的 HTTP GET 请求将会由 getContactIds() 子资源方法处理。

    子资源定位器

    子资源定位器是能进一步解析用来处理给定请求的资源的一些方法。它们非常类似于子资源方法,因它们具备一个 @Path 注释,但不具备 HTTP 请求方法指示符,比如 @GET 注释。

    清单 5. JAX-RS 子资源定位器
    package com.ibm.jaxrs.sample.organization;
    
    import java.util.List;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    
    @Path(value="/contacts")
    public class ContactsResource {
    	
    	@GET
    	public List<ContactInfo> getContactss() {
    		...
    	}
    	
    		@GET
    	@Path(value="/ids")
    	public List<String> getContactIds() {
    		...
    	}
    	
    	
    	
    	@Path(value="/contact/{contactName}/department")
    	public Department getContactDepartment(@PathParam(value="contactName") 
    		String contactName) {
    		...
    	}
    	
    
    }

    在上述例子中,对 /contact/{contactName}/department 路径的任何 HTTP 请求都将由 getContactDepartment 子资源定位器处理。 {contactName} 部分表明 contact 路径部分之后可以是任何合法的 URL 值。


    注释

    本节将会探讨一些重要的注释及其使用。对于由 JAX-RS 规范提供的注释的完整列表,可以参考本文的 参考资料 部分给出的 JSR-311 链接。

    @Path

    @Path 注释被用来描述根资源、子资源方法或子资源的位置。value 值可以包含文本字符、变量或具有定制正则表达式的变量。清单 6 的例子展示了 @Path 注释的主要应用。

    清单 6. @Path 的使用
    package com.ibm.jaxrs.sample.organization;
    
    import java.util.List;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    
    @Path(value="/contacts")
    public class ContactsResource {
    
    		
    	@GET
    	@Path(value="/{emailAddress:.+@.+\\.[a-z]+}")
    	public ContactInfo getByEmailAddress(@PathParam(value="emailAddress") 
    		String emailAddress) {
    		...
    	}
    	
    	@GET
    	@Path(value="/{lastName}")
    	public ContactInfo getByLastName(@PathParam(value="lastName") String lastName) {
    		...
    	}
    }

    ContactsResource 类上的注释表明对 /contacts 路径的所有请求都将由 ContactsResource 根资源处理。getByEmailAddress 上的 @Path 注释则表明任何发送到 /contacts/{emailAddress} 的请求(其中 emailAddress 代表的是正则表达式 .+@.+\\.[a-z]+)都将由 getByEmailAddress 处理。

    getByLastName 方法上的 @Path 注释指定了发送到 /contacts/{lastName} 路径的所有请求(其中 lastName 代表的是一个与 getByEmailAddress 内的正则表达式不匹配的有效的 URL 部分)都将由 getByLastName 方法处理。

    @GET、@POST、@PUT、@DELETE、@HEAD

    @GET、@POST、@PUT、@DELETE 以及 @HEAD 均是 HTTP 请求方法指示符注释。您可以使用它们来绑定根资源或子资源内的 Java 方法与 HTTP 请求方法。HTTP GET 请求被映射到由 @GET 注释的方法;HTTP POST 请求被映射到由 @POST 注释的方法,以此类推。用户可能还需要通过使用 @HttpMethod 注释定义其自己的定制 HTTP 请求方法指示符。

    清单 7. 定制的 HTTP 请求方法指示符注释
    package com.ibm.jaxrs.sample.organization;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import javax.ws.rs.HttpMethod;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @HttpMethod("GET")
    public @interface CustomGET {
    
    }

    上述的声明定义了 @CustomGET 注释。此注释将具有与 @GET 注释相同的语义值并可用在其位置上。

    @Conumes 和 @Produces

    @Consumes 注释代表的是一个资源可以接受的 MIME 类型。@Produces 注释代表的是一个资源可以返回的 MIME 类型。这些注释均可在资源、资源方法、子资源方法、子资源定位器或子资源内找到。

    清单 8. @Consumes/@Produces
    package com.ibm.jaxrs.sample.organization;
    
    import java.util.List;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.Produces;
    
    @Path(value="/contacts")
    public class ContactsResource {
    
    		
    	@GET
    	@Path(value="/{emailAddress:.+@.+\\.[a-z]+}")
    	@Produces(value={"text/xml", "application/json"})
    	public ContactInfo getByEmailAddress(@PathParam(value="emailAddress") 
    		String emailAddress) {
    		...
    	}
    	
    	@GET
    	@Path(value="/{lastName}")
    	@Produces(value="text/xml")
    	public ContactInfo getByLastName(@PathParam(value="lastName") String lastName) {
    		...
    	}
    	
    	@POST
    	@Consumes(value={"text/xml", "application/json"})
    	public void addContactInfo(ContactInfo contactInfo) {
    		...
    	}
    }

    对于上述的 getByEmailAddressaddContactInfo 方法,它们均能处理 text/xmlapplication/json。被接受或返回的资源表示将依赖于客户机设置的 HTTP 请求头。@Consumes 注释针对 Content-Type 请求头进行匹配,以决定方法是否能接受给定请求的内容。

    在清单 9 中,application/jsonContent-Type 头再加上对路径 /contacts 的 POST,表明我们的 ContactsResource 类内的 addContactInfo 方法将会被调用以处理请求。

    清单 9. Content-Type 头部的使用
    POST /contacts HTTP/1.1
    Content-Type: application/json
    Content-Length: 32

    相反地,@Produces 注释被针对 Accept 请求头进行匹配以决定客户机是否能够处理由给定方法返回的表示。

    清单 10. Accept 头部的使用
    GET /contacts/johndoe@us.ibm.com HTTP/1.1
    Accept: application/json

    在清单 10 中,对 /contacts/johndoe@us.ibm.com 的 GET 请求表明了 getByEmailAddress 方法将会被调用并且返回的格式将会是 application/json,而非 text/xml。


    Providers

    JAX-RS 提供程序是一些应用程序组件,允许在三个关键领域进行运行时行为的定制:数据绑定、异常映射以及上下文解析(比如,向运行时提供 JAXBContext 实例)。每个 JAX-RS 提供程序类必须由 @Provider 注释。如下的例子讨论了两个数据绑定提供程序 MessageBodyWriter MessageBodyReader

    MessageBodyWriter

    MessageBodyWriters 被 JAX-RS 运行时用来序列化所返回资源的表示。遵从 JSR-311 的运行时提供了对常见类型(java.lang.String、java.io.InputStream、 JAXB 对象等)的本机支持,但用户也可以向 JAX-RS 运行时提供他或她自己的 MessageBodyWriter。比如,您可以提供一个定制 MessageBodyWriter 来处理定制 ContactInfo Java 类型,如下所示。

    清单 11. 定制 MessageBodyWriter
    package com.ibm.jaxrs.sample.organization;
    
    import javax.ws.rs.Consumes;
    import javax.ws.rs.Produces;
    import javax.ws.rs.ext.MessageBodyWriter;
    import javax.ws.rs.ext.Provider;
    
    @Provider
    @Produces("text/xml")
    public class ContactInfoWriter implements MessageBodyWriter<ContactInfo> {
    
    	public long	getSize(T t, java.lang.Class<ContactInfo> type, 
    		java.lang.reflect.Type genericType, java.lang.annotation.Annotation[] 
    		annotations, MediaType mediaType)  {
    		...
    	}
    	
    	public boolean isWriteable(java.lang.Class<ContactInfo> type, 
    		java.lang.reflect.Type genericType, java.lang.annotation.Annotation[] 
    		annotations, MediaType mediaType) {
    		return true;
    	}
    	
    	public void writeTo(ContactInfo contactInfo, java.lang.Class<ContactInfo> type, 
    		java.lang.reflect.Type genericType, java.lang.annotation.Annotation[] 
    		annotations, MediaType mediaType, MultivaluedMap<
    		java.lang.String, java.lang.Object> httpHeaders, java.io.OutputStream 
    		entityStream) {
    		contactInfo.serialize(entityStream);
    	}
    }

    ContactInfoWriter 则在所返回的资源表示被序列化之前由 JAX-RS 运行时调用。如果 isWriteable 返回 true 且 @Produces 是此资源方法的 @Produces 值最为接近的匹配,就会调用 writeTo 方法。在这里,ContactInfoWriter 负责向底层的 OutputStream 序列化 ContactInfo 实例的内容。

    MessageBodyReader

    MessageBodyReaders 则与 MessageBodyWriters 相反。对于反序列化,JAX-RS 运行时支持与序列化相同的类型。用户也可以提供他或她自己的 MessageBodyReader 实现。MessageBodyReader 的最主要的功能是读取请求 InputStream 并将传入的字节反序列化到一个此资源方法期望的 Java 对象。ContactInfo 类型的 MessageBodyReader 可以类似于清单 12。

    清单 12. 定制 MessageBodyReader
    package com.ibm.jaxrs.sample.organization;
    
    import javax.ws.rs.Consumes;
    import javax.ws.rs.Produces;
    import javax.ws.rs.ext.MessageBodyReader;
    import javax.ws.rs.ext.Provider;
    
    @Provider
    @Consumes("text/xml")
    public class ContactInfoReader implements MessageBodyReader<ContactInfo> {
    
    	public boolean isReadable(java.lang.Class<ContactInfo> type, 
    		java.lang.reflect.Type genericType, java.lang.annotation.Annotation[] 
    		annotations, MediaType mediaType) {
    		return true;
    	}
    	
    	public ContactInfo readFrom(java.lang.Class<ContactInfo> type, 
    		java.lang.reflect.Type genericType, java.lang.annotation.Annotation[] 
    		annotations, MediaType mediaType, MultivaluedMap<
    		java.lang.String,java.lang.String> httpHeaders, java.io.InputStream 
    		entityStream) {
    		return ContactInfo.parse(entityStream);
    	}
    	
    }

    与 MessageBodyWriter isWriteable 类似,ContactInfoReaderisReadable 方法将被调用以便决定 MessageBodyReader 能否处理此输入。如果 isReadable 返回 true 且 @Consumes 值与此资源方法的 @Consumes 值最为匹配,就会选择 ContactInfoReader。当 readFrom 方法被调用时,结果会是基于请求 InputStream 的内容创建 ContactInfo 实例。

    展开全文
  • sun也推出了RESTful WebService官方规范:JAX-RS,全称:Java API for RESTful WebService。 该规范定义了一系列注解,RESTful简化了web service设计,它不再需要wsdl,也不再需要soap协议, 而是通过最简单...

    RESTful 简化了 web service 的设计,它不再需要 wsdl ,也不再需要 soap 协议,而是通过最简单的 http 协议传输数据 ( 包括 xml  json) 。既简化了设计,也减少了网络传输量(因为只传输代表数据的 xml  json ,没有额外的 xml 包装),JAX-RS ,全称 Java API for RESTful WebService。该规范定义了一系列的注解。

    下面为大家介绍使用 cxf 开发 RESTful WebService

    Cxf3.1.5 实现 jax-rs 的全套规范。在使用它时,最好全部包含它的lib(在它安装目录下的lib下面),从其官网上下载apache-cxf-3.1.5.zip,解压后,在解压的lib目录就是运行时需要的文件。

    服务端

    Spring4 +cxf3.1.5 开发 RESTfulweb service。

    在eclipse上,选择开发动态web 应用项目,然后选择tomcat8作为web server。

    然后,在项目视图中选择build path,去添加spring4,cxf3.1.5的lib (为了省事,直接把cxf下面的lib全部包含过来就可以了),如图:

    同时,你得把这些libs都copy到 webcontent|web-inf|lib下面去,这样,eclipse在制作WAR文件时,会把这些.jar文件copy到war文件中去。

    否则,tomcat会因为找不到这些jar文件而无法启动this web service.

    本例子中,开发环境: 

    服务器端: eclipse + tomcat8 + CXF3.1.5 + Sring4 

    自己得去下载Spring4的jar包和CXF3.1.5的jar包,放到eclipse这个项目的web-content | web-info| lib下面


    Client端: eclipse  + CXF3.1.5 + httpclient + JSON + Java SE8


    在tomcat上面的运行的server代码

    EmployeeWSRestFulService.java (interface)

    package cxf.server;
    
    import java.util.*;
    import javax.ws.rs.core.*; 
    import javax.ws.rs.*;
    /**
     * 
     * @author bigtree
     * restful URI 匹配原理,它是咋构成的? access the below page
     *http://blog.csdn.net/bigtree_3721/article/details/51158758
     *
     */
    @Path("/")
    public interface EmployeeWSRestFulService {
    	/**
    	 * JSON提交
    	 * url:
    	 * http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws/addUser
    	 * Json format:{"user":{"id":123,"name":"newBook"}}
    	 * @param book
    	 * @return
    	 */
    	@Path("/addUser/")
    	@POST
    	@Consumes({"application/json","application/xml"})
    	Response addUser(User user);
    	  
    	@Path("/delUser/{id}/")
    	@DELETE
    	@Consumes({"application/json","application/xml"}) 
    	Response delUser(@PathParam("id") String id);
    	  
    	@Path("/updateUser/")
    	@PUT
    	@Consumes({"application/json","application/xml"})   
    	Response updateUser(User user);
    	 
    	  /* http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws/getUserById/1/
    	   * JSON: response content as below
    	   * 
    	   * HTTP/1.1 200 OK
    	   * {"user":{"id":1,"name":"bigtree"}}
    	   */
    	/*
    	 * XML response content as below
    		 * HTTP/1.1 200 OK
          <?xml version="1.0" encoding="UTF-8" standalone="yes"?><user><id>1</id><name>bigtree</name></user>
    		 */
    	
    	@Path("/getUserById/{id}/")
    	@GET
    	@Produces({"application/json","application/xml"}) //json is high priority
    	User getUserById(@PathParam("id") String id);
    
    	  /* http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws/
    	   * response:
    	   * HTTP/1.1 200 OK
    	   * {"user":[{"id":1,"name":"bigtree"},{"id":2,"name":"jackie"}]}
    	   * 
    	   */
    	@Path("/")
    	@GET
    	//json is high priority, default is application/xml
    	@Produces({"application/json","application/xml"}) 
    	List<User> findAllUsers();
    	
    }
    

    MyServiceImpl.java (server 的实现类)

    package cxf.server;
    import java.util.*;
    import javax.ws.rs.*;
    import javax.ws.rs.core.*;
    import java.net.URI;  
    import javax.ws.rs.core.Response.*; 
    public class MyServiceImpl implements EmployeeWSRestFulService {
    private void init(){
       User user = new User();
       user.setId("1");
       user.setName("bigtree");
       users.put(user.getId(), user);
       user = new User();
       user.setId("2");
       user.setName("jackie");
       users.put(user.getId(), user);
      }
     
     private HashMap<String, User> users = new HashMap<String,User>();
     public MyServiceImpl(){
       init();
     }
     public Response addUser(User user) {
       users.put(user.getId(), user);
       System.out.println("User entity to add: user id= "+user.getId()+" name="+user.getName());
       System.out.println("adding user succeed");
       System.out.println("total users in pool="+users.size());
       return Response.ok().build();
     }
     public Response delUser(String id) {
       User muser=users.remove(id);
       if(muser == null) { 
        // this user with this id not exist
        System.out.println("delUser(): no user entry found to delete");
        return Response.status(Status.BAD_REQUEST).build();
        }
       else
          return Response.ok().build();
     }
     public Response updateUser(User user) {
       users.put(user.getId(), user);
       System.out.println(users.get("1").getName());
       return Response.ok().build();
     }
     public User getUserById(String id) {
     User muser=users.get(id);
     if(muser==null)
     System.out.println("getUserById(): no user entry found");
     return muser;
     }
      public List<User> findAllUsers() {
       List<User> userlist = new ArrayList<User>();
       Iterator userit =  users.keySet().iterator();
       while(userit.hasNext()){
        userlist.add(users.get(userit.next()));
       }
       return userlist;
        }
     }

     Spring 配置文件 applicationContext.xml  配置内容如下, (applicationContext是 Spring从tomcat启动需要的缺省配置文件)

    <?xml version="1.0" encoding="GBK"?>
    <!-- Spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 -->
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
        xsi:schemaLocation=
          "http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-4.0.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
           http://www.springframework.org/schema/cache 
           http://www.springframework.org/schema/cache/spring-cache-4.0.xsd
           http://cxf.apache.org/jaxrs 
           http://cxf.apache.org/schemas/jaxrs.xsd
           ">
                
          <bean id="WSRestfulBean" class="cxf.server.MyServiceImpl"/>
          <jaxrs:server id="userService" address="/userws">
            <jaxrs:serviceBeans>
              <ref bean="WSRestfulBean"/>
            </jaxrs:serviceBeans>
           </jaxrs:server>
    </beans>
    

    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_3_0.xsd" id="WebApp_ID" version="3.0">
      
      <!-- 配置spring -->
        
      <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      <!-- 配置cxf servlet -->
      <servlet>
            <servlet-name>CXF315</servlet-name>
            <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>CXF315</servlet-name>
            <url-pattern>/WSRest/*</url-pattern>
        </servlet-mapping>
    
    </web-app>

    上面绿色部分需要自己写的。

    然后在eclipse中以输出上面的项目(eclipse会产生一个.war文件),启动tomcat,然后从进入tomcat管理页面(

    缺省是http://localhost:8080),点击"manager app",然后选择“WAR file to deploy”,选择上面产生的war文件,即可部署该web service服务了。


    客户端

    因为 RESTful 就是利用最原始的 http 协议传输数据,所以客户端其实就是一个 http客户端,有以下几种实现方式

    1) JAX-RS Client API --cxf3.0+

    2)Proxy 【使用起来简单,代理封装通信细节】

    3)Apache HttpClient

    4) WebClient

    为了简单我使用了 HttpClient方式

    代码如下

    WSRestFulClient.java

    package JAXRSClient;
    /*
     * How Request URI is Matched?
     * 
     * http://blog.csdn.net/bigtree_3721/article/details/51158758
     * 
    Lets assume 
    1) you have a web application called 'rest' (example, a 'rest.war' archive). 
    2) CXFServlet's url-pattern is "/test/*" (here it is defined in web.xml as below example shows
    <servlet>
    <servlet-name>CXF315</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>CXF315</servlet-name>
    <url-pattern>/WSRest/*</url-pattern>
    </servlet-mapping>
    3)  Finally, jaxrs:server's address is "/bar" 
    (it is defined in Spring's bean xml such as applicationContext.xml as below shown) 
    
    
    <bean id="WSRestfulBean" class="cxf.server.MyServiceImpl"/>   
    <jaxrs:server id="userService" address="/userws">
    <jaxrs:serviceBeans>
      <ref bean="WSRestfulBean"/>
    </jaxrs:serviceBeans>
    </jaxrs:server>
    
    
    Requests like /rest/test/bar or /rest/test/bar/baz will be delivered to one of the resource classes in a given jaxrs:server 
    endpoint. For the former request to be handled, a resource class with @Path("/") should be available, in the latter case - 
    at least @Path("/") or a more specific @Path("/baz").
     * 
     */
    
    
    /*
     * Output format:
     * 
     *  http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws/getUserById/1/
     *  
     *  Single user information format:
    **   JSON response format as below:
    *   HTTP/1.1 200 OK
    *   {"user":{"id":1,"name":"bigtree"}}  	   
    **  XML response format as below: 
        * HTTP/1.1 200 OK
        * <?xml version="1.0" encoding="UTF-8" standalone="yes"?><user><id>1</id><name>bigtree</name></user>
        * 
    * Multi-users response data format:
    * JSON response format as below
    *  HTTP/1.1 200 OK
    *  {"user":[{"id":1,"name":"bigtree"},{"id":2,"name":"jackie"}]}
    *
    ** XML response format as below
     * HTTP/1.1 200 OK
     * <?xml version="1.0" encoding="UTF-8"?><users><user><id>1</id><name>bigtree</name></user><user><id>2</id><name>jackie</name></user></users>
     */
    
    
    /* console output 
     * 
     * httpMethodgo(): request string={"user":{"name":"Jane","id":"5"}}
    HTTP/1.1 200 OK
    
    
    HttpPutgo(): request string={"user":{"name":"Jane5","id":"5"}}
    HTTP/1.1 200 OK
    
    
    get one user via Get method of WS-Restful
    HTTP/1.1 200 OK
    {"user":{"id":5,"name":"Jane5"}}
    receive OK rsp
    id=5 name=Jane5
    get all users via Get method of WS-Restful
    HTTP/1.1 200 OK
    {"user":[{"id":1,"name":"bigtree"},{"id":2,"name":"jackie"},{"id":5,"name":"Jane5"}]}
    receive OK rsp
    id=1 name=bigtree
    id=2 name=jackie
    id=5 name=Jane5
    deleting user failed
    HTTP/1.1 400 Bad Request
    
    
    HTTP/1.1 200 OK
    {"user":[{"id":1,"name":"bigtree"},{"id":2,"name":"jackie"},{"id":5,"name":"Jane5"}]}
    receive OK rsp
    id=1 name=bigtree
    id=2 name=jackie
    id=5 name=Jane5
     * 
     */
    
    
    import org.apache.http.*;  
    import org.apache.http.client.*;   
    import org.apache.http.client.methods.*;
    import org.apache.http.impl.client.*;
    import org.apache.http.util.*;
    import org.apache.http.entity.*;
    
    
    import java.net.URI;
    import java.util.*;
    import java.io.*;
    
    
    import org.json.*;
    import cxf.server.*;
    
    
    public class WSRestFulClient {
    	public static void main(String[] args) throws Exception {
    		 User muser = new User();
    		 muser.setId("5");
    		 muser.setName("Jane");
    		 
    		//post method to add user
    		 httpMethodgo("http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws/addUser", muser); 
    		
    		 //put method to update user
    		 muser.setName("Jane5");
    		 HttpPutgo("http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws/updateUser", muser); 		 
    	    /*
    		 * get a specified user via ID
    		 */
    		System.out.println("get one user via Get method of WS-Restful");
    		HttpGetgo("http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws/getUserById",5, true);
    		
    		System.out.println("get all users via Get method of WS-Restful");
    		/*
    		 * get all users
    		 */
    		HttpGetgo("http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws",1,false);  
    		//delete this user
    		 muser.setId("100");
    		 HttpDeletego("http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws/delUser", muser); 
    		 //get all users again
    		 HttpGetgo("http://localhost:8080/MyWebserviceRestfulSpringServer/WSRest/userws",1,false);  
    		 return;
    	  }
    	
    	private static void HttpPutgo(String uri, User muser ) throws Exception { 
    		 CloseableHttpClient httpclient = HttpClients.createDefault();
    		 HttpPut httpMethod = new HttpPut(uri);
    		 httpMethod.addHeader("content-type","application/json");
    
    
    		 JSONObject c = new JSONObject();
    		 c.put("name", muser.getName());
    		 c.put("id", muser.getId());
    		 
    		 JSONStringer js = new JSONStringer();
    		 js.object();
    		 js.key("user").value(c);
    		 js.endObject();
    		 
    		 String ms=js.toString();
    		 /** Console output
    		  * HttpPutgo(): request string={"user":{"name":"Jane5","id":"5"}}
    		  */
    		 System.out.println("HttpPutgo(): request string="+ms); 
    		 StringEntity entity = new StringEntity(ms,"UTF-8"); 
    		 httpMethod.setEntity(entity);
    		 CloseableHttpResponse response2 = httpclient.execute(httpMethod);
    		 System.out.println(response2.getStatusLine());
    		 String rst=EntityUtils.toString(response2.getEntity());
    		 /**
    		  * console output:
    		  * HTTP/1.1 200 OK
    		  */
             System.out.println(rst); 
    	 }
    	
    	 private static void httpMethodgo(String uri, User muser) throws Exception { 
    		 CloseableHttpClient httpclient = HttpClients.createDefault();
    		 HttpPost httpMethod = new HttpPost(uri);
    		 httpMethod.addHeader("content-type","application/json");
    		 
    		 JSONObject c = new JSONObject();
    		 c.put("name", muser.getName());
    		 c.put("id", muser.getId());
    		 
    		 JSONStringer js = new JSONStringer();
    		 js.object();
    		 js.key("user").value(c);
    		 js.endObject();
    		 
    		 String ms=js.toString();
    		 /** console output:
    		  * httpMethodgo(): request string={"user":{"name":"Jane","id":"5"}}
    		  */
    		 System.out.println("httpMethodgo(): request string="+ms); 
    		 
    		 StringEntity entity = new StringEntity(ms,"UTF-8"); 
    		 httpMethod.setEntity(entity);
    		 
    		 CloseableHttpResponse response2 = httpclient.execute(httpMethod);
    		 System.out.println(response2.getStatusLine());
    		 String rst=EntityUtils.toString(response2.getEntity());
    		 /**
    		  * HTTP/1.1 200 OK
    		  */
             System.out.println(rst);    
    	 }
    	 
    	 private static void HttpGetgo(String resource, Integer userid, boolean SingleResult) throws Exception {  
    		 CloseableHttpClient httpclient = HttpClients.createDefault();
    		 HttpGet request=null;
    		 try {
    			 if (SingleResult) {
    				 //get one user via id
    				request=new HttpGet(resource+"/"+userid.toString());
    						 else 	 
    			    request = new HttpGet(resource);
    			 
    			 HttpResponse response = httpclient.execute(request); 
    			 try {
    				    System.out.println(response.getStatusLine());
    				    String rst=EntityUtils.toString(response.getEntity());
    	                System.out.println(rst);
    	                
    	              if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK) {
    	                 System.out.println("receive OK rsp");
    	                 HttpEntity entity = response.getEntity();
    	                 if(entity == null) {
    	                	 System.out.println("entity is null");
    	                	return;
    	                }
    	                
    	                JSONObject jsonrsp = null;
    	                jsonrsp = new JSONObject(new JSONTokener(rst));
    	              
    	                if(SingleResult==false) {
    	                 JSONArray mobj=jsonrsp.getJSONArray("user");
    	                 Iterator it=mobj.iterator();
    	                 while(it.hasNext()){
    	                	JSONObject obj=(JSONObject)it.next();
    	                	  System.out.println("id="+obj.getInt("id")+" name="+obj.getString("name"));
    	                    } 
    	                 } 
    	                else {
    	                	JSONObject obj=jsonrsp.getJSONObject("user");
    	                	System.out.println("id="+obj.getInt("id")+" name="+obj.getString("name"));
    	                   }
    	                } 	              
    	            else {
    	                System.out.println("receive error rsp");
    	                }
    	      	    } 
    			finally {
    	                ;
    	            }
    		    } 
    		 finally {
    	            httpclient.close();
    	       }
    	 }  
    
    
    private static void HttpDeletego(String resource, User muser) throws Exception {  
    	 CloseableHttpClient httpclient = HttpClients.createDefault();
    	 HttpDelete request=null;
    	 try {
    		 //delete one user via id
    		  request=new HttpDelete(resource+"/"+muser.getId().toString());
    		  HttpResponse response = httpclient.execute(request); 
    		  if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
    			  System.out.println("deleting user succeed");  
    		  } 
    		  else {
    			  System.out.println("deleting user failed");   
    		  }
    		  
    		  System.out.println(response.getStatusLine());
    		  String rst=EntityUtils.toString(response.getEntity());
              System.out.println(rst);    
    	     } 
    	 finally {
               httpclient.close();
          }
      }  
    }
    

    另外,如果你不想用注解来标注代码,也可以用spring的 xml来配置,就像配置java bean一样,在上面的例子中,在applicatoinContent.xml中,可以写进如下的代码(例子)。

    <bean id="restfulRegeditService" class="zxn.ws.service.impl.RestfulRegeditServiceImpl" />

       <!--restful服务 -->
        <jaxrs:server id="restServiceContainer" address="/regedit">
            <jaxrs:serviceBeans>
                <ref bean="restfulRegeditService" />
            </jaxrs:serviceBeans>
            <jaxrs:extensionMappings>
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
            </jaxrs:extensionMappings>
            <jaxrs:languageMappings>
                <entry key="en" value="en-gb" />
            </jaxrs:languageMappings>
        </jaxrs:server>

    JSON-Java API page:

    http://stleary.github.io/JSON-java/index.html

    使用 TCPMON 这个工具监控以下,可以看到 http body 中只是简单的 json串,没有像 soap 协议那样的“信封”包装

    使用 RESTful 设计风格 + 传输 json 数据格式 可以大大的简化 web service 的设计并提高传输效率

    其实springMVC也采用了RESTful的设计风格,不过它使用的是spring自己的注解,这些注解和jax-rs中的注解惊奇的类似。如果大家有兴趣可以研究一下springMVC的RESTful特性。


    展开全文
  • 理解RESTful的幂等性,并且设计符合幂等规范的高质量RESTful API。 怎么理解幂等性 HTTP幂等方法,是指无论调用多少次都不会有不同结果的 HTTP 方法。不管你调用一次,还是调用一百次,一千次,结果都是相同的。 ...

    理解RESTful的幂等性,并且设计符合幂等规范的高质量RESTful API。

    怎么理解幂等性

    HTTP幂等方法,是指无论调用多少次都不会有不同结果的 HTTP 方法。不管你调用一次,还是调用一百次,一千次,结果都是相同的。

    还是以之前的博文的例子为例。

    GET     /tickets       # 获取ticket列表
    GET     /tickets/12    # 查看某个具体的ticket
    POST    /tickets       # 新建一个ticket
    PUT     /tickets/12    # 更新ticket 12
    PATCH   /tickets/12    # 更新ticket 12
    DELETE  /tickets/12    # 删除ticekt 12
    

    HTTP GET方法

    HTTP GET方法,用于获取资源,不管调用多少次接口,结果都不会改变,所以是幂等的。

    GET     /tickets       # 获取ticket列表
    GET     /tickets/12    # 查看某个具体的ticket
    

    只是查询数据,不会影响到资源的变化,因此我们认为它幂等。

    值得注意,幂等性指的是作用于结果而非资源本身。怎么理解呢?例如,这个HTTP GET方法可能会每次得到不同的返回内容,但并不影响资源。

    可能你会问有这种情况么?当然有咯。例如,我们有一个接口获取当前时间,我们就应该设计成

    GET     /service_time # 获取服务器当前时间
    

    它本身不会对资源本身产生影响,因此满足幂等性。

    HTTP POST方法

    HTTP POST方法是一个非幂等方法,因为调用多次,都将产生新的资源。

    POST    /tickets       # 新建一个ticket
    

    因为它直接把实体部分的数据替换到服务器的资源,我们多次调用它,只会产生一次影响,但是有相同结果的 HTTP 方法,所以满足幂等性。

    HTTP PATCH方法

    HTTP PATCH方法是非幂等的。HTTP POST方法和HTTP PUT方法可能比较好理解,但是HTTP PATCH方法只是更新部分资源,怎么是非幂等的呢?

    因为,PATCH提供的实体则需要根据程序或其它协议的定义,解析后在服务器上执行,以此来修改服务器上的资源。换句话说,PATCH请求是会执行某个程序的,如果重复提交,程序可能执行多次,对服务器上的资源就可能造成额外的影响,这就可以解释它为什么是非幂等的了。

    可能你还不能理解这点。我们举个例子

    PATCH   /tickets/12    # 更新ticket 12
    

    此时,我们服务端对方法的处理是,当调用一次方法,更新部分字段,将这条ticket记录的操作记录加一,这次,每次调用的资源是不是变了呢,所以它是有可能是非幂等的操作。

    HTTP DELETE方法

    HTTP DELETE方法用于删除资源,会将资源删除。

    DELETE  /tickets/12    # 删除ticekt 12
    

    调用一次和多次对资源产生影响是相同的,所以也满足幂等性。

    如何设计符合幂等性的高质量RESTful API

    HTTP GET方法 vs HTTP POST方法

    也许,你会想起一个面试题。HTTP请求的GET与POST方式有什么区别?你可能会回答到:GET方式通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。但是,我们现在从RESTful的资源角度来看待问题,HTTP GET方法是幂等的,所以它适合作为查询操作,HTTP POST方法是非幂等的,所以用来表示新增操作。

    但是,也有例外,我们有的时候可能需要把查询方法改造成HTTP POST方法。比如,超长(1k)的GET URL使用POST方法来替代,因为GET受到URL长度的限制。虽然,它不符合幂等性,但是它是一种折中的方案。

    HTTP POST方法 vs HTTP PUT方法

    对于HTTP POST方法和TTP PUT方法,我们一般的理解是POST表示创建资源,PUT表示更新资源。当然,这个是正确的理解。

    但是,实际上,两个方法都用于创建资源,更为本质的差别是在幂等性。HTTP POST方法是非幂等,所以用来表示创建资源,HTTP PUT方法是幂等的,因此表示更新资源更加贴切。

    HTTP PUT方法 vs HTTP PATCH方法

    此时,你看会有另外一个问题。HTTP PUT方法和HTTP PATCH方法,都是用来表述更新资源,它们之间有什么区别呢?我们一般的理解是PUT表示更新全部资源,PATCH表示更新部分资源。首先,这个是我们遵守的第一准则。根据上面的描述,PATCH方法是非幂等的,因此我们在设计我们服务端的RESTful API的时候,也需要考虑。如果,我们想要明确的告诉调用者我们的资源是幂等的,我的设计更倾向于使用 HTTP PUT 方法。

    转自: 梁桂钊的博客

    展开全文
  • 理解RESTful的幂等性,并且设计符合幂等规范的高质量RESTful API。 怎么理解幂等性 HTTP幂等方法,是指无论调用多少次都不会有不同结果的 HTTP 方法。不管你调用一次,还是调用一百次,一千次,结果都是相同的。 ...
  • restful设计

    2018-04-27 11:23:00
    这份工作之前也自认为写个几个restful的API了,这篇文章简单说说我认为的rest。。  很多人都知道restful是一种风格,我更喜欢说是一种对接口的规范。  举个例子我之前写API的时候(对前端),api.test....
  • 理解RESTful的幂等性,并且设计符合幂等规范的高质量RESTful API。 怎么理解幂等性 HTTP幂等方法,是指无论调用多少次都不会有不同结果的 HTTP 方法。不管你调用一次,还是调用一百次,一千次,结果都是相同的。...
  • 我所理解的restful风格

    2018-02-11 00:06:41
    第一次看到时,看几个例子,心想这个风格很好理解,貌似是蛮简单的规范嘛。最近又看到几篇文件,对restful有了更深理解。感觉网上很多帖子都是比较雷同,只能知其然,而不知其所以然,更不知道来龙去脉,所以不...
  • RestFul风格

    2021-05-27 21:07:34
    简化业务调用 ...但是新请求规范规定应该让请求尽可能变成无状态请求.(删除动词) 常见请求类型: 1.GET 2.POST 3.PUT 4.DELETE 优化: 1.新增用户 /user 请求类型: POST 2.修改用户 /user 请求类型.
  • RESTful API 最佳实践

    2019-04-11 10:08:30
    这是在网上看到比较好关于RESTful 资源,因为相对其他来说写简单易懂,用例子阐述RESTful 是什么,比较清晰,所以转发出来,方便大家阅览,希望对你有所帮助。原文链接:...
  • springboot restful风格

    千次阅读 2017-04-01 18:25:36
    今天稍微研究了下rest,不是写代码,只是看文字。...rest是一种规范,满足rest风格,就是restful风格框架。 体现在很多地方,刚好这几天在玩springboot,就用springboot来举例子吧。 基于之前,我分享springb
  • restful风格幂等

    2018-01-25 09:48:16
    理解RESTful的幂等性,并且设计符合幂等规范的高质量RESTful API。 怎么理解幂等性 HTTP幂等方法,是指无论调用多少次都不会有不同结果的 HTTP 方法。不管你调用一次,还是调用一百次,一千次,结果都是相同的。 ...
  • 仅API模块,用于扩展RESTful Web服务 可以按资源类型在列表中访问所有资源。 例子: URI:RESOURCE.json 包含:'list'键是单个资源对象数组。 每个单独资源都可以直接访问。 例子: URI:RESOURCE / ID....
  • 怎么RESTful理解幂等性

    2018-10-30 13:54:18
    理解RESTful的幂等性,并且设计符合幂等规范的高质量RESTful API。 怎么理解幂等性 HTTP幂等方法,是指无论调用多少次都不会有不同结果的 HTTP 方法。不管你调用一次,还是调用一百次,一千次,结果都是相同的。...
  • JAX-RS (JSR-311) 是为 Java EE 环境下 RESTful 服务能力提供一种规范。它能提供对传统基于 SOAP Web 服务一种可行替代。 在本文中,了解 JAX-RS 主要组件。本文用一个例子展示了一个企业如何使用 ...
  • 如何在Java中 提供 RESTful Web 服务

    千次阅读 2016-08-02 17:24:07
    JAX-RS (JSR-311) 是为 Java EE 环境下 RESTful 服务能力提供一种规范。它能提供对传统基于 SOAP Web 服务一种可行替代。 在本文中,了解 JAX-RS 主要组件。本文用一个例子展示了一个企业如何使用 JAX...
  • JAX-RS (JSR-311) 是为 Java EE 环境下 RESTful 服务能力提供一种规范。它能提供对传统基于 SOAP Web 服务一种可行替代。 在本文中,了解 JAX-RS 主要组件。本文用一个例子展示了一个企业如何使用 JAX...
  • 用Java技术创建RESTful Web服务

    千次阅读 2011-11-01 16:29:49
    JAX-RS (JSR-311) 是为 Java EE 环境下 RESTful 服务能力提供一种规范。它能提供对传统基于 SOAP Web 服务一种可行替代。 在本文中,了解 JAX-RS 主要组件。本文用一个例子展示了一个企业如何使用 JAX...
  • 前面几篇文章介绍了一些RESTful API设计方面的参考规范,这篇文章我们来看几个“不良”的例子,并以个人的实践总结为这一系列做个结尾。欢迎大家评论交流。一、几个“不良”示例 1. 查询当前活动状态 ** 请求:** ...
  • JAX-RS (JSR-311) 是为 Java EE 环境下 RESTful 服务能力提供一种规范。它能提供对传统基于 SOAP Web 服务一种可行替代。 在本文中,了解 JAX-RS 主要组件。本文用一个例子展示了一个企业如何使用 JAX...
  • JAX-RS (JSR-311) 是为 Java EE 环境下 RESTful 服务能力提供一种规范。它能提供对传统基于 SOAP Web 服务一种可行替代。 在本文中,了解 JAX-RS 主要组件。本文用一个例子展示了一个企业如何使用 ...
  • go开发之restful等幂性

    2020-12-18 16:27:56
    幂等性属于语义范畴,正如编译器只能帮助检查语法错误一样,HTTP规范也没有办法通过消息格式等语法手段来定义它,这可能是它不太受到重视原因之一。但实际上,幂等性是分布式系统设计中十分重要概念,而HTTP...
  • JAX-RS (JSR-311) 是为 Java EE 环境下 RESTful 服务能力提供一种规范。它能提供对传统基于 SOAP Web 服务一种可行替代。 在本文中,了解 JAX-RS 主要组件。本文用一个例子展示了一
  • RESTful一些注意事项、规范等 : ...后台controller接口的改造(举个put的例子): 之前 @RequestMapping(&amp;amp;quot;/path&amp;amp;quot;) @JsonBody public Object updateObject(...
  • Swagger是一个规范和完整框架,用于生成、描述、调用和可视化 RESTful 风格 Web 服务。总体目标是使客户端和文件系统作为服务器以同样速度来更新。文件方法,参数和模型紧密集成到服务器端代码,允许API来...

空空如也

空空如也

1 2 3 4
收藏数 63
精华内容 25
关键字:

规范restful的例子