skip to Main Content

Im trying to make an AJAX call to a servlet from a login page which is designed as a ‘.jsp’ page.

Im using ‘fetch’ API for AJAX (code snippet attached below). This script is written in same ‘.jsp’ page below <body>.

/* Function for making Ajax call to login controller */
    const fnAjaxUsersController = function () {
        const userName = document.getElementById('idUserName');
        const userPassWord = document.getElementById('idUserPassWord');

        console.log(userName.value);
        console.log(userPassWord.value);

        const myHeaders = new Headers();
        myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');

        const linkToLoginController = `UsersController.do`;

        fetch(linkToLoginController, {      
            method: 'POST'  ,
            headers: myHeaders,         
            body: `uname=${userName.value}&pwd=${userPassWord.value}`            
        })
            .then((response) => {
                if (!response.ok) {
                    throw new Error(`${linkToLoginController} response failed`);
                } else {
                    console.log(response);
                    return response.json()
                }
            })
            .then((jsonData) => {
                console.log(jsonData);
                if (Number.parseInt(jsonData.msgCode) === 0) {
                    fnChangeClassToInValid(userName);
                    fnChangeClassToInValid(userPassWord);

                } else {
                    fnChangeClassToValid(userName);
                    fnChangeClassToValid(userPassWord);

                }
            })
            .catch(err => {
                console.log(`${err.message}`)
            }).finally(() => {
                //console.log(`This block is always executed`);
                /* Normally used for disappearing loading buffer */
            });
    };

Now the request is getting through the servlet controller but when I’m accessing them using getParameter method its showing null.

protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        /*
         * Creating user object(No need to validate parameters as they are handled at
         * front end)
         */     
        Users u = new Users((String)request.getParameter("uname"), (String)request.getParameter("pwd"));
        System.out.println(u);

.....   

Im guessing it has something to do with Content-Type header as same is working if login page is changed to plain ‘.html’.

Below is the form for accepting user inputs.

    <form id ="idLoginForm" accept-charset="utf-8" method='post' action='${pageContext.request.contextPath}/header/header.jsp'>
        <div class="row mb-3 text-center">
            <div class="col-sm-4 themed-grid-col"></div>
            <div class="col-sm-4 themed-grid-col">
                <img class="mt-4" src="${pageContext.request.contextPath}/img/80_ISG.png" alt="" width="100" height="57">
            </div>
            <div class="col-sm-4 themed-grid-col"></div>
        </div>

        <div class="row mb-3 text-center">
            <div class="col-sm-4 themed-grid-col"></div>
            <div class="col-sm-4 themed-grid-col">
                <h1 class="h3 mb-3 fw-normal">Please sign in</h1>
            </div>
            <div class="col-sm-4 themed-grid-col"></div>
        </div>

        <div class="row mb-3 ">
            <div class="col-sm-4 themed-grid-col"></div>
            <div class="col-sm-4 themed-grid-col">
                <div class="form-floating">
                    <input type="text" class="form-control" id="idUserName" placeholder="Username"
                        aria-describedby="idUserNameFeedBack" required> <label for="idUserName">Username</label>
                    <div id="idUserNameFeedBack" class="invalid-feedback">
                        Please enter valid user name
                    </div>
                </div>
            </div>
            <div class="col-sm-4 themed-grid-col"></div>
        </div>

        <div class="row mb-3 ">
            <div class="col-sm-4 themed-grid-col"></div>
            <div class="col-sm-4 themed-grid-col">
                <div class="form-floating">
                    <input type="password" class="form-control" id="idUserPassWord" placeholder="Password"
                        aria-describedby="idUserPassWordFeedBack" required> <label
                        for="idUserPassWord">Password</label>
                    <div id="idUserPassWordFeedBack" class="invalid-feedback">
                        Please enter valid user password
                    </div>
                </div>
            </div>
            <div class="col-sm-4 themed-grid-col"></div>
        </div>

        <div class="row mb-3 text-center">
            <div class="col-sm-4 themed-grid-col"></div>
            <div class="col-sm-4 themed-grid-col">
                <button id="idLoginSubmit" class="btn btn-primary w-100 py-2" type="submit">Sign in</button>
                <p class="mt-5 mb-3 text-body-secondary">© 2017–2024</p>
            </div>
            <div class="col-sm-4 ">
            </div>
        </div>
    </form>

3

Answers


  1. I think controller is unable to parse body sent in this format, ServletRequest.getParameter(…) spec is saying:

    For HTTP servlets, parameters are contained in the query string or posted form data

    you are sending params in body, so to read them you either need to move them to request URL as request params, e.g.

    const linkToLoginController = 
       `UsersController.do?uname=${userName.value}&pwd=${userPassWord.value}`;
    

    or change body to FormData, something like this:

    const formData = new FormData();
    formData.append('uname', userName.value);
    formData.append('pwd', userPassWord.value);
    fetch(linkToLoginController, {      
         method: 'POST'  ,
         headers: myHeaders,         
         body: formData            
    })
    
    Login or Signup to reply.
  2. You get the wrong code to access form fields

    instead

    body: `uname=${userName.value}&pwd=${userPassWord.value}`            
    

    you should use

    body: 'uname='+userName.value+'&pwd='+userPassWord.value            
    

    The Content-Type header is x-www-form-urlencoded, but it should be

    headers:{'Content-Type':'application/x-www-form-urlencoded'}
    
    Login or Signup to reply.
  3. Im guessing it has something to do with Content-Type header as same is working if login page is changed to plain ‘.html’.

    It’s because the JavaScript template literal syntax ${...} is also interpreted by JSP as part of Expression Language.

    You have 2 options:

    • Put JS code in its own JS file and reference it by <script src="yourScriptFile.js">. Additional benefit is that it can improve performance, because client can now request it asynchronously and also has the possibility to cache it following different rules.
    • Escape the template literals which you don’t want to be processed as part of JSP EL. You can do so by putting a backslash in the front of $ as in ${...}.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search