yas*_*nth 2 java rest spring cxf jax-rs
我有一个用例,我需要限制可以作为查询参数传递的值。
\n\n@Path("/foo")\npublic interface Foo {\n\n @GET\n @Path("/details/id/{id}")\n void getFooDetails(@PathParam("id") String id, @QueryParam("sort") String sortDirection);\n}\n\npublic class FooImpl {\n public void getFooDetails(String id, String sortDir) {\n //Implementation\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n在上面的示例中,我想限制sort可以通过 API 传递到ASC, DESC.
是否有任何现有的 CXF 注释可以用来限制参数的值?我还没有找到任何解决方案,所以我尝试了以下解决方案。
\n\n我的方法:
\n\n@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})\n@Retention(RetentionPolicy.RUNTIME)\n@Inherited\npublic @interface ValueSet {\n\n String[] allowedValues();\n}\nRun Code Online (Sandbox Code Playgroud)\n\n修改后的界面如下所示。
\n\n@Path("/foo")\npublic interface Foo {\n\n @GET\n @PathParam("/details/id/{id}")\n void getFooDetails(@PathParam("id") String id, @QueryParam("sort") @ValueSet(allowedValues = {"ASC", "DESC"}) String sortDirection);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我编写了一个 CXF 拦截器来拦截 API 调用。我使用反射来处理参数FooImpl.getFooDetails。但我面临的问题是,拦截器查看 FooImpl.getFooDetails 方法,但在方法参数上找不到注释 @QueryParam,因为 @QueryParam 位于基本方法上,并且注释不是继承的。
拦截器实现:
\n\n@Provider\npublic class ParamValidationInterceptor extends AbstractPhaseInterceptor<Message> {\n\n public ParamValidationInterceptor() {\n super(Phase.PRE_INVOKE);\n super.addBefore(someInterceptor);\n }\n\n @Override\n public void handleMessage(Message message) throws Fault {\n\n UriInfo uriInfo = new UriInfoImpl(message);\n MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();\n Method methodToInvoke = (Method) message.get("org.apache.cxf.resource.method");\n Parameter[] parameters = methodToInvoke.getParameters();\n for (Parameter parameter : parameters) {\n\n if (parameter.isAnnotationPresent(ValueSet.class)) {\n ValueSet valueSet = parameter.getAnnotation(ValueSet.class);\n QueryParam queryParam = parameter.getAnnotation(QueryParam.class);\n Object invokedVal = queryParams.get(queryParam.value());\n\n String[] allowedValues = valueSet.allowedValues();\n\n if (!Arrays.asList(allowedValues).contains(invokedVal)) {\n throw new CustomException();\n }\n }\n }\n\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n有人能提出前进的方向吗?如果有人能提出替代方法,那就太好了。
\n\nPS:我使用 CXF 作为 JAX-RS 的实现,并使用 spring 作为容器。
\n\n更新:
\n\n就像 @C\xc3\xa1ssio Mazzochi Molin 和 @Andy McCright 建议的那样,我将使用 @Pattern 注释。但我很好奇为什么 JAX-RS 注释不是从接口继承的,尽管规范说它们将被继承。
\n根据JAX-RS 规范的\xc2\xa73.6 Annotation Inheritance部分,建议始终重复注释而不是依赖注释继承。
\n\n请参阅此答案以获取完整报价。
\n\n@QueryParam可以应用于不同的目标请记住,@QueryParam注释可以应用于:
因此,手动验证可能很棘手。
\n\n出于验证目的,您应该考虑Bean Validation。考虑@Pattern带有允许值的注释:
@Pattern(regexp = "ASC|DESC")\nRun Code Online (Sandbox Code Playgroud)\n\n只需注释您的资源方法参数:
\n\n@GET\n@Path("foo")\npublic Response getFoos(@QueryParam("sort") \n @Pattern(regexp = "ASC|DESC") String sortDirection) {\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n\n如果您喜欢不区分大小写的值,请使用:
\n\n@Pattern(regexp = "ASC|DESC", flags = Pattern.Flag.CASE_INSENSITIVE)\nRun Code Online (Sandbox Code Playgroud)\n\n如果给定值无效,ConstraintViolationException则会抛出 a 。要处理此类异常并返回自定义响应,您可以使用ExceptionMapper:
@Provider \npublic class ConstraintViolationExceptionMapper \n implements ExceptionMapper<ConstraintViolationException> {\n\n @Override\n public Response toResponse(ConstraintViolationException exception) {\n ...\n } \n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
3011 次 |
| 最近记录: |