gpt4 book ai didi

java - 使用 CXF 作为实现限制查询参数 JAX-RS 的值

转载 作者:行者123 更新时间:2023-11-30 07:54:08 24 4
gpt4 key购买 nike

我有一个用例,我需要限制可以作为查询参数传递的值。

@Path("/foo")
public interface Foo {

@GET
@Path("/details/id/{id}")
void getFooDetails(@PathParam("id") String id, @QueryParam("sort") String sortDirection);
}

public class FooImpl {
public void getFooDetails(String id, String sortDir) {
//Implementation
}
}

在上面的示例中,我想限制可以通过 API 传递给 ASC, DESC 的查询参数 sort 的值。

是否有任何现有的 CXF 注释可用于限制参数的值?我还没有找到,所以我尝试了以下解决方案。

我的方法:

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ValueSet {

String[] allowedValues();
}

修改后的界面是这样的

@Path("/foo")
public interface Foo {

@GET
@PathParam("/details/id/{id}")
void getFooDetails(@PathParam("id") String id, @QueryParam("sort") @ValueSet(allowedValues = {"ASC", "DESC"}) String sortDirection);
}

我编写了一个 CXF 拦截器来拦截 API 调用。我使用反射来处理 FooImpl.getFooDetails 参数。但我面临的问题是拦截器查看 FooImpl.getFooDetails 方法,但没有在方法参数上找到注释 @QueryParam,因为 @QueryParam 在基本方法上并且注释不是继承的。

拦截器实现:

@Provider
public class ParamValidationInterceptor extends AbstractPhaseInterceptor<Message> {

public ParamValidationInterceptor() {
super(Phase.PRE_INVOKE);
super.addBefore(someInterceptor);
}

@Override
public void handleMessage(Message message) throws Fault {

UriInfo uriInfo = new UriInfoImpl(message);
MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
Method methodToInvoke = (Method) message.get("org.apache.cxf.resource.method");
Parameter[] parameters = methodToInvoke.getParameters();
for (Parameter parameter : parameters) {

if (parameter.isAnnotationPresent(ValueSet.class)) {
ValueSet valueSet = parameter.getAnnotation(ValueSet.class);
QueryParam queryParam = parameter.getAnnotation(QueryParam.class);
Object invokedVal = queryParams.get(queryParam.value());

String[] allowedValues = valueSet.allowedValues();

if (!Arrays.asList(allowedValues).contains(invokedVal)) {
throw new CustomException();
}
}
}

}
}

谁能提出前进的方向?如果有人能提出替代方法,那就太好了。

P.S:我将 CXF 用作 JAX-RS 的实现,并将 spring 用作容器。

更新:

正如@Cássio Mazzochi Molin 和@Andy McCright 所建议的那样,我将使用@Pattern 注释。但是我很想知道为什么 JAX-RS 注释没有从接口(interface)继承,尽管规范说它们将被继承。

最佳答案

注解继承

根据 §3.6 注释继承 部分 JAX-RS specification ,建议始终重复注解,而不是依赖注解继承。

引用这个answer获取完整报价。

@QueryParam可以应用于不同的目标

请记住 @QueryParam注释可以应用于:

  • 资源方法参数
  • 资源类字段
  • 资源类 bean 属性

因此手动验证可能很棘手。

使用 Bean 验证

出于验证目的,您应该考虑 Bean Validation .考虑一个 @Pattern具有允许值的注释:

@Pattern(regexp = "ASC|DESC")

只需注释您的资源方法参数:

@GET
@Path("foo")
public Response getFoos(@QueryParam("sort")
@Pattern(regexp = "ASC|DESC") String sortDirection) {
...
}

如果您喜欢不区分大小写的值,请使用:

@Pattern(regexp = "ASC|DESC", flags = Pattern.Flag.CASE_INSENSITIVE)

如果给定值无效,一个ConstraintViolationException将被抛出。要处理此类异常并返回自定义响应,您可以使用 ExceptionMapper :

@Provider 
public class ConstraintViolationExceptionMapper
implements ExceptionMapper<ConstraintViolationException> {

@Override
public Response toResponse(ConstraintViolationException exception) {
...
}
}

关于java - 使用 CXF 作为实现限制查询参数 JAX-RS 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44264138/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com