繁体   English   中英

使用注释修改 REST 参数 - Java EE8

[英]Modify REST parameters with annotation - Java EE8

我的目的是在 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类)。

任何提示?

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

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

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

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

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

这在标准 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM