Updating static resources with versioning using a servlet filter (including an additional query parameter)

Trying to create a filter that can modify a JavaScript URL from /script/script1.js to

/scripts/script1.js?version=1.3.2

Attempts made:

  1. Tried using

    response.sendRedirect("/scripts/script1.js?version=1.3.2")
    but received an ERR_TOO_MANY_REDIRECTS error in the browser console.

  2. Attempted to use RequestWrapper, adding a parameterMap with a key of "version" and value of "1.3.2", however, it requires adding this information into queryParameters map. Is it possible to add queryParameters in a filter?

Is there any solution for implementing versioning in Java using a filter?

PS: Acknowledged that this may not be the optimal solution and will avoid using URLrewriteFilter.

Answer №1

A great solution to consider in this scenario is using Filters:

1. Develop a filter that wraps the original request with new parameters:

@WebFilter("/scripts/*")
public class CustomFilter implements Filter
{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException,
        ServletException
    {
        String version=request.getParameter("version");
        if (version == null)
        {
            Map<String, String[]> myParameters=new HashMap<>(request.getParameterMap());
            request=new EnhancedHttpServletRequest((HttpServletRequest)request, myParameters);
        }
        chain.doFilter(request, response);
    }

    // ... implement rest of the Filter logic...
}

2. Implement the request wrapper:

public class EnhancedHttpServletRequest extends HttpServletRequestWrapper
{
    private final Map<String, String[]> parameters;

    public EnhancedHttpServletRequest(HttpServletRequest request, Map<String, String[]> parameters)
    {
        super(request);
        this.parameters=parameters;
    }

    @Override
    public String getParameter(String name)
    {
        String[] values=parameters.get(name);
        return values!=null && values.length > 0
            ? values[0]
            : null;
    }

    @Override
    public Map<String, String[]> getParameterMap()
    {
        return parameters;
    }
}

Update

If you need to override the getQueryString method, you can do it like this:

    @Override
    public String getQueryString()
    {
        String queryString;
        try
        {
            queryString=super.getQueryString();
            if (queryString == null)
            {
                queryString="?";
            }
            for (Map.Entry<String, String[]> param : getParameterMap().entrySet())
            {
                queryString+="&";
                for (String value : param.getValue())
                {
                    queryString+=URLEncoder.encode(param.getKey(), "UTF-8") + "=" + URLEncoder.encode(value, "UTF-8");
                }
            }
        }
        catch (UnsupportedEncodingException e)
        {
            throw new java.lang.RuntimeException("Unhandled exception", e);
        }
        return queryString;
    }
}

Answer №2

One alternative you can consider is to redirect the request from the filter:

RequestDispatcher dispatcher = request.getRequestDispatcher("/scripts/script1.js?version=1.3.2");
dispatcher.forward(request, response);

By doing this, there is no need to invoke filter.doChain(request, response).

The forwarded request will have "version" accessible as a query parameter.

Answer №3

To implement this filter, you can include the following code snippet directly in the JSP file that is calling the specific file:

<c:choose>
    <c:when test="${filter.value eq 'xxx'}">
      ... add JavaScript function here
    </c:when>
    <c:otherwise>
    .... other script content goes here
    </c:otherwise>
</c:choose>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips on handling parameters in the form of a single value or an array of values

I've implemented multiple functions structured like this: this.something = function (which) { // Can be one or many. if (!Array.isArray(which)) { // Single input case. doSomething(which); } else { ...

What could be the reason for v-model not functioning properly within vue.extend?

I've configured a page structure similar to the following: <main id="app"> <div id="mount-place"></div> </main> <script type="text/x-template" id="my-template"> ...some code her ...

Upload images easily by dragging and dropping a URL instead of a file

My goal is to make the following scenario possible: Picture this: two browser windows are open - one window (a) displaying a website with a drop area for picture files, and the other window (b) containing some pictures. I aim to drag and drop a picture d ...

Leveraging Node.js to establish a connection between two pug files

Recently, I decided to delve into the world of pug and JavaScript. However, I seem to be facing a small issue that I can't quite figure out on my own. My project involves creating multiple .pug files with various text content that I can navigate betwe ...

Analyze - browsing through information in a vast XML document

Does anyone know of a tool or widget that can efficiently load and display data from large XML files (over 1 GB) in the browser without freezing up? Any suggestions would be greatly appreciated. Thanks! ...

Managing user input in Android using a Fragment

In my latest project, the main activity is structured as shown below: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R ...

Whenever I execute the code in Java, the function "verifyTextPresent" is providing inaccurate results

My experience with using Selenium IDE to create a recorded test has been interesting. One of the commands I used was verifyTextPresent, and when the text changed as expected, the IDE flagged an error. After transferring the recorded test to Eclipse and ru ...

How can I retrieve console log information in POSTMAN when a test fails?

Having an issue with this test. I am trying to trigger a console.log when the installment value in my JSON is less than 100 (resulting in a test FAIL). However, I am receiving both PASS and FAIL results in the test, but no information is showing up in th ...

When a superclass variable points to a subclass object in Java

Question about Java Inheritance: Understanding the use of parent reference variables. As I delve into learning Java and explore the inheritance concepts, a question has arisen. public class Shape { private String shapeName; private String area; ...

SvelteKit: Exploring alternative ways to interact with MongoDB without relying on traditional endpoints

(1/9/2023) Update: SvelteKit has recently introduced support for server-only load functions and Form actions to enable sending requests to the server. I am looking to retrieve data from my database without allowing end users to access it through the API e ...

How can I adjust the widths of two input fields in a jQuery select box?

I found this cool jquery plugin that enhances the appearance of select dropdown boxes. You can check it out here: http://code.google.com/p/select-box/ Take a look at this fiddle to see how it works: http://jsfiddle.net/FQKax/1/ I've been trying to m ...

What is the best way to position and align an angle with the axis of a moving 3D figure?

My latest project involves a rotating planet, specifically Saturn with its iconic rings. To capture the best view of this celestial marvel, I configured the camera with precision: var camera = new THREE.PerspectiveCamera(45, width / height, 0.05, 1000); ...

Passing the app variable from Express.js to routes

I am attempting to transfer some data from the app (variable defined as var app = express();) to some Socket.IO related code by sending a value to a middleware in a similar manner: function routes(app) { app.post('/evento', function (req, re ...

Pattern matching to exclude specific characters

To enhance security measures, I am looking to restrict users from inputting the following characters: ~ " # % & * : < > ? / \ { | } . The key requirement is that all other characters should be permitted, while ensuring that only the sp ...

Tips for ensuring jwt token is not lost when refreshing a page in an angularjs app

My project involves authorizing users using jwt tokens, but I am facing an issue where the token is lost upon page refresh and subsequent requests to the server do not include the token. The setup includes storing the token in local storage and utilizing ...

Generate an array containing NaN data type value on an Android platform

Currently, I am working on developing a dynamic array to create a chart in an Android application using the AchartEngine library. The goal is to insert some arbitrary integer, such as NaN in JavaScript, so that the chart library will skip drawing a point ...

Addressing simple JavaScript "async" AJAX requests that are sequenced and reliant on each other

I'm currently developing an application that includes a dashboard on its main page. In order to address any potential loading issues, the content of the dashboard is being calculated asynchronously using Ajax. This means that users do not have to wait ...

In my actions, when I make a call using async/await, it results in a Promise that is currently <pending>

Greetings! I am a newbie when it comes to making api calls and have recently started using axios to fetch a simple deck of cards. In my attempt to make a basic axios call, I noticed that when I log the response (res), I get the desired data. However, upon ...

Using the import statement to bring in module one from "./two" is causing a malfunction in my JavaScript file while working with Laravel 5.4 broadcasting using Pusher

Node Version 8.6.0 npm version 5.3.0 Chrome Issue (Version 61.0.3163.100) Error: Unexpected token import Mozila Problem (Version 56.0 (64-bit)) SyntaxError: Only top-level import declarations are allowed import one from "./two"; ...

Issues arise in the alignment of the tab order when utilizing a combination of the stripe card

Experiencing an issue with tab index not working properly when using Vue.js and having a stripe card-element inside the Vue main element. Below is the code snippet: <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js ...