jersey实现的RESTful

Resultful架构

1.JAX-RS标准 2.0

JAX-RSJAVA EE6引入的一个新技术。JAX-RSJAVA APIfor RESTful Web services,是一个Java编程语言的应用程序接口,支持按照表述性状态转移(REST)架构风格创建Web服务。JAX-RS标准中定义了目标、非目标和元素等内容。

目标:

1) 基于POJO(Plain Ordinary Java Object)JAX-RSAPI提供一组注解和相关的接口、类,并定义了POJO对象的生命周期和作用域,规定使用POJO来公布Web资源。

2) HTTP(超文本传输协议)为中心:JAX-RS采用HTTP协议,并提供清晰的HTTP和同意资源定位(URL)元素来映射相关的API类和注解。JAX-RSAPI不但支持通用的HTTP使用模式,还对WebDAVAtom等扩展协议提供灵活的支持。

3) 格式独立性:JAX-RS对传输数据的类型/格式的支持非常宽泛,允许在标准风格之上使用额外的数据类型。

4) 容器独立性:JAX-RS的应用可以部署在各种Servlet容器中,比如Tomcat/jetty,也可以部署在支持JAX-WS的容器中。

5) 内置于Java EEJAX-RSJava EE规范的一部分,它定义了在一个Java EE容器内的Web资源类的内部,如何使用Java EE的功能和组件。

非目标:

1) J2SE6.0之前版本的支持:JAX-RS中大量使用了注解,需要J2SE6.0以及更新的版本,因此不支持之前的版本。

2) 对服务的描述、注册和探测:JAX-RS没有定义也无需支持任何服务的描述,服务的注册和服务的探测。

3) HTTP协议栈:JAX-RS没有定义新的HTTP协议栈。承载JAX-RS应用的容器提供对HTTP的支持。

4) 数据类型/格式类:JAX-RSJAX-RS没有定义处理实体内容的类,它将这一类型的类交由使用JAX-RS的应用中的类去实现。

元素:

1) 资源类:使用JAX-RS注解来实现相关Web资源的Java类。

2) 根资源类:使用@Path注解,提供资源类树的根资源及其子资源的访问。资源类分为根资源类和子资源类。

3) 请求方法标识符:使用运行期注解@HttpMethod,用来标识处理资源的HTTP请求方法。该方法将被资源类的相应方法处理。

4) 资源方法:资源类中定义的方法,使用了请求方法标志符,用来处理相关资源的请求。

5) 子资源标志符:资源类中定义的方法,用来定位相关资源的子资源。

6) 子资源方法:资源类中定义的方法,用来处理相关资源的子资源的请求。

7) Providers:一种JAX-RS扩展接口的实现类,扩展了JAX-S运行期的能力。

8) Filter:一种用于过滤请求和相应的Provider

9) Entity Interceptor:一种用于处理拦截消息读写的Provider

10) Invocation:一种用于配置发布HTTP请求的客户端API对象。

11) WebTarger:一种使用URI标识的Invocation容器的对象。

12) Link:一种携带与数据的URI,包括媒体类型、关系和标题等。

其他JAX-RS标准的实现

除了使用jersey实现了JAX-RS标准,还有其他项目也实现了该标准,比如RESTEasyCXF项目。

其他REST实现

JAX-RSJava领域实现RESTWeb服务的标准规范,但不一定实现了REST式的Web服务同时也实现了JAX-RS标准。比如RestletSpring MVC项目在没有采用JAX-RS标准也实现了REST风格。

2.HTTP(超文本传输协议)

HTTP协议的请求主要由3部分组成:请求行、请求报头和请求体。其中某些请求报头和请求体的内容是可选的,请求报头和请求体之间需要用空行隔开。

2.1请求行

请求行只包含三个内容:方法、请求资源的URIHTTP版本,格式如下:

Method Request-URI HTTP-Version CRLF

其中Method除了常用的CURD操作外还有如下几种:HEADTRACEPATCHMOVECOPYLINKUNLINKWRAPPEDExtension-method

2.2请求报头

请求包头包含客户端传递请求的附加信息及客户端的自身信息。以下是常用的请求报头说明:

Accept:用于指定客户端所支持的信息类型,可重复指定。

Accpet-Charset:设置客户端可接收的字符集。

Accept-Encoding:设置文本压缩方法,值有gzipcompressidentity,优先级可以通过设置q0-1)值的大小。

Accept-language:指定客户端可以接受的自然语言。

Host:指定被请求资源所在的主机和端口号,缺省端口号为80

Connection:指定请求结束后是保持连接还是关闭链接。HTTP1.0下不支持该属性,HTTP1.1以上版本可以设置为keep-alive(默认)或者close

2.3响应状态码

1xx:指示信息,表示请求被接收或正在处理;

2xx:表示请求成功;

3xx:表示重定向;

400:表示语义有误,该请求无法被服务器理解;

401:当请求需要用户验证的资源时,并被拒绝;

402:为可能的需求而预留;

403:服务器拒绝提供服务,主要是由于用户权限不足导致的错误;

404:最常见的错误,未找到相应资源;

415:请求的实体类型不匹配。

5xx:表示服务器错误。

 


 

3REST API设计

3.1REST 统一接口

GET方法

@GET

Public Response getStore(@QueryParam (“uuid”) String uuid){

……

}

PUT方法:

@PUT

@Path(“/{uuid}”)

Public Response updateStore(@PathParam(“uuid”) String uuid,

StoreInfoRequest request){

…….

}

POST方法:

@POST

Public Response createStore(StoreInfoRequest request){

…….

}

DELETE方法:

@DELETE

Public Response deleteStore(@QueryParam(“uuid”) String uuid){

…….

}

JAX-RS标准定义了以上经常使用的几种方法以及@HEAD@OPTIONS,相对HTTP方法来说,还有许多没有JAX-RS中定义,不过可以通过WebDAV扩展方法HTTP进行扩展代码如下

@Targer({ElementType.Method})

@Retention(RetentionPolicy.RUNTIME)

@HttpMethod(value = ”MOVE”)

@Documented

Public @interface MOVE{}

这段代码定义了MOVE注解,使用@HttpMethod注解定义了名为MOVEHTTP扩展方法有了这个扩展方法,就可以在资源类中定义新的方法来支持扩展方法的请求。实例如下

@MOVE

Public Response MoveStore(@QueryParam(“uuid”) String uuid){

……

}

3.2资源定位

REST使用URI实现资源的定位因此URI设计Web服务至关重要分解如下

Scheme://host:port/path?quertParam

Scheme

指定协议名称,如HTTPFTP

Host

服务器地址

Port

服务提供的端口号

Path

资源地址,通过/’符号体现层次结构

?

分隔资源地址和查询参数

queryParam

查询参数

&

用来分隔查询条件的参数

,

用来分隔有次序的参数

用来分隔无次序的参数

 

@QueryParam注解:

注解组成urlqueryParam部分,可以通过它定义查询参数。格式如下:

@QueryParam(“uuid”) String uuid;

@QueryParam(“access_time”) Date accessTime;

……..

@PathParam注解

注解组成urlPath部分,它主和@PATH注解成对使用。其中@PATH注解的使用格式:{参数名称:正则表达式}。具体格式如下

@GET

@Path(“{start:\\d+}-{end:\\d+}”)

Public Response getStore(@PathParam(“start”) Long start,

@PathParam(“end”) Long end){

}

还有一种更加灵活的路径支持即路径区间(PathSegment),可以和正则表达式生成更加宽泛的路径地址。具体如下

@GET

@Path(“{region:.+}\store\{start:\\d+}-{end:\\d+}”)

Public Response getStore(@PathParam(“region”) List<PathSegment>  ps,

@PathParam(“start”) Long start,

@PathParam(“end”) Long end)) {

}

资源地址可以通过…/33/3301/store/2016-2017的形式访问

@FormParam注解

注解用于定义表单参数相应的REST方法处理请求实体媒体类型为Content-Typeapplication/x-www-form-urlencoded的请求。示例代码如下

@POST

Public Response updateUser(@FormParam(“account”) String account,

@FormParam(“pwd”) String pwd){

}

@Context注解

注解用于解析上下文参数,JAX-RS中的多种元素都可以通过@Context注解作为上下文参数使用。示例代码如下

Public Response getStore(@Context final Application application,

@Context final Request request,

@Context final UriInfo uriInfo,

@Context final Httpheaders headers){

}

3.3REST响应处理

返回类型

1) void

在返回值类型是void响应中,HTTP状态码为204

2) Response

返回值类型是Response的响应中,可以通过Responseentity方法定义实体类的实例。如果内容为空,返回的状态码也是204,正常200

3) GenericEntity

这部分内容和自定义类型类似。

4) 自定义类型

JDK的类都可以作为返回值的类型,并且自己定义的实体类可以作为返回值类型

处理异常

JAX-RS的异常和HTTP状态码对应表

HTTP状态码

异常类

400

  BadRequestExceotion

  401

  NotAuthorizedException

  403

  ForbiddenException

  404

  NotFoundException

  405

  NotAllowedException

  406

  NotAcceptableException

  415

  NotSupportedException

 

3.4内容协商

@Produces注解

注解@Produces用于定义方法的响应实体的数据类型可以定义一个多个,同时可以每种类型定义质量因素,质量因素取值范围从01之间。如果未定义质量因素,默认为1。案例如下:

@GET

@Produces(MedisType.APPLICATION_JSON_TYPE)

Public Response getStore(){

......

}

@Consumes

注解@Consumes用于定义方法的请求实体的数据类型。和@Produces注解功能相对,该注解的定义只用于JAX-RS匹配请求处理的方法,不做内容协商处理。如果匹配不到相应的类型,那么服务器会返回HTTP状态码415。示例代码如下:

@POST

@Consumes(“application/json;qs=.8”)

Public void createStore(){

......

}


4.REST 请求处理

4.1REST 过滤器

按照客户端向服务器进行请求操作时,请求操作流程先后顺序是:客户端请求过滤器->服务器请求过滤器->服务器响应过滤器->客户请求过滤器。这四种过滤器分别是ClientRequestFilterContainerRequestFilterContainerResponseFilter以及ClientResponseFilter

ClientRequestFilter:

客户端请求过滤接口。定义了filter方法,方法中带一个上下文类ClientRequestContext的参数。可以通过其实现类覆盖fliter方法实现过滤操作案例如下:

@Override

Public void filter(ClientRequestContext crc){

If(!crc.getHeaders().containsKey(“EVE-ACCESS-TOKEN”)){

……

}

}

ContainerRequestFilter:

服务器请求过滤接口。针对过滤切面,服务器请求过滤器接口ContainerRequestFilter的实现类可以定义预处理和后处理。默认采用的后处理方式,即先执行容器接收请求操作,接收并处理后执行过滤。要更改过滤顺序可以通过实现类上加@PreMarching注解改为预处理。案例如下:

@PreMatching

@Provider

@Service

@Priority(Priorities.AUTHENTICATION)

Public class RequestAuthenticationFilter implements ContainerRequestFilter{

@Override

Public void filter(ContainerRequestContext requestContext) throws IOExeption{

……

}

}

ContainerResponseFilter:

服务器响应过滤接口定义过滤方法filter()包含两个参数,除了前面的容器请求上下文类ContainerRequestContext,另一个是容器响应上下文类ContainerResponseContext。案例如下

@Provider

Public class ResponseAdditionalHeaderFilter implements ContainerResponse{

@Override

Public void filter(ContainerRequestContext reqContext,ContainerResponseContext resContext) throws IOException{

resContext.getHeaders().putSingle(Pragma”,”no-cache”);

……

}

}

ClientResponseFilter:

客户端响应过滤器。定义的过滤方法filter()也包含两个参数,与容器上下文类类似。

4.2 REST 拦截器

REST拦截器和过滤器都是在请求一响应模型进行切面处理。拦截器除了主要功能不同外,他的代码形式也不同。没有客户端和服务端的区分,通常读写成对。JAX-RS定义的拦截器接口是ReadInterceptor和WriteInterceptor。在jersey也提供了一些拦截器类,比如DeflateEncoderGZipEncoderContentEncoder类。

ReaderInterceptor:

拦截器接口定义拦截方法为aroundReadFrom(),该方法包含一个参数ReaderInterceptorContext,从中可以获得头信息、输入流和媒体类型等

WriterInterceptor:

拦截器接口定义的拦截方法是aroundWriteTo(),该方法也包含一个参数,即写拦截器上下文接口WriterInterceptorContext从中可以获得头信息、输出流以及媒体类型等。

ContentEncoder类

同时实现了读/写拦截器,覆盖了方法。具体如下:

@Override

Public final Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException{

String contentEncoding = context.getHeaders()

.getFirst(HttpHeaders.CONTENT_ENCODING);

        if (contentEncoding != null && getSupportedEncodings().contains(contentEncoding)) {

            context.setInputStream(decode(contentEncoding, context.getInputStream()));

        }

return context.proceed();

}’

4.3 异常处理 ExceptionMapper

通过实现ExceptionMapper接口并使用@Provider注解可以实现通用的面向切面的异常处理。示例如下:

@Provider

Public classResponseExceptionmapper implements

ExceptionMapper<BaseResponseException>{

@Override

Public Response toResponse(BaseResponseException exception){

……

}

}


5. REST 客户端

Client接口

Client接口是REST客户端的基本接口,用于和REST服务器通信Client被定义一种重量级的对象,其内部要管理客户端通信底层实现所需的各种对象,比如连接器解析器等。具体代码如下

ClientConfig config = new ClientConfig();

config.register(new AnotherClientFilter());

Client client = ClientBuilder.newClient(config);

WebTarget接口

WebTarget接口是为REST客户端实现资源定位的接口。通过WebTarger接口可以定义请求资源的具体地址、查询参数媒体类型等WebTarget可以链式设置属性,但每次返回的WebTarget都是新的对象,和StringBuffer类调用append()方法返回自身有一定区别。示例如下:

WebTarget webtarget = client.target(URI);

webtarget.path(“store”);

Webtarget.path(“single”);

webtarget.queryParam(uuid”,”1”);

Builder builder = webtarget.request(MediaType.APPLICATION_JSON_TYPE);

Invocation接口

Invocation接口是在完成资源定位配置后,向REST服务端发起请求的接口。BuilderInvocation的内部定义接口,并继承了SyncInvoker接口。SyncInvoker定义了Http标准的请求方法,如GETPUTPOSTDeleteTrace等。示例如下:

Invocation.Builder builder = webTarget.request(MediaType.APPLICATION_JSON_TYPE);

Store store = builder.get(Store.class);

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值