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

问题描述 投票:0回答:2

我的目的是在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
2个回答
0
投票

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

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

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

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

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


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

© www.soinside.com 2019 - 2024. All rights reserved.