JAX-RS – How to bind Filters to JAX-RS resources with Name Binding

In my earlier post, I have given an example to know how to bind the Filters to JAX-RS resources with Dynamic Binding.

Refer it @ JAX-RS Dynamic Binding

In this post, I am going to show how we can do that with Name Binding.

Follow the below steps to do that.

1. Create a custom annotation which uses @NameBinding annotation.


package com.resource;

import javax.ws.rs.NameBinding;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@NameBinding
@Target({ ElementType.METHOD, ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface AppKeyVerifier {}

2. Create a filter and implement the app key verification logic. Then apply the custom annotation to it.


package com.resource;

import com.model.AppError;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

@Provider
@AppKeyVerifier
public class AppKeyVerifierFilter implements ContainerRequestFilter {

    private final static Logger LOGGER = LoggerFactory.getLogger(AppKeyVerifierFilter.class);

    private final static String APP_KEY = "994f4fe4-APP-KEY-f3d5af27e1ee";

    @Context
    private HttpServletRequest httpServletRequest;

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

        String appKeyValueFromHeader = requestContext.getHeaderString("APP-KEY");
        LOGGER.info("APP Key:{}", appKeyValueFromHeader);
        if (!StringUtils.equals(APP_KEY, appKeyValueFromHeader) ) {
            requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED)
                                             .entity(new AppError("APP-KEY is not available or wrong"))
                                             .build());

        }
    }
}

3. Then apply the custom annotation to the target resource classes or methods.


package com.resource;

import com.model.User;
import com.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;

@AppKeyVerifier
@Path("users")
public class UserResource {

    private final static Logger LOGGER = LoggerFactory.getLogger(UserResource.class);

    @Inject
    UserService userService;

    @GET
    @Path("get/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public User get(@PathParam("id") String id) throws Exception {
        LOGGER.debug("get method is called with id:{}", id);
        return userService.get(id);
    }
    @GET
    @Path("getAll")
    @Produces(MediaType.APPLICATION_JSON)
    public List getAll() throws Exception {
        LOGGER.debug("getAll method is called");
        return userService.getAll();
    }

    @POST
    @Path("add")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public String save(User user) throws Exception {
        LOGGER.debug("save method is called with user:{}", user);
        return userService.save(user);
    }

    @DELETE
    @Path("delete/{id}")
    @Produces(MediaType.TEXT_PLAIN)
    public String remove(@PathParam("id") String id) throws Exception {
        LOGGER.debug("remove method is called with id:{}", id);
        return userService.remove(id);
    }

    @POST
    @Path("update")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public String update(User user) throws Exception {
        LOGGER.debug("update method is called with user:{}", user);
        return userService.update(user);
    }
}

Refer my code @https://github.com/dkbalachandar/java-rest-docker