'Quarkus static content response filter

Is there a way to add a filter/interceptor to static resources served from META-INF/resources?

I seem have tried all the possible options: @ServerResponseFilter, ContainerResponseFilter,WriterInterceptor however all these functions are called only for @Path or @Route...

Is there anything similar to @RouteFilter but for response?



Solution 1:[1]

There seem to be nothing built-in to modify the response of a static content for now but nothing stops you from serving content in a dynamic way:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;

@Path("/")
@Produces(MediaType.TEXT_HTML)
public class FrontendController {

    @GET
    public Response index() throws IOException {
        try (var index = getClass().getResourceAsStream(FrontendConstants.INDEX_RESOURCE)) {
            if (index == null) {
                throw new IOException("index.html file does not exist");
            }

            //modify index

            return Response
                .ok(index)
                .cacheControl(FrontendConstants.NO_CACHE)
                .build();
        }
    }

    @GET
    @Path("/{fileName:.+}")
    public Response staticFile(@PathParam("fileName") String fileName) throws IOException {
        try (var file = FrontendController.class.getResourceAsStream(FrontendConstants.FRONTEND_DIR + "/" + fileName)) {
            if (file == null) {
                return index();
            }

            var contentType = URLConnection.guessContentTypeFromStream(file);

            return Response
                .ok(
                    new String(file.readAllBytes(), StandardCharsets.UTF_8),
                    contentType == null ? MediaType.TEXT_PLAIN : contentType
                )
                .cacheControl(FrontendConstants.NO_CACHE)
                .build();
        }
    }
}

Solution 2:[2]

Those are the only ones available:

public interface ClientRequestFilter {
    void filter(ClientRequestContext requestContext) throws IOException;
}

public interface ClientResponseFilter {
    void filter(ClientRequestContext requestContext,
        ClientResponseContext responseContext) throws IOException;
}

public interface ContainerRequestFilter {
    void filter(ContainerRequestContext requestContext) throws IOException;
}

public interface ContainerResponseFilter {
    void filter(ContainerRequestContext requestContext,
    ContainerResponseContext responseContext) throws IOException;
}

public interface ReaderInterceptor {
    Object aroundReadFrom(ReaderInterceptorContext context)
        throws java.io.IOException, javax.ws.rs.WebApplicationException;
}

public interface WriterInterceptor {
    void aroundWriteTo(WriterInterceptorContext context)
        throws java.io.IOException, javax.ws.rs.WebApplicationException;
}

You could try with ClientResponseFilter and see:

In the Client API, a ClientRequestFilter is executed as part of the invocation pipeline, before the HTTP request is delivered to the network.

ClientResponseFilter is executed upon receiving a server response, before control is returned to the application.

https://quarkus.io/specs/jaxrs/2.1/index.html#filters_and_interceptors

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sam Ivichuk
Solution 2 JCompetence