0

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

有什么提示吗?

4

2 回答 2

0

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

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

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

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

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

于 2019-12-10T16:16:27.210 回答
0

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

于 2019-12-10T17:36:45.553 回答