Java Rest API with sqlite and simple web frontend
This commit is contained in:
commit
10011418f5
49
pom.xml
Normal file
49
pom.xml
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||||
|
http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.test</groupId>
|
||||||
|
<artifactId>java-project</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>java-project</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.javalin</groupId>
|
||||||
|
<artifactId>javalin</artifactId>
|
||||||
|
<version>5.6.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.15.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xerial</groupId>
|
||||||
|
<artifactId>sqlite-jdbc</artifactId>
|
||||||
|
<version>3.45.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.10.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>17</source>
|
||||||
|
<target>17</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
BIN
purchase.db
Normal file
BIN
purchase.db
Normal file
Binary file not shown.
72
src/main/java/com/curlCommand.md
Normal file
72
src/main/java/com/curlCommand.md
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
CURL COMMAND TUTORIAL
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:7070/total
|
||||||
|
```
|
||||||
|
|
||||||
|
* **What it does:**
|
||||||
|
Sends an HTTP GET request to your API’s `/total` endpoint.
|
||||||
|
* **Purpose:**
|
||||||
|
Fetches the total profit so far from your server.
|
||||||
|
* **Response you got:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"totalProfit":12000.0}
|
||||||
|
```
|
||||||
|
|
||||||
|
This means the total sum of all purchased products recorded so far is ₹12,000.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:7070/turl -X POST http://localhost:7070/purchase -H "Content-Type: application/json" -d '{"product":"Camera Drone","price":12000}'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **What you tried to do:**
|
||||||
|
Looks like you tried to send a POST request to `/purchase` to add a new product "Camera Drone" priced at 12000.
|
||||||
|
|
||||||
|
* **Why it’s wrong / problematic:**
|
||||||
|
The syntax is incorrect and malformed. You are mixing a GET request to `/turl` with `-X POST http://localhost:7070/purchase`, which doesn’t make sense for `curl`.
|
||||||
|
The command has extra URL (`http://localhost:7070/purchase`) placed incorrectly after `-X POST`, which should only be followed by the HTTP method, not another URL.
|
||||||
|
|
||||||
|
* **Correct form:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:7070/purchase -H "Content-Type: application/json" -d '{"product":"Camera Drone","price":12000}'
|
||||||
|
```
|
||||||
|
|
||||||
|
* This correctly sends a POST request to `/purchase` endpoint with a JSON body specifying the product and price.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### Summary of key curl options used:
|
||||||
|
|
||||||
|
* `curl [URL]` — by default, sends a GET request to the URL.
|
||||||
|
|
||||||
|
* `-X POST` — explicitly sets HTTP method to POST (used to send data).
|
||||||
|
|
||||||
|
* `-H "Content-Type: application/json"` — adds HTTP header specifying the request body is JSON.
|
||||||
|
|
||||||
|
* `-d '{"product":"Camera Drone","price":12000}'` — the JSON data to send in the body of the POST request.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
If you want to test adding a new purchase and then check total, this sequence is correct:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:7070/purchase -H "Content-Type: application/json" -d '{"product":"Camera Drone","price":12000}'
|
||||||
|
curl http://localhost:7070/total
|
||||||
|
```
|
||||||
|
|
||||||
|
This will record the new product and then return the updated total profit.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
If you want, I can help you build some shell scripts or alias commands to make testing easier! Just say the word.
|
114
src/main/java/com/test/App.java
Normal file
114
src/main/java/com/test/App.java
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
package com.test;
|
||||||
|
|
||||||
|
//Custom Classes Imported below
|
||||||
|
import com.test.PurchaseDAO;
|
||||||
|
|
||||||
|
// Import necessary classes
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import io.javalin.Javalin;
|
||||||
|
import io.javalin.http.Context;
|
||||||
|
import io.javalin.plugin.bundled.CorsPluginConfig;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
// Create a Constructor object to hold user and product info
|
||||||
|
Constructor construct = new Constructor("Arul", 24, "India, TN");
|
||||||
|
|
||||||
|
// Counter to track number of products purchased
|
||||||
|
int productIndex = 0;
|
||||||
|
|
||||||
|
// Map to store product name as key and price as value
|
||||||
|
Map<String, Double> purchasedProductDetails = new HashMap<>();
|
||||||
|
|
||||||
|
// Scanner object to read input from console
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
|
||||||
|
PurchaseDAO db = new PurchaseDAO(); // Initializing DB
|
||||||
|
|
||||||
|
// Method to record a purchase
|
||||||
|
public void recordPurchase(String product, double price) {
|
||||||
|
productIndex++; // Increment product count
|
||||||
|
construct.setProductName(product); // Set product name
|
||||||
|
construct.setProductPrice(price); // Set product price
|
||||||
|
construct.setTotalProductsPurchased(productIndex); // Update total
|
||||||
|
makeList(); // Add to local Map
|
||||||
|
db.insertPurchase(product, price); // Save to DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read user input from console (for CLI use)
|
||||||
|
public void printAndRead() {
|
||||||
|
System.out.println("[+] Enter the Product " + productIndex + " Name:");
|
||||||
|
String productName = scanner.nextLine();
|
||||||
|
System.out.println("[+] Enter price of the Product");
|
||||||
|
Double productPrice = scanner.nextDouble();
|
||||||
|
scanner.nextLine(); // Consume newline
|
||||||
|
recordPurchase(productName, productPrice);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add product and price to Map
|
||||||
|
public void makeList() {
|
||||||
|
purchasedProductDetails.put(construct.getProductName(), construct.getProductPrice());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate total from DB and print
|
||||||
|
public void calculateTotalProfit() {
|
||||||
|
double sum = db.getTotalProfit(); // ✅ From DB
|
||||||
|
System.out.println("Total profit: ₹" + sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🟢 Start API server
|
||||||
|
public void startApi() {
|
||||||
|
Javalin app = Javalin.create(config -> {
|
||||||
|
// ✅ Enable CORS for frontend origin
|
||||||
|
config.plugins.enableCors(cors -> {
|
||||||
|
cors.add(CorsPluginConfig::anyHost); // Or use allowHost("http://localhost:8080")
|
||||||
|
});
|
||||||
|
}).start(7070);
|
||||||
|
|
||||||
|
// Set JSON response type
|
||||||
|
app.before(ctx -> ctx.contentType("application/json"));
|
||||||
|
|
||||||
|
// 🔸 POST /purchase → Record purchase
|
||||||
|
app.post("/purchase", ctx -> {
|
||||||
|
Map<String, Object> data = ctx.bodyAsClass(Map.class);
|
||||||
|
String product = data.get("product").toString();
|
||||||
|
double price = Double.parseDouble(data.get("price").toString());
|
||||||
|
recordPurchase(product, price);
|
||||||
|
ctx.status(200).result("Recorded: " + product + " for ₹" + price);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 🔹 GET /total → Return total profit
|
||||||
|
app.get("/total", ctx -> {
|
||||||
|
double sum = db.getTotalProfit();
|
||||||
|
ctx.json(Map.of(
|
||||||
|
"totalProfit", sum,
|
||||||
|
"customerName", construct.name,
|
||||||
|
"customerAge", construct.age,
|
||||||
|
"customerRegion", construct.region
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🚀 Main Method
|
||||||
|
public static void main(String[] args) {
|
||||||
|
App app = new App();
|
||||||
|
app.startApi(); // Start server
|
||||||
|
|
||||||
|
// Optional CLI (not needed for frontend, just for manual entry)
|
||||||
|
int flag = 0;
|
||||||
|
while (flag != 1) {
|
||||||
|
System.out.println("Proceed Adding Products? (Y/N)");
|
||||||
|
String userInput = app.scanner.nextLine();
|
||||||
|
if (userInput.equalsIgnoreCase("Y")) {
|
||||||
|
app.printAndRead();
|
||||||
|
} else {
|
||||||
|
app.calculateTotalProfit();
|
||||||
|
flag = 1;
|
||||||
|
app.scanner.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
62
src/main/java/com/test/Constructor.java
Normal file
62
src/main/java/com/test/Constructor.java
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
package com.test;
|
||||||
|
|
||||||
|
public class Constructor {
|
||||||
|
|
||||||
|
// User info fields
|
||||||
|
String name;
|
||||||
|
int age;
|
||||||
|
String region;
|
||||||
|
|
||||||
|
// Product-related fields (private for encapsulation)
|
||||||
|
private String purchaseProduct;
|
||||||
|
private double productPrice;
|
||||||
|
private double profitOfTheDay;
|
||||||
|
private int totalProductsPurchased;
|
||||||
|
|
||||||
|
// Constructor to initialize user details
|
||||||
|
public Constructor(String name, int age, String region) {
|
||||||
|
this.age = age;
|
||||||
|
this.name = name;
|
||||||
|
this.region = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getter for product name
|
||||||
|
public String getProductName() {
|
||||||
|
return purchaseProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getter for product price
|
||||||
|
public double getProductPrice() {
|
||||||
|
return productPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getter for profit of the day (not used yet in App)
|
||||||
|
public double getProfitOfTheDay() {
|
||||||
|
return profitOfTheDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setter for product name
|
||||||
|
public void setProductName(String purchaseProduct) {
|
||||||
|
this.purchaseProduct = purchaseProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setter for product price
|
||||||
|
public void setProductPrice(double productPrice) {
|
||||||
|
this.productPrice = productPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setter for profit of the day
|
||||||
|
public void setProfitOfTheDay(double profitOfTheDay) {
|
||||||
|
this.profitOfTheDay = profitOfTheDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setter for total products purchased
|
||||||
|
public void setTotalProductsPurchased(int totalProductsPurchased) {
|
||||||
|
this.totalProductsPurchased = totalProductsPurchased;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getter for total products purchased
|
||||||
|
public int getTotalProductsPurchased() {
|
||||||
|
return totalProductsPurchased;
|
||||||
|
}
|
||||||
|
}
|
57
src/main/java/com/test/PurchaseDAO.java
Normal file
57
src/main/java/com/test/PurchaseDAO.java
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package com.test;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class PurchaseDAO {
|
||||||
|
|
||||||
|
private static final String DB_URL = "jdbc:sqlite:purchase.db";
|
||||||
|
|
||||||
|
public PurchaseDAO(){
|
||||||
|
try(Connection conn = DriverManager.getConnection(DB_URL);
|
||||||
|
Statement stmt = conn.createStatement())
|
||||||
|
{
|
||||||
|
String sql = "CREATE TABLE IF NOT EXISTS purchases ("
|
||||||
|
+ "id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||||
|
+ "product TEXT NOT NULL,"
|
||||||
|
+ "price REAL NOT NULL);";
|
||||||
|
stmt.execute(sql);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(SQLException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertPurchase(String product, double price){
|
||||||
|
|
||||||
|
String sql = "INSERT INTO purchases (product, price) VALUES (?,?)";
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL);
|
||||||
|
PreparedStatement pstmt = conn.prepareStatement(sql)){
|
||||||
|
|
||||||
|
pstmt.setString(1, product);
|
||||||
|
pstmt.setDouble(2, price);
|
||||||
|
pstmt.executeUpdate();
|
||||||
|
}
|
||||||
|
catch(SQLException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getTotalProfit(){
|
||||||
|
|
||||||
|
double total = 0;
|
||||||
|
String sql = "SELECT SUM(price) FROM purchases";
|
||||||
|
try(Connection conn = DriverManager.getConnection(DB_URL);
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
ResultSet res = stmt.executeQuery(sql)){
|
||||||
|
if(res.next()){
|
||||||
|
total = res.getDouble(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(SQLException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
54
src/main/java/com/test/frontend/app.js
Normal file
54
src/main/java/com/test/frontend/app.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Wait until the DOM (HTML page) is fully loaded
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
// Grab form elements and buttons
|
||||||
|
const form = document.getElementById("purchaseForm");
|
||||||
|
const resultDiv = document.getElementById("result");
|
||||||
|
const totalBtn = document.getElementById("totalBtn");
|
||||||
|
|
||||||
|
// 🟩 Handle form submission (Add new Purchase)
|
||||||
|
form.addEventListener("submit", function (event) {
|
||||||
|
event.preventDefault(); // Prevent page refresh
|
||||||
|
|
||||||
|
// Get product and price values from form
|
||||||
|
const product = document.getElementById("product").value;
|
||||||
|
const price = parseFloat(document.getElementById("price").value);
|
||||||
|
|
||||||
|
const data = { product: product, price: price };
|
||||||
|
|
||||||
|
// Send POST request to /purchase endpoint
|
||||||
|
fetch("http://localhost:7070/purchase", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then(function (response) {
|
||||||
|
return response.text(); // Expecting plain text response
|
||||||
|
})
|
||||||
|
.then(function (data) {
|
||||||
|
resultDiv.innerText = data; // Show server response
|
||||||
|
form.reset(); // Clear form inputs
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
resultDiv.innerText = "Error: " + error; // Show error if any
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 🟦 Handle "Show Total Profit" button click (GET from /total)
|
||||||
|
totalBtn.addEventListener("click", function () {
|
||||||
|
fetch("http://localhost:7070/total")
|
||||||
|
.then((response) => response.json()) // Expect JSON response
|
||||||
|
.then((data) => {
|
||||||
|
// Format and display returned data
|
||||||
|
const output = `
|
||||||
|
Name: ${data.customerName}
|
||||||
|
Age: ${data.customerAge}
|
||||||
|
Region: ${data.customerRegion}
|
||||||
|
Total Profit: ₹${data.totalProfit}
|
||||||
|
`;
|
||||||
|
resultDiv.innerText = output;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
resultDiv.innerText = "Error: " + error; // Display fetch error
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
37
src/main/java/com/test/frontend/index.html
Normal file
37
src/main/java/com/test/frontend/index.html
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Purchase Tracker</title>
|
||||||
|
|
||||||
|
<!-- Link CSS -->
|
||||||
|
<link rel="stylesheet" href="styles.css" />
|
||||||
|
|
||||||
|
<!-- Link JS (corrected attribute typo: 'data-jslicence' to 'data-jslicense') -->
|
||||||
|
<script src="app.js" defer data-jslicense="MIT"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Product Purchase Tracker</h1>
|
||||||
|
|
||||||
|
<!-- Purchase form -->
|
||||||
|
<form id="purchaseForm">
|
||||||
|
<label for="product">Product Name:</label>
|
||||||
|
<input type="text" id="product" name="product" required />
|
||||||
|
|
||||||
|
<label for="price">Price (₹):</label>
|
||||||
|
<input type="number" id="price" name="price" step="0.01" required />
|
||||||
|
|
||||||
|
<button type="submit">Add Purchase</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Button to fetch total -->
|
||||||
|
<button id="totalBtn">Show Total Profit</button>
|
||||||
|
|
||||||
|
<!-- Result will be shown here -->
|
||||||
|
<div id="result"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
28
src/main/java/com/test/frontend/styles.css
Normal file
28
src/main/java/com/test/frontend/styles.css
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 500px;
|
||||||
|
margin: auto;
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* optional visual polish */
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result {
|
||||||
|
margin-top: 20px;
|
||||||
|
white-space: pre-wrap; /* keep newlines and wrap long lines */
|
||||||
|
}
|
72
target/classes/com/curlCommand.md
Normal file
72
target/classes/com/curlCommand.md
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
CURL COMMAND TUTORIAL
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:7070/total
|
||||||
|
```
|
||||||
|
|
||||||
|
* **What it does:**
|
||||||
|
Sends an HTTP GET request to your API’s `/total` endpoint.
|
||||||
|
* **Purpose:**
|
||||||
|
Fetches the total profit so far from your server.
|
||||||
|
* **Response you got:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"totalProfit":12000.0}
|
||||||
|
```
|
||||||
|
|
||||||
|
This means the total sum of all purchased products recorded so far is ₹12,000.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:7070/turl -X POST http://localhost:7070/purchase -H "Content-Type: application/json" -d '{"product":"Camera Drone","price":12000}'
|
||||||
|
```
|
||||||
|
|
||||||
|
* **What you tried to do:**
|
||||||
|
Looks like you tried to send a POST request to `/purchase` to add a new product "Camera Drone" priced at 12000.
|
||||||
|
|
||||||
|
* **Why it’s wrong / problematic:**
|
||||||
|
The syntax is incorrect and malformed. You are mixing a GET request to `/turl` with `-X POST http://localhost:7070/purchase`, which doesn’t make sense for `curl`.
|
||||||
|
The command has extra URL (`http://localhost:7070/purchase`) placed incorrectly after `-X POST`, which should only be followed by the HTTP method, not another URL.
|
||||||
|
|
||||||
|
* **Correct form:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:7070/purchase -H "Content-Type: application/json" -d '{"product":"Camera Drone","price":12000}'
|
||||||
|
```
|
||||||
|
|
||||||
|
* This correctly sends a POST request to `/purchase` endpoint with a JSON body specifying the product and price.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### Summary of key curl options used:
|
||||||
|
|
||||||
|
* `curl [URL]` — by default, sends a GET request to the URL.
|
||||||
|
|
||||||
|
* `-X POST` — explicitly sets HTTP method to POST (used to send data).
|
||||||
|
|
||||||
|
* `-H "Content-Type: application/json"` — adds HTTP header specifying the request body is JSON.
|
||||||
|
|
||||||
|
* `-d '{"product":"Camera Drone","price":12000}'` — the JSON data to send in the body of the POST request.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
If you want to test adding a new purchase and then check total, this sequence is correct:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:7070/purchase -H "Content-Type: application/json" -d '{"product":"Camera Drone","price":12000}'
|
||||||
|
curl http://localhost:7070/total
|
||||||
|
```
|
||||||
|
|
||||||
|
This will record the new product and then return the updated total profit.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
If you want, I can help you build some shell scripts or alias commands to make testing easier! Just say the word.
|
BIN
target/classes/com/test/App.class
Normal file
BIN
target/classes/com/test/App.class
Normal file
Binary file not shown.
BIN
target/classes/com/test/Constructor.class
Normal file
BIN
target/classes/com/test/Constructor.class
Normal file
Binary file not shown.
BIN
target/classes/com/test/PurchaseDAO.class
Normal file
BIN
target/classes/com/test/PurchaseDAO.class
Normal file
Binary file not shown.
54
target/classes/com/test/frontend/app.js
Normal file
54
target/classes/com/test/frontend/app.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Wait until the DOM (HTML page) is fully loaded
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
// Grab form elements and buttons
|
||||||
|
const form = document.getElementById("purchaseForm");
|
||||||
|
const resultDiv = document.getElementById("result");
|
||||||
|
const totalBtn = document.getElementById("totalBtn");
|
||||||
|
|
||||||
|
// 🟩 Handle form submission (Add new Purchase)
|
||||||
|
form.addEventListener("submit", function (event) {
|
||||||
|
event.preventDefault(); // Prevent page refresh
|
||||||
|
|
||||||
|
// Get product and price values from form
|
||||||
|
const product = document.getElementById("product").value;
|
||||||
|
const price = parseFloat(document.getElementById("price").value);
|
||||||
|
|
||||||
|
const data = { product: product, price: price };
|
||||||
|
|
||||||
|
// Send POST request to /purchase endpoint
|
||||||
|
fetch("http://localhost:7070/purchase", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then(function (response) {
|
||||||
|
return response.text(); // Expecting plain text response
|
||||||
|
})
|
||||||
|
.then(function (data) {
|
||||||
|
resultDiv.innerText = data; // Show server response
|
||||||
|
form.reset(); // Clear form inputs
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
resultDiv.innerText = "Error: " + error; // Show error if any
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 🟦 Handle "Show Total Profit" button click (GET from /total)
|
||||||
|
totalBtn.addEventListener("click", function () {
|
||||||
|
fetch("http://localhost:7070/total")
|
||||||
|
.then((response) => response.json()) // Expect JSON response
|
||||||
|
.then((data) => {
|
||||||
|
// Format and display returned data
|
||||||
|
const output = `
|
||||||
|
Name: ${data.customerName}
|
||||||
|
Age: ${data.customerAge}
|
||||||
|
Region: ${data.customerRegion}
|
||||||
|
Total Profit: ₹${data.totalProfit}
|
||||||
|
`;
|
||||||
|
resultDiv.innerText = output;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
resultDiv.innerText = "Error: " + error; // Display fetch error
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
37
target/classes/com/test/frontend/index.html
Normal file
37
target/classes/com/test/frontend/index.html
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Purchase Tracker</title>
|
||||||
|
|
||||||
|
<!-- Link CSS -->
|
||||||
|
<link rel="stylesheet" href="styles.css" />
|
||||||
|
|
||||||
|
<!-- Link JS (corrected attribute typo: 'data-jslicence' to 'data-jslicense') -->
|
||||||
|
<script src="app.js" defer data-jslicense="MIT"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Product Purchase Tracker</h1>
|
||||||
|
|
||||||
|
<!-- Purchase form -->
|
||||||
|
<form id="purchaseForm">
|
||||||
|
<label for="product">Product Name:</label>
|
||||||
|
<input type="text" id="product" name="product" required />
|
||||||
|
|
||||||
|
<label for="price">Price (₹):</label>
|
||||||
|
<input type="number" id="price" name="price" step="0.01" required />
|
||||||
|
|
||||||
|
<button type="submit">Add Purchase</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Button to fetch total -->
|
||||||
|
<button id="totalBtn">Show Total Profit</button>
|
||||||
|
|
||||||
|
<!-- Result will be shown here -->
|
||||||
|
<div id="result"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
28
target/classes/com/test/frontend/styles.css
Normal file
28
target/classes/com/test/frontend/styles.css
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 500px;
|
||||||
|
margin: auto;
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* optional visual polish */
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result {
|
||||||
|
margin-top: 20px;
|
||||||
|
white-space: pre-wrap; /* keep newlines and wrap long lines */
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
com/test/PurchaseDAO.class
|
||||||
|
com/test/App.class
|
||||||
|
com/test/Constructor.class
|
|
@ -0,0 +1,3 @@
|
||||||
|
/home/arul/apiServerProject/java-project/src/main/java/com/test/App.java
|
||||||
|
/home/arul/apiServerProject/java-project/src/main/java/com/test/Constructor.java
|
||||||
|
/home/arul/apiServerProject/java-project/src/main/java/com/test/PurchaseDAO.java
|
Loading…
Reference in New Issue
Block a user