JAX-RS入门 三 :细节
一、若希望一个Java类能够处理REST请求,则这个类必须至少添加一个@Path("/")的annotation;对于方法,这个annotation是可选的,如果不添加,则继承类的定义。
二、一个方法上只有添加了某个Http Method的annotation,例如@GET,才有资格处理请求。
三、@Path里的值可以是一个复杂的表达式,例如@Path("{id}") ,其中 {id}表达式代码了一个模板参数;一个模板参数是一个定义在@Path里的通配符,它以 { 开始,中间是一堆字母和数字的混合串(不能包含 / 字符),以} 结尾。又如: @Path("{firstName}-{lastName}") .
四、@Path也支持正则表达式,例如: @Path("{id: \\d+}") ,其中 \\d+ 表示一个数字。格式为: A : B
五、可以自定http method的annotation,具体参考已经有的实现,例如@GET的实现:
- @Target({ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- @HttpMethod(HttpMethod.GET)
- public @interface GET {
- }
其中HttpMethod的实现为:
- @Target({ElementType.ANNOTATION_TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface HttpMethod {
- /**
- * HTTP GET method
- */
- public static final String GET="GET";
- /**
- * HTTP POST method
- */
- public static final String POST="POST";
- /**
- * HTTP PUT method
- */
- public static final String PUT="PUT";
- /**
- * HTTP DELETE method
- */
- public static final String DELETE="DELETE";
- /**
- * HTTP HEAD method
- */
- public static final String HEAD="HEAD";
- /**
- * HTTP OPTIONS method
- */
- public static final String OPTIONS="OPTIONS";
- /**
- * Specifies the name of a HTTP method. E.g. "GET".
- */
- String value();
- }
因此,可以如下自定义新的http 请求方法:
- @Target({ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- @HttpMethod("LOCK")
- public @interface LOCK {
- }
注:请不要试图重写HttpMethod annotation。
六、Path的优先级规则
- 首先检查匹配的字符的个数,匹配的个数越多越优先
- 其次检查内嵌的模板表达式的个数,个数越多越优先
- 最后是非缺省模板表达式的个数;缺省模板即未定义正则表达式的模板
例如以下顺利:
- 1 /customers/{id}/{name}/address
- 2 /customers/{id : .+}/address
- 3 /customers/{id}/address
- 4 /customers/{id : .+}
如果以上匹配不能解决你的问题,那多半是因为你的设计过于复杂,需要重新审视。
七、允许、保留和需要转意的字符
- 所以有 a-z、A-Z、0-9 都被允许
- 所有: _-!.~'()* 都被允许
- 所有: ,;:$&+=?/[]@ 都是保留字符 (需要转意)
- 所有其他字符需要用 % 进行转意;格式为 %HH (%加两个十六进制数)
注:如果Path中uri的表达式包含有需要转意的字符,JAX-RS会自动进行转意;否则会视之为已经进行了URL的encoding。
八、Matrix Param
Matrix Param是一个嵌在URI字符串中的name-value对,例如:
http://example.cars.com/mercedes/e55;color=black/2006
Matrix Param用于修饰特定的片段,如上修饰e55片段;不同于Query Param,用于修饰整个URI资源。
Matrix Param不出现在@Path的表达式中,例如以上URI对应的@Path的表达式可能是:@Path("/e55/{year}")。
但是可以用@MatrixParam annotation来取得Matrix Param的值,例如:@MatrixParam("color")
九、Subresource Locators
Subresources Locators是指一个指定了@Path annotation,但未指定HttpMethod的annotation,例如@GET,的Java方法。这个方法返回一个含有JAX-RS annotation的REST Service对象,这个对象知道怎么去分发剩余的请求。
例如:
- @Path("/customers")
- public class CustomerDatabaseResource {
- @Path("{database}-db")
- public CustomerResource getDatabase(@PathParam("database") String db) {
- // find the instance based on the db parameter
- CustomerResource resource = locateCustomerResource(db);
- return resource;
- }
- protected CustomerResource locateCustomerResource(String db) {
- ...
- }
- }
其中CustomerResource可能是:
- public class CustomerResource {
- private Map<Integer, Customer> customerDB =
- new ConcurrentHashMap<Integer, Customer>();
- private AtomicInteger idCounter = new AtomicInteger();
- @POST
- @Consumes("application/xml")
- public Response createCustomer(InputStream is) {
- ...
- }
- @GET
- @Path("{id}")
- @Produces("application/xml")
- public StreamingOutput getCustomer(@PathParam("id") int id) {
- ...
- }
- @PUT
- @Path("{id}")
- @Consumes("application/xml")
- public void updateCustomer(@PathParam("id") int id, InputStream is) {
- ...
- }
- }
因为CustomerResource 并不打算做一个Service暴露,所以在类上没有添加@Path的annotation。
十、完全动态分发
所谓完全分发,就是实现类可以是任意类,例如上面的CustomerDatabaseResource的getDatabase()方法的实现可以改为:
- @Path("/customers")
- public class CustomerDatabaseResource {
- protected CustomerResource europe = new CustomerResource();
- protected FirstLastCustomerResource northamerica =
- new FirstLastCustomerResource();
- @Path("{database}-db")
- public Object getDatabase(@PathParam("database") String db) {
- if (db.equals("europe")) {
- return europe;
- }
- else if (db.equals("northamerica")) {
- return northamerica;
- }
- else return null;
- }
- }
这里返回值是一个Object,已经不再局限于CustomerResource类了。JAX-RS会检查这个实例,以决定怎么分发请求。
JAX-RS入门 三 :细节的更多相关文章
- 脑残式网络编程入门(三):HTTP协议必知必会的一些知识
本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...
- 转 Python爬虫入门三之Urllib库的基本使用
静觅 » Python爬虫入门三之Urllib库的基本使用 1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器 ...
- redis入门(三)
目录 redis入门(三) 目录 前言 事务 原理 Lua脚本 安装 脚本命令 集群搭建工具 redis-trib.rb redis官方集群搭建 集群横向扩展 故障转移 redis管理 参考文档 re ...
- 【原创】NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
前言 本文将演示一个iOS客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo.服务端将分别用MINA2和Netty4进行实现,而通信时服务端你只需选其一就行了.同 ...
- Swift语法基础入门三(函数, 闭包)
Swift语法基础入门三(函数, 闭包) 函数: 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被用于“调用”函数 格式: ...
- Thinkphp入门三—框架模板、变量(47)
原文:Thinkphp入门三-框架模板.变量(47) [在控制器调用模板] display() 调用当前操作名称的模板 display(‘名字’) 调用指定名字的模板文件 控制器调用模板四种方式 ...
- DevExpress XtraReports 入门三 创建 Master-Detail(主/从) 报表
原文:DevExpress XtraReports 入门三 创建 Master-Detail(主/从) 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用 ...
- 微服务(入门三):netcore ocelot api网关结合consul服务发现
简介 api网关是提供给外部调用的统一入口,类似于dns,所有的请求统一先到api网关,由api网关进行指定内网链接. ocelot是基于netcore开发的开源API网关项目,功能强大,使用方便,它 ...
- 3.Python爬虫入门三之Urllib和Urllib2库的基本使用
1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS.CSS ...
- C#基础入门 三
C#基础入门 三 类 类使用class关键字进行声明,前面加一个访问修饰符,public class car{} 访问修饰符:修师傅可以用来修饰类和类成员等,控制它们的可见度 修饰符关键字分别为:pu ...
随机推荐
- (转载)根据数据字典表定义的表结构,生成创建表的SQL语句
<来源网址:http://www.delphifans.com/infoview/Article_221.html>根据数据字典表定义的表结构,生成创建表的SQL语句 //1. 类名:T ...
- Kakfa揭秘 Day4 Kafka中分区深度解析
Kakfa揭秘 Day4 Kafka中分区深度解析 今天主要谈Kafka中的分区数和consumer中的并行度.从使用Kafka的角度说,这些都是至关重要的. 分区原则 Partition代表一个to ...
- FragmentActivity和Activity的具体区别在哪里
fragment是3.0以后的东西,为了在低版本中使用fragment就要用到android-support-v4.jar兼容包,而fragmentActivity就是这个兼容包里面的,它提供了操作f ...
- Linux安装oracle 10g常见问题之——ORA-01078,LRM-00109,ORA-01102
[oracle@toughhou database]$ sqlplus /nolog SQL> conn / as sysdba SQL> startup ORA-01078: failu ...
- EXTJS4.2 控件之Grid 根据数据源某列数据不同绑定不同的控件setEditor
Grid 根据数据源某列数据不同绑定不同的控件,例如:文本框和下拉框 主要代码写在grid的 plugins: [rowEditing],下面这是定义的rowEditing对象,这里面的要定义成 E ...
- EXTJS 4.2 资料 控件之btn设置可否点击
1.下面是一个btn按钮的代码,默认不可以点击 { id: 'skipStep3', disabled: true,//默认不可点击 text: "跳转第三步", handler: ...
- Mac - 更新 Ruby
因为准备在项目中使用bootstrap,在安装bootstrap过程中提示需要Ruby的版本在1.9.2以上,而目前使用的Ruby版本是Mac系统自带的1.8.7.所以需要对Ruby进行升级.这里使用 ...
- Linux必学的60个命令
inux必学的60个命令Linux提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令.要想 ...
- PAT-乙级-1007. 素数对猜想 (20)
1007. 素数对猜想 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 让我们定义 dn 为:dn = ...
- Java在Windows的环境配置
JDK环境变量配置的步骤如下: 1.我的电脑-->属性-->高级-->环境变量. 2.配置用户变量: 系统变量 a.新建 JAVA_HOME C:\Program Files\Jav ...