超越JAX-RS规范:Apache CXF搜索扩展
在今天的帖子中,我们将超越JAX-RS 2.0规范,并探索Apache CXF (流行的JAX-RS 2.0实现之一)为REST服务和API开发人员提供的有用扩展。 特别是,我们将讨论使用OData 2.0查询过滤器子集的搜索扩展。
简而言之,搜索扩展仅将某种过滤器表达式映射到一组匹配的类型化实体(Java类的实例)。 OData 2.0查询过滤器可能非常复杂,但是目前Apache CXF仅支持它们的子集:
操作员 | 描述 | 例 |
---|---|---|
当量 | 等于 | 雷德蒙德市 |
NE | 不相等 | 城市“伦敦” |
gt | 比...更棒 | 价格gt 20 |
ge | 大于或等于 | 价格GE 10 |
lt | 少于 | 价格lt 20 |
乐 | 小于或等于 | 价格100 |
和 | 逻辑与 | 价格le 200和价格gt 3.5 |
要么 | 逻辑或 | 价格le 3.5或价格gt 200 |
基本上,要配置和激活JAX-RS服务的搜索扩展,只需定义两个属性search.query.parameter.name和search.parser ,再加上一个附加提供程序SearchContextProvider :
@Configuration
public class AppConfig { @Bean( destroyMethod = "shutdown" )public SpringBus cxf() {return new SpringBus();}@Bean @DependsOn( "cxf" )public Server jaxRsServer() {final Map< String, Object > properties = new HashMap< String, Object >(); properties.put( "search.query.parameter.name", "$filter" );properties.put( "search.parser", new ODataParser< Person >( Person.class ) );final JAXRSServerFactoryBean factory = RuntimeDelegate.getInstance().createEndpoint( jaxRsApiApplication(), JAXRSServerFactoryBean.class );factory.setProvider( new SearchContextProvider() );factory.setProvider( new JacksonJsonProvider() );factory.setServiceBeans( Arrays.< Object >asList( peopleRestService() ) );factory.setAddress( factory.getAddress() ); factory.setProperties( properties );return factory.create();}@Bean public JaxRsApiApplication jaxRsApiApplication() {return new JaxRsApiApplication();}@Bean public PeopleRestService peopleRestService() {return new PeopleRestService();}
}
search.query.parameter.name定义用作过滤器的查询字符串参数的名称(我们将其设置为$ filter ),而search.parser定义用于解析过滤器表达式的解析器(我们设置将其与Person类一起参数化为ODataParser )。 ODataParser建立在出色的Apache Olingo项目之上, 该项目当前实现了OData 2.0协议(正在支持OData 4.0 )。
配置完成后,任何JAX-RS 2.0服务都可以通过注入上下文参数SearchContext来受益于搜索功能。 让我们通过定义REST服务来管理下面的Person类所代表的人员,来了解实际情况 :
public class Person {private String firstName;private String lastName;private int age;// Setters and getters here
}
该PeopleRestService将只允许使用来创建新的个人HTTP POST和使用进行搜索HTTP GET,下/搜索端点所列:
package com.example.rs;import java.util.ArrayList;
import java.util.Collection;import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;import org.apache.cxf.jaxrs.ext.search.SearchCondition;
import org.apache.cxf.jaxrs.ext.search.SearchContext;import com.example.model.Person;@Path( "/people" )
public class PeopleRestService {private final Collection< Person > people = new ArrayList<>();@Produces( { MediaType.APPLICATION_JSON } )@POSTpublic Response addPerson( @Context final UriInfo uriInfo,@FormParam( "firstName" ) final String firstName, @FormParam( "lastName" ) final String lastName,@FormParam( "age" ) final int age ) { final Person person = new Person( firstName, lastName, age );people.add( person );return Response.created( uriInfo.getRequestUriBuilder().path( "/search" ).queryParam( "$filter=firstName eq '{firstName}' and lastName eq '{lastName}' and age eq {age}" ).build( firstName, lastName, age ) ).entity( person ).build();}@GET@Path("/search")@Produces( { MediaType.APPLICATION_JSON } )public Collection< Person > findPeople( @Context SearchContext searchContext ) { final SearchCondition< Person > filter = searchContext.getCondition( Person.class );return filter.findAll( people );}
}
findPeople方法是我们正在寻找的方法。 由于Apache CXF所做的所有努力,该方法看起来非常简单:注入了SearchContext ,并从$ filter查询字符串参数中自动提取了过滤器表达式。 最后一部分是将过滤器应用于数据,在我们的例子中,它只是一个名为people的集合。 非常干净和直接。
让我们构建项目并运行它:
mvn clean package
java -jar target/cxf-search-extension-0.0.1-SNAPSHOT.jar
使用很棒的curl工具,让我们发出几个HTTP POST请求,以生成一些数据以针对以下条件运行过滤器查询:
> curl http://localhost:8080/rest/api/people -X POST -d "firstName=Tom&lastName=Knocker&age=16"
{"firstName": "Tom","lastName": "Knocker","age": 16
}> curl http://localhost:8080/rest/api/people -X POST -d "firstName=Bob&lastName=Bobber&age=23"
{"firstName": "Bob","lastName": "Bobber","age": 23
}> curl http://localhost:8080/rest/api/people -X POST -d "firstName=Tim&lastName=Smith&age=50"
{"firstName": "Tim","lastName": "Smith","age": 50
}
有了示例数据,让我们继续前进,提出几个不同的搜索条件,这些条件足够复杂,足以展示OData 2.0查询过滤器的强大功能:
- 查找所有名字为Bob的人 ($ filter = “ firsteq eq'Bob'” )
> curl -G -X GET http://localhost:8080/rest/api/people/search --data-urlencode $filter="firstName eq 'Bob'"
[{"firstName": "Bob","lastName": "Bobber","age": 23}
]
- 查找所有姓氏为Bobber或姓氏 Smith且名字不是Bob的人 ($ filter = “ lastName eq'Bobber'或(lastName eq'Smith'and firstName ne'Bob')” ))
> curl -G -X GET http://localhost:8080/rest/api/people/search --data-urlencode $filter="lastName eq 'Bobber' or (lastName eq 'Smith' and firstName ne 'Bob')"
[{"firstName": "Bob","lastName": "Bobber","age": 23},{ "firstName": "Tim","lastName": "Smith","age": 50}
]
- 查找其名字开始从字母T,谁所有的人在16岁以上($ =过滤器“名字EQ‘T *’和年龄GE 16”)
> curl -G -X GET http://localhost:8080/rest/api/people/search --data-urlencode $filter="firstName eq 'T*' and age ge 16"
[{"firstName": "Tom","lastName": "Knocker","age": 16},{"firstName": "Tim","lastName": "Smith","age": 50}
]
注意 :如果在类似Linux的环境中运行此命令,则可能需要使用\ $转义$符号,例如:
curl -X GET -G http:// localhost:8080 / rest / api / people / search –data-urlencode \ $ filter =“ firstName eq'Bob'”
目前, Apache CXF仅提供OData 2.0查询过滤器的基本支持,并保留了许多强大的表达式。 但是,一旦社区对使用此功能表示出足够的兴趣,就有承诺将其推进。
值得一提的是, OData 2.0查询过滤器不是唯一可用的选项。 搜索扩展还支持FIQL (提要项查询语言),而来自Apache CXF核心开发人员之一的精彩文章也对其进行了很好的介绍。
我认为Apache CXF的这一非常有用的功能可以通过为JAX-RS 2.0服务提供简单(而不是那么简单)的搜索功能来节省大量时间和精力。 如果适合您的应用程序需求,请尝试一下。
- 完整的项目源代码可在Github上获得 。
翻译自: https://www.javacodegeeks.com/2014/12/beyond-the-jax-rs-spec-apache-cxf-search-extension.html
超越JAX-RS规范:Apache CXF搜索扩展相关推荐
- Apache CXF框架简介
Apache CXF框架是一个开源的Web Services框架,它来源于两个开源项目--ObjectWeb Celtix(ESB产品)和Codehaus XFire(SOAP堆栈软件) Apache ...
- Apache CXF 3.0:CDI 1.1支持替代Spring
几周前刚刚发布了Apache CXF 3.0 ,该项目又迈出了满足JAX-RS 2.0规范要求的又一个重要步骤:与CDI 1.1集成. 在此博客文章中,我们将看几个有关Apache CXF 3.0和A ...
- apache-cxf 使用_使用Apache CXF进行Web服务学习
apache-cxf 使用 在我的最后几个项目中,我使用了Web服务,在某些地方创建它们并在其他地方使用它们. 我认为标准任务(例如创建客户端,创建Web服务等)非常简单,如果遇到问题,有足够的资源. ...
- Apache CXF 3.0:CDI 1.1支持可替代Spring
在几周前刚刚发布Apache CXF 3.0时 ,该项目又迈出了满足JAX-RS 2.0规范要求的又一个重要步骤:与CDI 1.1集成. 在此博客文章中,我们将看几个有关Apache CXF 3.0和 ...
- Apache CXF 3.0:JAX-RS 2.0和Bean验证1.1最终一起
即将发布的出色的Apache CXF框架3.0版 (当前处于里程碑2阶段)带来了许多有趣且有用的功能,越来越接近提供完整的JAX-RS 2.0支持. Bean Validation 1.1的支持是我们 ...
- 使用Apache CXF进行Web服务学习
在我的最后几个项目中,我使用了Web服务,在某些地方创建它们并在其他地方使用它们. 我觉得创建客户端,创建Web服务等标准任务非常简单,如果遇到问题,有足够的资源. 但是对于Web服务,这是一项琐碎的 ...
- cxf springmvc_拥抱模块化Java平台:Java 10上的Apache CXF
cxf springmvc 自Java 9发布最终将Project Jigsaw交付给大众以来,已经过去了整整一年的时间. 这是一段漫长的旅程,但是在那里,所以发生了什么变化? 这是一个很好的问题,答 ...
- java cxf_拥抱模块化Java平台:Java 10上的Apache CXF
java cxf Java 9版本终于将Project Jigsaw交付给大众已经过去了一年的时间. 这是一段漫长的旅程,但是在那里,所以发生了什么变化? 这是一个很好的问题,答案并不明显和直接. 总 ...
- 拥抱模块化Java平台:Java 10上的Apache CXF
Java 9版本终于将Project Jigsaw交付给大众已经过去了一年多的时间. 这是一段漫长的旅程,但是在那里,所以发生了什么变化? 这是一个很好的问题,答案并不明显和直接. 总的来说, 拼图项 ...
最新文章
- python读取.so_Python入门-编译安装Python3教程
- 聊聊HystrixEventNotifier
- uC/OS-II OS_TASK.C中有关任务管理的函数
- shell脚本if和switch语句编写案例
- 分布式系统面试 - 常见问题
- mysql数据库别名_MySQL数据库表名、列名、别名区分大小写的问题
- Coding WebIDE 开放支持第三方 Git 仓库
- redis事务冲突问题 - 乐观锁和悲观锁
- cocoapods 总结
- zmap扫描mysql_zmap/masscan 快速扫描网络
- 计算机科班比其他专业有多少优势呢?
- android商品标签,TextView首行缩进效果(商品标签)
- 禁用笔记本键盘和触摸板
- 一步一步教你网站采集规则
- 毕业设计 基于JSP动漫论坛的设计与实现
- 30ea是什么意思_数量单位EA是什么意思?EACH? 单位EA是什么意思
- 浙江污水处理厂数字孪生平台建模_三维激光扫描_吉优赛维三维可视化管理平台_三维建模_3D模型
- 二、C++反作弊对抗实战 (进阶篇 —— 16.如何实现游戏加速瞬移与对抗)
- 大数据权限管理组件Apache Ranger简介和原理
- 15min掌握正则表达式