0

My purpose is to use a custom annotation within the REST method that automatically transform the parameter in some desired form. Something like:

Response get(@StringNormalizer(UPPERCASE) String myparam)

I know there is the HttpServletRequestWrapper class that can be used to intercept and modify input 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
    }
}

However I don't know how to retrieve annotations for method parameters (which, in the above example, is StringNormalizer class).

Any hints?

Fabrizio Stellato
  • 1,727
  • 21
  • 52

2 Answers2

0

This is pretty straight forward in standard JAX-RS. You'll want a ContainerRequestFilter that can transform your parameters. Something like:

@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);
        }
    }
}

Note that this uppercases every path parameter. If this isn't what you want you'll want to examine the key. So if, for example, your URL pattern for the REST service is something like @Path("getCustomer/{customerId}") the key would be customerId and the value would be what the URL has on it.

Lastly, you can duplicate this loop with getQueryParameters where you get the MultivaluedMap if you'd like to handle query parameters too.

stdunbar
  • 16,263
  • 11
  • 31
  • 53
-1

You have two ways to do that. At first, and the best solution for me, is to use an Argument Resolver.

An argument resolver is a class that implement the HandlerMethodArgumentResolver interface. The abstract methods you have to implements let you get the parameter type and the parameter optional annotations and to build it accessing original data.

Then you should extends your Configuration class implementing the WebMvcConfigurer and to override the addArgumentResolvers to include the newly created one to the list declared as formal parameter.

With this configuration Spring will automatically intercept for all controller all declared parameters matching the condition you've written in the Argument Resolver class, and it will apply the transform logic you've developed.

The second solution to achieve your goal is to implement Aspect Oriented Programming which is over-structured in this case but well suited for such purposes. Spring let you implement Aspects using AspectJ. As i said before i think the best solution for you is to use the argument resolvers.

Roberto Canini
  • 340
  • 1
  • 3
  • 13