资源描述
JAXRS.:REST式式Web服务服务API中新增中新增的和值得关注的功能的和值得关注的功能JAX-RS 2.0:REST 式式 Web 服务服务 API 中新增的和值得关注的功中新增的和值得关注的功能能John ClinganJava EE 和 GlassFish 产品经理JAX-RS 2.0 中的新增中的新增功能功能JAX-RS 回顾客户端 API通用配置异步处理过滤器/拦截器超媒体支持服务器端内容协商JAX-RS 用于用于 REST 式服务的式服务的 Java API基于 POJO 的资源类以 HTTP 为中心的编程模型实体格式独立性容器独立性包括在 Java EE 中注解驱动的标准API,用于帮助开发人员使用 Java 构建 REST 式 Web 服务和客户端JAX-RS 示例示例.POST Path(/withdrawal)Consumes(text/plain)Produces(application/json)public Money withdraw(PathParam(card)String card,QueryParam(pin)String pin,String amount)return getMoney(card,pin,amount);JAX-RS 注解(续)注解(续)注解注解目的目的PathParam绑定来自 URI 的值,例如PathParam(“id”)QueryParam绑定查询名称的值/查询值,例如QueryParam(“name”)CookieParam绑定 cookie 的值,例如CookieParam(“JSESSIONID”)HeaderParam绑定 HTTP 标头的值,例如HeaderParam(“Accept”)FormParam绑定 HTML 表单的值,例如FormParam(“name”)MatrixParam绑定矩阵参数的值,例如MatrixParam(“name”)JAX RS 2.0 客户端客户端 API客户端客户端 APIHTTP 客户端库太低级利用 JAX-RS 1.x API 中的提供商/概念主要实现引入的专用 API动机客户端客户端 API/Get instance of ClientClient client=ClientBuilder.newClient();/Get account balanceString bal=client.target(:/./atm/cardId/balance).resolveTemplate().queryParam(pin,9876).request(text/plain).get(String.class);客户端客户端 API/Withdraw some moneyMoneymoney=client.target(:/./atm/cardId/withdrawal).resolveTemplate().queryParam(pin,9876).request(application/json).post(text(50.0),Money.class);客户端客户端 APIInvocationinvocation1=client.target(:/./atm/cardId/balance).request(“text/plain”).buildGet();Invocationinvocation2=client.target(:/./atm/cardId/withdraw).request(application/json).buildPost(text(50.0);客户端客户端 APICollection invocations=Arrays.asList(inv1,inv2);Collection responses=Collections.transform(invocations,new F()public Responseapply(Invocationinvocation)return invocation.invoke(););客户端客户端 API/Create client and register MyProvider1Client client=ClientBuilder.newClient();client.register(MyProvider1.class);/Create atm target;inherits MyProvider1WebTargetatm=client.target(:/./atm);/Register MyProvider2atm.register(MyProvider2.class);/Create balance target;inherits MyProvider1,MyProvider2WebTarget balance=atm.path(”cardId/balance);/Register MyProvider3balance.register(MyProvider3.class);JAX RS 2.0通用配置通用配置通用配置通用配置 动机动机客户端客户端客户端 .register(JsonMessageBodyReader.class).register(JsonMessageBodyWriter.class).register(JsonpInterceptor.class).property().property().通用配置通用配置 动机动机服务器端public SetClass getClasses()SetClass classes=new HashSet();.classes.add(JsonMessageBodyReader.class);classes.add(JsonMessageBodyWriter.class);classes.add(JsonpInterceptor.class);.return classes;通用配置通用配置 解决方案解决方案客户端客户端客户端 .register(JsonMessageBodyReader.class).register(JsonMessageBodyWriter.class).register(JsonpInterceptor.class).property().property().JsonFeaturejf=new JsonFeature().enableCallbackQueryParam();client.register(jf);通用配置通用配置 解决方案解决方案服务器端public SetClassgetClasses().classes.add(JsonMessageBodyReader.class);classes.add(JsonMessageBodyWriter.class);classes.add(JsonpInterceptor.class);.public SetClassgetClasses().classes.add(JsonFeature.class);.通用配置通用配置public interface Configurable Configuration getConfiguration();Configurable property(String name,Object value);Configurable register(.);public interface Configuration Set getClasses();Map getContracts(Class componentClass);Set getInstances();Map getProperties();Object getProperty(String name);Collection getPropertyNames();boolean isEnabled(Feature feature);boolean isRegistered(Object component);.通用配置通用配置public interface Feature boolean configure(FeatureContext context);Feature 示例示例public void JsonFeature implements Feature public boolean configure(FeatureContext context)context.register(JsonMessageBodyReader.class).register(JsonMessageBodyWriter.class).register(JsonpInterceptor.class).property(CALLBACK_NAME,calbackName).property(USE_QUERY_PARAM,useQueryParam);return true;动态动态 Feature仅服务器端public interface DynamicFeature void configure(ResourceInfo ri,FeatureContext context);public interface ResourceInfo Method getResourceMethod();Class getResourceClass();JAX RS 2.0异步处理异步处理异步处理异步处理服务器 API分流 I/O 容器线程高效的异步事件处理利用 Servlet 3.x 异步支持(如果可用)客户端 API异步的请求调用 API异步处理异步处理StatelessPath(/async/longRunning)public class MyResource GET Asynchronous public void longRunningOp(SuspendedAsyncResponse ar)ar.setTimeoutHandler(new MyTimoutHandler();ar.setTimeout(15,SECONDS);final String result=executeLongRunningOperation();ar.resume(result);异步处理:服务器端异步处理:服务器端public interface AsyncResponse public void resume(Object/Throwable response);public void cancel();public void cancel(int/Date retryAfter);public boolean isSuspended();public boolean isCancelled();public boolean isDone();public void setTimeout(long time,TimeUnit unit);public void setTimeoutHandler(TimeoutHandler handler);public CollectionClass register(Class callback);public MapClass,CollectionClass register(Class callback,Class.callbacks);public CollectionClass register(Object callback);public MapClass,CollectionClass register(Object callback,Object.callbacks);异步处理:服务器端异步处理:服务器端Target(ElementType.PARAMETER)Retention(RetentionPolicy.RUNTIME)Documentedpublic interface Suspended public interface TimeoutHandler void handleTimeout(AsyncResponse asyncResponse);异步处理:服务器端异步处理:服务器端public interface CompletionCallback public void onComplete(Throwable throwable);public interface ConnectionCallback public void onDisconnect(AsyncResponse disconnected);异步处理:客户端异步处理:客户端WebTarget target=client.target(:/./balance”)/Start async call and register callbackFuture handle=target.request().async().get(new InvocationCallback()void complete(String balance)void failed(InvocationException e);/After waiting for too longif(!handle.isDone()handle.cancel(true);JAX RS 2.0过滤器过滤器/拦截器拦截器过滤器和拦截器过滤器和拦截器定制 JAX-RS 请求/响应处理用例:日志记录、压缩、安全性,等等针对客户端和服务器 API 而引入替换现有的专用支持动机过滤器过滤器和拦截器和拦截器非包装过滤器链过滤器不直接调用链中的下一个过滤器由 JAX-RS 运行时管理每个过滤器决定是继续还是中断链过滤每个传入/传出消息请求 请求ContainerRequestFilter,ClientRequestFilter响应 响应ContainerResponseFilter,ClientResponseFilter服务器端特性PreMatching、DynamicFeature过滤器过滤器和拦截器和拦截器日志记录过滤器示例public class RequestLoggingFilter implements ContainerRequestFilter Override public void filter(ContainerRequestContext requestContext)log(requestContext);/non-wrapping=returns without invoking the next filter .过滤器和过滤器和拦截器拦截器只有当发生实体处理时才会调用性能提升包装拦截器链每个拦截器都通过 context.proceed()调用链中的下一个拦截器拦截实体提供者MessageBodyReader 拦截器ReaderInterceptor接口MessageBodyWriter 拦截器WriterInterceptor接口过滤器和过滤器和拦截器拦截器Gzip 读取器拦截器示例public class GzipInterceptor implements ReaderInterceptor Override Object aroundReadFrom(ReaderInterceptorContext ctx)InputStream old=ctx.getInputStream();ctx.setInputStream(new GZIPInputStream(old);/wrapping=invokes the next interceptorObject entity=ctx.proceed();ctx.setInputStream(old);return entity;过滤器过滤器和和拦截器拦截器应用程序请求过滤过滤器器过滤过滤器器网络传输响应过滤过滤器器过滤过滤器器写入器写入器拦截器拦截器MBWMBR写入器写入器拦截器拦截器读取器读取器拦截器拦截器读取器读取器拦截器拦截器过滤器过滤器和和拦截器拦截器响应应用程序过滤过滤器器过滤过滤器器网络响应过滤过滤器器过滤过滤器器MBW写入器写入器拦截器拦截器写入器写入器拦截器拦截器过滤过滤器器过滤过滤器器请求请求读取器读取器拦截器拦截器MBR读取器读取器拦截器拦截器过滤过滤器器过滤过滤器器资源匹配PreMatching绑定和优先级绑定和优先级绑定将过滤器和拦截器与资源方法相关联服务器端概念优先级声明在执行链中的相对位置Priority(int priority)过滤器和拦截器共有的概念有作用域的绑定全局绑定静态NameBinding默认PreMatching动态DynamicFeature无绑定绑定NameBindingTarget(ElementType.TYPE,ElementType.METHOD)Retention(value=RetentionPolicy.RUNTIME)public interface Logged ProviderLoggedPriority(USER)public class LoggingFilter implements ContainerRequestFilter,ContainerResponseFilter 绑定绑定Path(/greet/name)Produces(text/plain)public class MyResourceClass Logged GET public String hello(PathParam(name)String name)return Hello +name;DynamicFeature 示例示例仅服务器端public void SecurityFeature implements DynamicFeature public boolean configure(ResourceInfo ri,FeatureContext context)String roles=getRolesAllowed(ri);if(roles!=null)context.register(new RolesAllowedFilter(roles);.JAX RS 2.0超媒体支持超媒体支持超媒体支持超媒体支持REST 原则标识符和链接HATEOAS(超媒体作为应用程序状态的引擎)链接类型:结构性链接过渡性链接超媒体支持超媒体支持Link:;rel=ship,;rel=cancel .:/./customers/11 :/./customers/11/address/1 :/./products/1112 .超媒体超媒体Link 和 LinkBuilder 类RFC 5988:Web 链接支持 ResponseBuilder 和过滤器中的链接过渡性链接(标头)支持手动结构性链接通过 Link.JaxbAdapter 和 Link.JaxbLink从客户端 API 中的链接创建资源目标超媒体超媒体/Producer API(server-side)Link self=Link.fromMethod(MyResource.class,”handleGet”).build();Link update=Link.fromMethod(MyResource.class,“handlePost”).rel(”update”).build();.Response res=Response.ok(order).link(:/./orders/1/ship,ship).links(self,update).build();超媒体超媒体Response order=client.target().request(application/xml).get();/Consumer API(client-side)Link shipmentLink=order.getLink(“ship”);if(shipmentLink!=null)Response shipment=client.target(shipmentLink).post(null);JAX RS 2.0服务器端内容协商服务器端内容协商服务器端内容协商服务器端内容协商GET :/./widgets2Accept:text/*;q=1Path(widgets2)public class WidgetsResource2 GET Produces(text/plain,text/html)public Widgets getWidget().服务器端内容协商服务器端内容协商GET :/./widgets2Accept:text/*;q=1Path(widgets2)public class WidgetsResource2 GET Produces(text/plain;qs=0.5,text/html;qs=0.75)public Widgets getWidget().JAX-RS 2.0 总结总结主要新功能客户端 API、过滤器和拦截器、异步资源、超媒体许多微小的 API 改进和扩展Bean 验证、请求/响应、URI 生成器、字符串转换器、BeanParam、MultivaluedHashMap、GenericTypeDI 集成、Java EE 安全性、MVC、延迟的高级客户端API其他资源其他资源阅读 JSR 343 规范:GlassFish 4.0Open Message Queue 5.0JAX-RS 2.0:REST 式式 Web 服务服务 API 中新增的和值得关注的功中新增的和值得关注的功能能John ClinganJava EE 和 GlassFish 产品经理JAX-RS 2.0 中的新增中的新增功能功能JAX-RS 回顾客户端 API通用配置异步处理过滤器/拦截器超媒体支持服务器端内容协商JAX-RS 用于用于 REST 式服务的式服务的 Java API基于 POJO 的资源类以 HTTP 为中心的编程模型实体格式独立性容器独立性包括在 Java EE 中注解驱动的标准API,用于帮助开发人员使用 Java 构建 REST 式 Web 服务和客户端JAX-RS 示例示例.POST Path(/withdrawal)Consumes(text/plain)Produces(application/json)public Money withdraw(PathParam(card)String card,QueryParam(pin)String pin,String amount)return getMoney(card,pin,amount);JAX-RS 注解(续)注解(续)注解注解目的目的PathParam绑定来自 URI 的值,例如PathParam(“id”)QueryParam绑定查询名称的值/查询值,例如QueryParam(“name”)CookieParam绑定 cookie 的值,例如CookieParam(“JSESSIONID”)HeaderParam绑定 HTTP 标头的值,例如HeaderParam(“Accept”)FormParam绑定 HTML 表单的值,例如FormParam(“name”)MatrixParam绑定矩阵参数的值,例如MatrixParam(“name”)JAX RS 2.0 客户端客户端 API客户端客户端 APIHTTP 客户端库太低级利用 JAX-RS 1.x API 中的提供商/概念主要实现引入的专用 API动机客户端客户端 API/Get instance of ClientClient client=ClientBuilder.newClient();/Get account balanceString bal=client.target(:/./atm/cardId/balance).resolveTemplate().queryParam(pin,9876).request(text/plain).get(String.class);客户端客户端 API/Withdraw some moneyMoneymoney=client.target(:/./atm/cardId/withdrawal).resolveTemplate().queryParam(pin,9876).request(application/json).post(text(50.0),Money.class);客户端客户端 APIInvocationinvocation1=client.target(:/./atm/cardId/balance).request(“text/plain”).buildGet();Invocationinvocation2=client.target(:/./atm/cardId/withdraw).request(application/json).buildPost(text(50.0);客户端客户端 APICollection invocations=Arrays.asList(inv1,inv2);Collection responses=Collections.transform(invocations,new F()public Responseapply(Invocationinvocation)return invocation.invoke(););客户端客户端 API/Create client and register MyProvider1Client client=ClientBuilder.newClient();client.register(MyProvider1.class);/Create atm target;inherits MyProvider1WebTargetatm=client.target(:/./atm);/Register MyProvider2atm.register(MyProvider2.class);/Create balance target;inherits MyProvider1,MyProvider2WebTarget balance=atm.path(”cardId/balance);/Register MyProvider3balance.register(MyProvider3.class);JAX RS 2.0通用配置通用配置通用配置通用配置 动机动机客户端客户端客户端 .register(JsonMessageBodyReader.class).register(JsonMessageBodyWriter.class).register(JsonpInterceptor.class).property(“jsonp.callback.name”,“callback”).property(“jsonp.callback.queryParam”,“true”).通用配置通用配置 动机动机服务器端public class MyApp extends javax.ws.rs.core.Application public SetClass getClasses()SetClass classes=new HashSet();.classes.add(JsonMessageBodyReader.class);classes.add(JsonMessageBodyWriter.class);classes.add(JsonpInterceptor.class);.return classes;通用配置通用配置 解决方案解决方案客户端客户端客户端 .register(JsonMessageBodyReader.class).register(JsonMessageBodyWriter.class).register(JsonpInterceptor.class).property(“jsonp.callback.name”,“callback”).property(“jsonp.callback.queryParam”,“true”).JsonFeaturejf=new JsonFeature().enableCallbackQueryParam();client.register(jf);通用配置通用配置 解决方案解决方案服务器端public SetClassgetClasses().classes.add(JsonMessageBodyReader.class);classes.add(JsonMessageBodyWriter.class);classes.add(JsonpInterceptor.class);.public SetClassgetClasses().classes.add(JsonFeature.class);.通用配置通用配置public interface Configurable Configuration getConfiguration();Configurable property(String name,Object value);Configurable register(.);public interface Configuration Set getClasses();Map getContracts(Class componentClass);Set getInstances();Map getProperties();Object getProperty(String name);Collection getPropertyNames();boolean isEnabled(Feature feature);boolean isRegistered(Object component);.通用配置通用配置public interface Feature boolean configure(FeatureContext context);Feature 示例示例public void JsonFeature implements Feature public boolean configure(FeatureContext context)context.register(JsonMessageBodyReader.class).register(JsonMessageBodyWriter.class).register(JsonpInterceptor.class).property(CALLBACK_NAME,calbackName).property(USE_QUERY_PARAM,useQueryParam);return true;动态动态 Feature仅服务器端public interface DynamicFeature void configure(ResourceInfo ri,FeatureContext context);public interface ResourceInfo Method getResourceMethod();Class getResourceClass();JAX RS 2.0异步处理异步处理异步处理异步处理服务器 API分流 I/O 容器线程高效的异步事件处理利用 Servlet 3.x 异步支持(如果可用)客户端 API异步的请求调用 API异步处理异步处理StatelessPath(/async/longRunning)public class MyResource GET Asynchronous public void longRunningOp(SuspendedAsyncResponse ar)ar.setTimeoutHandler(new MyTimoutHandler();ar.setTimeout(15,SECONDS);final String result=executeLongRunningOperation();ar.resume(result);异步处理:服务器端异步处理:服务器端public interface AsyncResponse public void resume(Object/Throwable response);public void cancel();public void cancel(int/Date retryAfter);public boolean isSuspended();public boolean isCancelled();public boolean isDone();public void setTimeout(long time,TimeUnit unit);public void setTimeoutHandler(TimeoutHandler handler);public CollectionClass register(Class callback);public MapClass,CollectionClass register(Class callback,Class.callbacks);public CollectionClass register(Object callback);public MapClass,CollectionClass register(Object callback,Object.callbacks);异步处理:服务器端异步处理:服务器端Target(ElementType.PARAMETER)Retention(RetentionPolicy.RUNTIME)Documentedpublic interface Suspended public interface TimeoutHandler void handleTimeout(AsyncResponse asyncResponse);异步处理:服务器端异步处理:服务器端public interface CompletionCallback public void onComplete(Throwable throwable);public interface ConnectionCallback public void onDisconnect(AsyncResponse disconnected);异步处理:客户端异步处理:客户端WebTarget target=client.target(:/./balance”)/Start async call and register callbackFuture handle=target.request().async().get(new InvocationCallback()void complete(String balance)void failed(InvocationException e);/After waiting for too longif(!handle.isDone()handle.cancel(true);JAX RS 2.0过滤器过滤器/拦截器拦截器过滤器和拦截器过滤器和拦截器定制 JAX-RS 请求/响应处理用例:日志记录、压缩、安全性,等等针对客户端和服务器 API 而引入替换现有的专用支持动机过滤器过滤器和拦截器和拦截器非包装过滤器链过滤器不直接调用链中的下一个过滤器由 JAX-RS 运行时管理每个过滤器决定是继续还是中断链过滤每个传入/传出消息请求 请求ContainerRequestFilter,ClientRequestFilter响应 响应ContainerResponseFilter,ClientResponseFilter服务器端特性PreMatching、DynamicFeat
展开阅读全文