Methods for transferring json information between javascript and servlets?

The Communication Challenge

Struggling with establishing communication between a client using html/javascript to send form data as json to a servlet, and then receiving json back from the servlet. The process seems to have some errors that I am unable to pinpoint.

Here's how it should work:

  • JavaScript retrieves data from a form, converts it to json, and sends it to the servlet.
  • On the server side, the servlet reads the json, takes necessary action, generates another json response, and sends it back.
  • Back on the client side, the json is received and used to draw dynamic html content. (Currently just logging it with console.log())

The Client-Side Code

A piece of javascript code responsible for handling the form submission:

// Adding event listener to the form submit
document.querySelector('#login_form').addEventListener('submit',(e)=>{
    e.preventDefault();
    login_send(e.target);
});

// Function to handle form submission
function login_send(form){
    console.log(form2json(form));
    
    fetch('login',{
        method:'POST',
        headers:{
            'Accept':'application/json, text/plain, */*',
            'Content-type':'application/json'},
        body: form2json(form)
    })
    .then((res) =>res.json())
    .then((data) => {
        console.log("Response: "+data);
    })
    .catch((err) => console.error(err));
}

// Custom function to convert form data to json
function form2json(form){
    let js="{";
    let last=form.length-1;
    for (i=0;i<last;i++){
        js+="\""+form.elements[i].name+"\":\""+form.elements[i].value+"\"";
        if(i+1<last) js+=",";
    }
    js+="}";
    return js;
}

The Server Configuration

Defining the url mapping in the web.xml file to connect the servlet java class:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <servlet>
        <servlet-name>Login Servlet</servlet-name>
        <servlet-class>com.cactusstore-1.ui.Login</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Login Servlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>

The Servlet Implementation

...
import javax.json.*;
...

public class Login extends HttpServlet {
    
    protected void processRequest(HttpServletRequest req,
            HttpServletResponse res) throws ServletException, IOException {
        res.setContentType("application/json;charset=UTF-8");
        
        try (PrintWriter out = res.getWriter()) {
            
            User u = new User(
                    req.getParameter("email"),
                    "10010099",
                    req.getParameter("pass")
            );
            
            JsonObject root;
            JsonObjectBuilder rootBuilder = Json.createObjectBuilder();
            JsonObjectBuilder userBuilder = Json.createObjectBuilder();
            
            userBuilder
                .add("name",u.getName())
                .add("email", u.getEmail())
                .add("sid", u.getSId());

            root = rootBuilder.add("login", userBuilder).build();
            
            out.println(root);
            out.flush();
            out.close();
        }
    }
}

An error occurs when trying to receive json response:

custom.js:23 SyntaxError: Unexpected end of JSON input

This issue suggests that the servlet might not be returning anything. As an attempt, modifying the res.json() or res.text() methods doesn't resolve the situation. Even changing out.println(root) directly results in no output being received.

Your insights would be greatly appreciated! (With my limited experience in these languages, any guidance is valuable).


Edit 1

User Class Details

public class User {
    private String email;
    private final String session_id;
    private String name;
    
    public User(String email, String id, String name) {
        this.email = email;
        this.session_id= id;
        this.name = name;
    }

    // Getters and setters omitted for brevity
}

Edit 2

Thanks to @vladwoguer, logs were examined revealing issues related to the Json class. Surprisingly, Netbeans shows no error but autocomplete functions are also failing. Further exploration is ongoing!

Error Logs:
java.lang.ClassNotFoundException: javax.json.Json
    ...
System.out.println("YOUR EMAIL: "+req.getParameter("email"));
Result:
YOUR EMAIL: null

Grateful for your continued support and patience during this learning process.

Answer №1

One issue that needs to be addressed is the error message:

java.lang.ClassNotFoundException: javax.json.Json
To resolve this, you must ensure that it is included in the classpath. Place the javax.json jar file that you are using inside the YOUR_PROJECT/web/WEB-INF/lib directory. In my case, I utilized javax.json-1.0.jar.

YOUR_PROJECT
|
|__web
   |
   |__WEB-INF
      |
      |__lib
         |  javax.json-1.0.jar

By following this method, when you export and deploy the war file on tomcat, the jar will be accessible in the classpath.

Another problem arises when passing a JSON to the server and attempting to retrieve parameters using req.getParameter. The correct approach involves parsing the json and extracting values as shown below:

 StringBuilder sb = new StringBuilder();
 BufferedReader br = req.getReader();
 String str = null;
 while ((str = br.readLine()) != null) {
     sb.append(str);
 }

 String json = sb.toString();


 JsonReader jsonReader = Json.createReader(new StringReader(json));
 JsonObject jsonObject = jsonReader.readObject();
 jsonReader.close();

 // an object with three fields.
 User u = new User(jsonObject.getString("email"), "10010099", jsonObject.getString("pass"));

The complete code example:

public class Login extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        res.setContentType("application/json;charset=UTF-8");
        try (PrintWriter out = res.getWriter()) {

            StringBuilder sb = new StringBuilder();
            BufferedReader br = req.getReader();
            String str = null;
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            
            String json = sb.toString();

            JsonReader jsonReader = Json.createReader(new StringReader(json));
            JsonObject jsonObject = jsonReader.readObject();
            jsonReader.close();

            // an object with three fields.
            User u = new User(jsonObject.getString("email"), "10010099", jsonObject.getString("pass"));

            // construct json answer.
            // based on https://www.youtube.com/watch?v=BPMVC999HTs
            JsonObject root;
            JsonObjectBuilder rootBuilder = Json.createObjectBuilder();
            JsonObjectBuilder userBuilder = Json.createObjectBuilder();
            userBuilder.add("name", u.getName()).add("email", u.getEmail()).add("sid", u.getSId());

            root = rootBuilder.add("login", userBuilder).build();
            // write response to out
            out.println(root);
            out.flush();
            out.close();
        }
    }
}

Answer №2

Creating JSON manually is not acceptable!
Remember, each HTML form has an onSubmit function that you should utilize.

<form onsubmit="login_send()">
    <button type="submit"></button>
</form>

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 for creating an illustration in Vue.js

As I attempt to create an image using canvas, my browser throws this error at me: Uncaught TypeError: Cannot read property 'drawImage' of undefined at Image.img.onload (test.js:23) To troubleshoot, I added some console.log() messages and here ...

Tips for Limiting Upload Image Size with Maximum Width and Height

Is it possible to set a maximum width and height for an image before uploading it? I want the user to select a file, see a preview of the image, crop it, and then upload it to be saved in a directory. How can I enforce a max width and height limit before a ...

Retrieving data using the GetJSON method consistently returns identical values

Here is the code I have written: $(document).ready(function () { $.getJSON("data.json", function (data) { var user_Data = ""; $.each(data, function (key, value) { user_Data += '<p class="user">' + value.na ...

Comparison between WeakReference and storing Lists of JSON objects

I need some advice. I am working with a JSON file containing nearly 6000 complex objects, each with a few different arrays. My goal is to serialize these objects into a simpler structure for insertion into a database, but once that is done, I no longer ne ...

Issue with Android boolean preference handling

How can I save the status of a checkbox into my preferences? I have set up a listener on the checkbox, so that when it is checked, I use prefs.putBoolean("cbstatus", true), and when it is unchecked, I use prefs.putBoolean("cbstatus", false); The problem ...

Angular SPA Routing for .Net Core 2.0

Having recently created a new Angular SPA project using the .Net core 2.0 SPA templates, I find myself facing some challenges as a newcomer to Angular/Typescript and HMR. While most functionalities were working smoothly at first, I noticed a peculiar issu ...

Optimal method for categorizing a product list by category | Utilizing Javascript

I'm currently exploring the most efficient method to categorize and analyze products in O(n) to extract valuable insights from different categories. Here is a snippet of the data I am working with: [ { "code": 25754, &qu ...

CSS margin-left causing issues in Chrome Extension

My current situation is incredibly puzzling, as I am at a loss for what is happening. I developed a Firefox add-on using jQuery and CSS to revamp a website. When attempting to transfer the add-on to Chrome (which was relatively straightforward due to the s ...

Creating a dynamic textarea input based on the number entered using AngularJS

Can a loop be simplified in AngularJs to easily determine the number of textarea inputs a user can fill? <input type="number" class="form-control" min="1" max="4" value="1"> <div ng-repeat="..."> <div class="form-group"> < ...

The datatables button triggers an event twice

Whenever I click a button or tag in datatables, the modal opens twice and ajax runs twice. PS. I am using angular.js with datatables as a directive that is created by jQuery datatables, not the Angular datatables module. How can I solve this issue? Than ...

Is there a way in vee-validate to validate specific sections of a form?

I'm struggling with my English skills. When I utilize 'this.$validator.validate()', I am seeking a way to only validate specific inputs on the page. Is there a method to achieve this? ...

The class is tangible and does not override the abstract function apply(Object) in Function

I am attempting to hold off until a JavaScript script returns true, however the code I have put together is causing compilation errors. is not abstract and does not override abstract method apply(Object) in Function Here is the snippet of code: WebDrive ...

Comparing Optimistic Updates and Tag Invalidation in RTK Query

I found a basic code example from the RTK query documentation: updatePost: build.mutation<void, Pick<Post, 'id'> & Partial<Post>>({ query: ({ id, ...patch }) => ({ url: `posts/${id}`, method: 'PUT', ...

"Trouble in Transmitting: Node.js Fails to

As a beginner in programming, I am currently following a tutorial to enhance my skills. I've encountered a roadblock and I can't seem to successfully post new entries using the code. I'm struggling to identify what I might be missing here. ...

In Firefox version 3.6, sIFR 3 is displaying text in a random arrangement along a single line

For some reason, sIFR 3 is behaving oddly in Firefox. In other browsers like IE, Chrome, and Safari, the Flash element within a 412px wide box remains consistent at that width. However, in Firefox, it initially stretches to the width of the Body element b ...

Guide on incorporating a thymeleaf custom dialect in an HTML script

Essentially, I am trying to create a dynamic schema using ld+json with thymeleaf. To fetch the URL for the corresponding page, we have set up a custom processor as shown below: public class CustomUrlAttributeTagProcessor extends AbstractAttributeTagProcess ...

Creating a digital signature in Java/Android using RSA keys

In my java/android project, I need to create a digital signature using a private key (RSA) stored in the database. The keys were generated using the code below (the project is in production and cannot be changed): // Get keys pair (RSA) KeyPair rsaKeyPai ...

Eliminating the save password prompt upon form submission in Firefox with the use of JavaScript

Is there a way to submit a form without triggering the browser's save password popup? This issue seems to be affecting Firefox version 59. I am attempting to log in to a form that includes two password input fields: <input type="password" name="l ...

Steps to retrieve hexadecimal addresses sequentially

Can anyone recommend a module or script that can generate sequential 64-bit hex addresses like the following: 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 00000000000 ...

Extracting identification values from an Array with Java

I need help filtering out the id value that corresponds with a specific variable and returning that id. result = { "drives": [{ "id": "0AEz3mOk9PVA", "name": "Dev2020-10" }, { ...