47.2.2. 注入请求 URI 中的数据
概述
设计 RESTful Web 服务的最佳实践之一是,每个资源应具有唯一的 URI。开发人员可以使用这个原则来为底层资源实施提供良好的信息。在为资源设计 URI 模板时,开发人员可以构建模板,使其包含可注入到资源实施中的参数信息。开发人员还可利用查询和列表参数,将信息馈送到资源实施中。
从 URI 的路径获取数据
获取资源信息的更常见机制之一是通过为资源创建 URI 模板时使用的变量。这可以通过 javax.ws.rs.PathParam
注解来完成。@PathParam
注释具有一个用于标识要注入数据的 URI 模板变量的单个参数。
在 例 47.1 “注入 URI 模板变量的数据” 中,@PathParam
注释指定 URI 模板变量 颜色
的值被注入到 itemColor
字段中。
例 47.1. 注入 URI 模板变量的数据
import javax.ws.rs.Path; import javax.ws.rs.PathParam ... @Path("/boxes/{shape}/{color}") class Box { ... @PathParam("color") String itemColor; ... }
@PathParam
注释支持的数据类型与 “支持的数据类型”一节 中描述的数据类型不同。@PathParam
注释注入数据的实体必须是以下类型之一:
PathSegment
该值将是路径匹配部分的最后一个部分。
List<PathSegment>
该值将是与指定模板参数匹配的路径网段对象列表。
-
原语,如
int
、char
或long
-
具有 buildor 的对象,它接受单个
String
参数 -
具有接受单个
String
参数的静态valueOf()
方法的对象
使用查询参数
在 Web 上传递信息的一种常见方法是使用 URI 中的 查询参数。查询参数出现在 URI 的末尾,并通过问号(?
)与 URI 的资源位置部分隔开。它们由一个或多个名称值对组成,其中 name 和 value 用等号(=
)分开。当指定多个查询参数时,对通过分号()或 符号(和)相互分离。
例 47.2 “带有查询字符串的 URI” 显示带有查询参数的 URI 的语法。
例 47.2. 带有查询字符串的 URI
http://fusesource.org?name=value;name2=value2;...
您可以使用 分号 或 符号来分隔查询参数,但不能两者。
javax.ws.rs.QueryParam
注解提取查询参数的值,并将其注入 JAX-RS 资源。该注释采用单个参数来标识从中获取并注入到指定字段、bean 属性或参数中的查询参数。@QueryParam
注释支持 “支持的数据类型”一节 中描述的类型。
例 47.3 “使用查询参数中的数据的资源方法” 显示一个资源方法,它将查询参数 id
的值注入到方法的 id
参数中。
例 47.3. 使用查询参数中的数据的资源方法
import javax.ws.rs.QueryParam; import javax.ws.rs.PathParam; import javax.ws.rs.POST; import javax.ws.rs.Path; ... @Path("/monstersforhire/") public class MonsterService { ... @POST @Path("/{type}") public void updateMonster(@PathParam("type") String type, @QueryParam("id") String id) { ... } ... }
要处理 HTTP POST
到 /monstersforhire/daikaiju?id=jonas the updateMonster()
方法 的类型
,并将 id
设置为 jonas
。
使用列表参数
URI 列表参数(如 URI 查询参数)是 name/value 对,可以提供附加信息选择资源。与查询参数不同,列表参数可能会出现 URI 中的任何位置,它们使用分号(;
)与 URI 的层次路径片段分离。/mostersforhire/daikaiju;id=jonas 有一个称为 id
和 /monstersforhire/japan;type=daikaiju/flying;wingspan=40 有两个列表参数,即 type
和 wingspan
。
在计算资源 URI 时,不会评估列表参数。因此,用于定位适当的资源以处理请求 URI /monstersforhire/japan;type=daikaiju/flying;wingspan=40 是 /monstersforhire/japan/flying。
matrix 参数的值通过 javax.ws.rs.MatrixParam
注解注入字段、参数或 bean 属性。该注释采用单个参数来标识从中提取值并注入到指定字段、bean 属性或参数的 matrix 参数的名称。@MatrixParam
注释支持 “支持的数据类型”一节 中描述的类型。
例 47.4 “使用列表参数中的数据的资源方法” 显示资源方法,它将列表参数值注入方法参数和 id
。
例 47.4. 使用列表参数中的数据的资源方法
import javax.ws.rs.MatrixParam; import javax.ws.rs.POST; import javax.ws.rs.Path; ... @Path("/monstersforhire/") public class MonsterService { ... @POST public void updateMonster(@MatrixParam("type") String type, @MatrixParam("id") String id) { ... } ... }
要处理 HTTP POST
到 /monstersforhire;type=daikaiju;id=whale,updateMonster()
方法 的类型
被设置为 daikaiju
,并将 id
设置为 whale
。
JAX-RS 一次性评估 URI 中的所有列表参数,因此无法对 URI 中的列表参数位置实施约束。例如 /monstersforhire/japan;type=daikaiju/flying;wingspan=40 , /monstersforhire/japan/flying;type=daikaiju;wspan=40, 和 /monstersforre/japan; type=daikaiju;wingspan=40/flying 均被视为使用 JAX-RS API 实施的 RESTful Web 服务。
禁用 URI 解码
默认情况下,所有请求 URI 被解码。因此,URI /monster/night%20stalker 和 URI /monster/night stalker 具有等同的。自动 URI 解码可让您轻松在 ASCII 字符集外发送字符作为参数。
如果您不想自动解码 URI,您可以使用 javax.ws.rs.Encode 注解来
取消激活 URI 解码。该注解可用于在以下级别上取消激活 URI 解码:
-
类级别 - 使用
@En
code 注释处理类可取消激活类中所有参数、字段和 bean 属性的 URI 解码。 -
方法级别 - 使用
@En
code 注释处理方法可取消激活类所有参数的 URI 解码。 -
参数/字段级别-使用
@En
code 注释停用类所有参数的 URI 解码参数或字段。
例 47.5 “禁用 URI 解码” 显示 getMonster()
方法不使用 URI 解码的资源。addMonster()
方法只禁用 type
参数的 URI decoding。
例 47.5. 禁用 URI 解码
@Path("/monstersforhire/") public class MonsterService { ... @GET @Encoded @Path("/{type}") public Monster getMonster(@PathParam("type") String type, @QueryParam("id") String id) { ... } @PUT @Path("/{id}") public void addMonster(@Encoded @PathParam("type") String type, @QueryParam("id") String id) { ... } ... }
错误处理
如果尝试使用其中一个 URI 注入注解注入数据时,会产生一个错误,则将生成 WebApplicationException 异常嵌套原始异常。WebApplicationException 异常的状态设置为 404
。