Java - Issue with SendRedirect not redirecting properly when used from a dialog box

I've implemented a Bootstrap form that is submitted by clicking the createTicketButton button, which triggers a jQuery call.

$('#createTicketButton').click(function(event) 
{
    $.ajax({
                processData : false,
                contentType : 'application/json',
                url : 'myUrl',
                "accept" : 'json',
                "dataType" : 'json',
                "type" : "POST",
                data : JSON.stringify(data),
                success : function(response) 
                {}
            });
});

The submission then goes through a Filter to verify the CSRF token matches what is stored on the server.

If there's a token mismatch, it should redirect to the login page. However, the issue arises when attempting to redirect as it causes a 500 error (Internal Server Error), and the redirection doesn't happen while the popover remains visible. Any suggestions?

public class CsrfFilter implements Filter
{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
    {
        boolean validToken = realToken.equals(requestToken);
        if (validToken)
        {
            chain.doFilter(request, response);
            return;
        }
        else
        {
            UriBuilder redirectUri = UriBuilder.fromUri("/login");
            try
            {
                String returnUrl = new URI(req.getHeader("referer")).getPath();
                redirectUri.queryParam("r", returnUrl);
            }
            catch (URISyntaxException | NullPointerException e)
            {
                // We don't need a return URL
            }
            res.sendRedirect(redirectUri.build().toString());
        }
    }
}

Here's my HTML code:

    <th:block th:fragment="createTicketFormModal">
        <div id="createNewTicket" class="modal fade" role="dialog" aria-labelledby="myModalLabel" data-backdrop="static" aria-hidden="true" data-modal-index="1">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="create-header modal-header">
                        <button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
                        <h4 id="edit-admin-modal" class="modal-title create-title">Create Ticket</h4>
                    </div>
                    <div class="modal-body">
                        <form id="create-ticket-form" class="create-form" method="POST" action="/cats/tickets/new">
                            <div class="alert alert-danger form-errors collapse"></div>

                       <!-- The form buttons -->
                                <input id="createTicketButton" class="btn btn-primary btn-block catsSubmit" type="button" value="Create Ticket" />
                                <button id="createTicketFormClearButton" class="btn btn-info btn-block" type="button">Clear</button>
                                <button class="btn btn-default btn-block" type="button" data-dismiss="modal">Close</button>
                                <input id="file-id" type="hidden" />

                        </form>
                    </div>
                </div>
            </div>
        </div>

    </th:block>

Below is the error stack:

java.lang.IllegalStateException: UT010019: Response already commited
io.undertow.servlet.spec.HttpServletResponseImpl.sendRedirect(HttpServletResponseImpl.java:173)
com.ephibian.j2ee.security.CsrfFilter.RedirectToLogin(CsrfFilter.java:194)

Answer №1

Seems like a unique occurrence happening within your servlet. Recommend diving in with your debugger and sharing the exception message here.

Answer №2

After investigating, I finally understand why this issue occurs. When making a request from Ajax, you cannot redirect using

response.sendRedirect("location")
as the client-side is responsible for handling the redirection.

It's recommended to send an error message and manage the redirection on the client-side.

You can achieve this by:

// Check if it's an Ajax call
if ("XMLHttpRequest".equals(req.getHeader("X-Requested-With"))) {
    res.sendError(Status.BAD_REQUEST.getStatusCode(),
            String.format("Invalid %s", CSRF_TOKEN_PARAM));
} else {
    UriBuilder redirectUri = UriBuilder.fromUri("/login");
    try {
        String returnUrl = new URI(req.getHeader("referer")).getPath();
        redirectUri.queryParam("r", returnUrl);
    } catch (URISyntaxException | NullPointerException e) {
        // No need for a return URL
    }
    res.sendRedirect(redirectUri.build().toString());
}

And on the client-side:

$('#createTicketButton').click(function(event) 
{
    $.ajax({
                processData : false,
                contentType : 'application/json',
                url : 'myUrl',
                "accept" : 'json',
                "dataType" : 'json',
                "type" : "POST",
                data : JSON.stringify(data),
                success : function(response) 
                {}, error: function (xhr, ajaxOptions, thrownError) {
                if(xhr.responseText.search("Invalid csrf_token")){
                    window.location.replace("location"); --> This is where we handle the redirection
                }

            }
            });
});

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

Adjusting the front size while utilizing the SideNav feature in Materialize

While creating a website using Symfony and Materialize, my client requested to have the menu displayed on the side. I followed the guidelines from and successfully implemented the side menu on the left. However, I am encountering two issues: The first ...

Discovering a duplicate of size 5 within a Java array

After creating an array that prints in sets of five, I am looking for a way to search the array by sets of five to identify any duplicates. Currently, my attempts have only allowed me to search by individual values rather than sets of five. Any guidance on ...

Issues with asynchronous functions arising while appending data into arrays

Struggling with an issue while working on async functions. My task involves comparing the deleteArray, containing current data needed in the collection, with the data present in the collection. static async updateDocsInCollection(data) { let dele ...

Pass the click event and state from child component to parent component

This is a parent component with an input field called day. By entering a number, clicking the Get data button will fetch some data (returnData) from an API. This data is then passed to a child component along with other values for display. Parent Componen ...

creating a lambda function to act as a timer

Below is my Timer code that I would like to rewrite as a lambda expression: private void setupPollingTimmer() { timer.scheduleAtFixedRate(new DownloadMessagesAndDisplayTask(), TIMERPERIOD,TIMERPERIOD); } private class DownloadMessages ...

Can classes in Nodejs have functions with the same name but different classes?

Is it possible for nodejs to have two functions in different classes with the same name? If not, what is the reason behind this limitation? Otherwise, there may be an issue in the code. Here is an example: var admins = require('./routes/admins' ...

Exploring Angular Route Configurations: Utilizing Multiple Outlets with Path as an Array of

In my Angular9 application, I have configured hundreds of routes paths. Is there a way to use multiple outlets with a single array of string paths? Current Code: const routes: Routes = [ { path: 'Data/:EntityID/:Date', compon ...

When using Oracle SQL, you can create a select query that will ignore a parameter if it is null

Imagine having an Oracle query like this: SELECT * FROM EMPLOYEE WHERE DEPARTMENT = ? AND DESIGNATION = ? AND DISTRICT = ? AND CIRCLE = ? In this query, it is possible that one, two, or three of the parameters (?) are empty or null. What can ...

Tips for leveraging a button to trigger server-side actions

Being a novice in web development, I'm currently working on a straightforward website that enables users to download files from the server side. These files are not pre-created; instead, there will be a button on the HTML page. When a user clicks this ...

The iframe is being loaded in the center of the page rather than at the top

I am currently facing an issue with embedding wetransfer into a website using iframe. The problem is that when the page loads, it automatically scrolls past the header section of the site instead of loading the new page at the top. How can I prevent this ...

Utilizing a .ini file to assign variables to styles elements in Material-UI: A comprehensive guide

I need to dynamically set the background color of my app using a variable retrieved from a .ini file. I'm struggling with how to achieve this task. I am able to fetch the color in the login page from the .ini file, but I'm unsure of how to apply ...

Tips for creating a dashed border line that animates in a clockwise direction when hovering

I currently have a dashed border around my div element: .dash_border{ border: dashed; stroke: 2px; margin:20px; } My goal is to make the dashed lines move clockwise when my pointer hovers over the div element and stop moving ...

What is the method to retrieve the information from a JSON response of a POST request in a Next/React application?

I am currently leveraging the Next.js API route to manage a POST request and subsequently send a response back to the frontend. To verify this process, I have utilized the Rapid API client extension and confirmed that a response is indeed being sent to the ...

A method of iteration that allows us to traverse through an object, regardless of whether it contains a single item or an array of items, is known as dynamic looping

I am dealing with a JSON output that can have different types of data: There may be an array of objects like this: var data = { "EARNINGS": [ { "PAYMENT": "1923.08", ...

Guidelines for creating a basic CSS modal

I am working on creating simple modal divs: <div class="modal"></div> <div class="modal-content"></div> Here are the related CSS rules: .modal{position:fixed;background:#444;opacity:0.5;width:100%;height:100%;left:0;right:0;botto ...

Create a unique HTML id dynamically using AngularJS

Hello, I am looking to create a unique identifier in html in the format 'a1', 'a2', etc. based on the values in the table. I am thinking of achieving this in the following way: <div ng-controller="ddController" > ...

Creating a new database row dynamically with PHP, JavaScript, and AJAX

There is a button that triggers a popup box with a textfield when clicked. Once something is entered in the textfield and the "Add" button is clicked, it should be added to the database. Currently, upon clicking "Add", data is inserted into the DB but it ...

Transmit information from a comprehensive form using AJAX technology

I created a complex form with 30 fields, out of which 3 fields are repeated 10 times. Here's the code: <form id="artikelform" method="POST" name="controleartikelen" action=""> <table id="controle"> <tr><th>Maakartikel</ ...

Changing view upon button click in ReactJS: implement conditional rendering

After grasping the fundamentals of ReactJS, I am eager to put my knowledge into practice by building a small application. The application includes two images below. In the Home view (1st image), there are several buttons that, when clicked, should lead to ...

Breaking down the string array into a two-dimensional array of characters

I am looking to convert the elements of a String array into a char array For example: String arr[]={"abc","defl","ghi"}; My goal is to save the characters in the String array into a char array at different indexes For example: char ch[0][]={'a&apo ...