我想出了如何仅使用泽西岛来解决我的问题。显然,没有办法将请求的URI与在调用该方法之前匹配的方法相匹配,至少在泽西岛1.x中是这样。但是,我能够使用 ResourceFilterFactory
为每个单独的资源方法创建一个 - 这样这些筛选器就可以提前了解目标方法。ResourceFilter
这是我的解决方案,包括对所需查询参数的验证(使用Guava和JSR 305):
public final class ValidationFilterFactory implements ResourceFilterFactory {
@Override
public List<ResourceFilter> create(AbstractMethod abstractMethod) {
//keep track of required query param names
final ImmutableSet.Builder<String> requiredQueryParamsBuilder =
ImmutableSet.builder();
//get the list of params from the resource method
final ImmutableList<Parameter> params =
Invokable.from(abstractMethod.getMethod()).getParameters();
for (Parameter param : params) {
//if the param isn't marked as @Nullable,
if (!param.isAnnotationPresent(Nullable.class)) {
//try getting the @QueryParam value
@Nullable final QueryParam queryParam =
param.getAnnotation(QueryParam.class);
//if it's present, add its value to the set
if (queryParam != null) {
requiredQueryParamsBuilder.add(queryParam.value());
}
}
}
//return the new validation filter for this resource method
return Collections.<ResourceFilter>singletonList(
new ValidationFilter(requiredQueryParamsBuilder.build())
);
}
private static final class ValidationFilter implements ResourceFilter {
final ImmutableSet<String> requiredQueryParams;
private ValidationFilter(ImmutableSet<String> requiredQueryParams) {
this.requiredQueryParams = requiredQueryParams;
}
@Override
public ContainerRequestFilter getRequestFilter() {
return new ContainerRequestFilter() {
@Override
public ContainerRequest filter(ContainerRequest request) {
final Collection<String> missingRequiredParams =
Sets.difference(
requiredQueryParams,
request.getQueryParameters().keySet()
);
if (!missingRequiredParams.isEmpty()) {
final String message =
"Required query params missing: " +
Joiner.on(", ").join(missingRequiredParams);
final Response response = Response
.status(Status.BAD_REQUEST)
.entity(message)
.build();
throw new WebApplicationException(response);
}
return request;
}
};
}
@Override
public ContainerResponseFilter getResponseFilter() {
return null;
}
}
}
并且 已在泽西岛注册为 servlet 的初始化参数:ResourceFilterFactory
web.xml
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>my.package.name.ValidationFilterFactory</param-value>
</init-param>
在启动时,为 Jersey 检测到的每个资源方法调用。ValidationFilterFactory.create
感谢这篇文章让我走上了正确的轨道:我如何在泽西岛容器ResponseFilter中获取资源注释