【问题标题】:Modify REST parameters with annotation - Java EE8使用注释修改 REST 参数 - Java EE8
【发布时间】:2019-12-10 16:01:23
【问题描述】:

我的目的是在 REST 方法中使用自定义注释,以某种所需的形式自动转换参数。比如:

Response get(@StringNormalizer(UPPERCASE) String myparam)

我知道有 HttpServletRequestWrapper 类可以用来拦截和修改输入 URI:

@WebFilter(urlPatterns="/*")
public class ApiOriginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
    {                       
        HttpServletRequest wrappedRequest = new MyWrappedRequest(request);
        chain.doFilter(wrappedRequest, response);
    }
}

public class MyWrappedRequest extends HttpServletRequestWrapper
{
    @Override
    public String getQueryString() {
        // return modified query
    }
}

但是我不知道如何检索方法参数的注释(在上面的示例中,它是 StringNormalizer 类)。

有什么提示吗?

【问题讨论】:

  • 您是要编写自己的注释处理器还是已经存在的东西?
  • 其实我需要的是一个大写/小写的转换器字符串,它适用于查询参数,如果可能的话,也适用于路径参数

标签: java rest servlets java-ee-6 java-ee-8


【解决方案1】:

您有两种方法可以做到这一点。 一开始,对我来说最好的解决方案是使用Argument Resolver

参数解析器是一个实现HandlerMethodArgumentResolver 接口的类。您必须实现的抽象方法让您可以获取参数类型和参数可选注释并构建它以访问原始数据。

然后您应该扩展实现WebMvcConfigurer 的配置类并覆盖addArgumentResolvers 以将新创建​​的包含到声明为形式参数的列表中。

使用此配置,Spring 将自动拦截所有与您在 Argument Resolver 类中编写的条件匹配的控制器声明的参数,并将应用您开发的转换逻辑。

实现目标的第二个解决方案是实现面向方面的编程,在这种情况下它是过度结构化的,但非常适合这种目的。 Spring 允许您使用 AspectJ 实现 Aspects。 正如我之前所说,我认为对您来说最好的解决方案是使用参数解析器。

【讨论】:

  • 对不起,我既不使用 Spring 也不使用 AspectJ
【解决方案2】:

这在标准 JAX-RS 中非常简单。您需要一个可以转换参数的ContainerRequestFilter。比如:

@Provider
@Priority(Priorities.USER)
public class RequestLoggingFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        UriInfo uriInfo = requestContext.getUriInfo();

        MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
        for( String nextKey: pathParameters.keySet() ) {
            List<String> oldValues = pathParameters.get(nextKey);
            List<String> newValues = new ArrayList<>();

            for (String nextValue : oldValues) {
                newValues.add(nextValue.toUpperCase());
            }
            // replace old parameters with new
            pathParameters.put(nextKey, newValues);
        }
    }
}

请注意,每个路径参数都大写。如果这不是您想要的,您将需要检查密钥。因此,例如,如果您的 REST 服务的 URL 模式类似于 @Path("getCustomer/{customerId}"),则键将是 customerId,值将是 URL 上的值。

最后,如果您还想处理查询参数,您可以使用getQueryParameters 复制此循环,在该循环中获得MultivaluedMap

【讨论】:

  • 这不适用于查询参数,因为它是不可修改的地图
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多