Pau*_*ora 18 java jersey jersey-1.0
我正在尝试实现一个ContainerRequestFilter对请求参数进行自定义验证的方法.我需要查找将与URI匹配的资源方法,以便我可以从方法的参数中删除自定义注释.
根据这个答案,我应该能够注入ExtendedUriInfo然后使用它来匹配方法:
public final class MyRequestFilter implements ContainerRequestFilter {
@Context private ExtendedUriInfo uriInfo;
@Override
public ContainerRequest filter(ContainerRequest containerRequest) {
System.out.println(uriInfo.getMatchedMethod());
return containerRequest;
}
}
Run Code Online (Sandbox Code Playgroud)
但getMatchedMethod显然会返回null,直到实际调用该方法为止(此时对我来说进行验证为时已晚).
Method在调用资源方法之前,如何检索与给定URI匹配的内容?
对于那些感兴趣的人,我正在尝试推出我自己的必需参数验证,如JERSEY-351中所述.
Chr*_*ler 20
实际上,您应该尝试注入ResourceInfo自定义请求过滤器.我已经尝试过RESTEasy,它在那里工作.优点是您针对JSR接口而不是Jersey实现进行编码.
public class MyFilter implements ContainerRequestFilter
{
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext requestContext)
throws IOException
{
Method theMethod = resourceInfo.getResourceMethod();
return;
}
}
Run Code Online (Sandbox Code Playgroud)
Pau*_*ora 13
我想出了如何使用Jersey解决我的问题.显然没有办法将请求的URI与调用该方法之前匹配的方法相匹配,至少在Jersey 1.x中是这样.但是,我能够使用a 为每个单独的资源方法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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且在ResourceFilterFactoryJersey中注册为servlet的init参数web.xml:
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>my.package.name.ValidationFilterFactory</param-value>
</init-param>
Run Code Online (Sandbox Code Playgroud)
在启动时,ValidationFilterFactory.create将调用Jersey检测到的每种资源方法.
感谢这篇文章让我走上正轨:如何在Jersey ContainerResponseFilter中获取资源注释