Showing posts with label JSP. Show all posts
Showing posts with label JSP. Show all posts

Chrome vs Firefox : jQuery faceoff (how range selection behaves differently in these 2 browsers)


Hello Buddies.

Long time since last post.

I want to share an interesting scenario I encountered few days back related to UI.

Scenario –
There are 2 multiple select boxes available on the JSP, in such a way that you can filter the data from the first one, using one regex, select a range of filtered out options and push them towards the second one.

Seems easy in the first shot. Isn’t it?

I used jQuery for this and implemented it, for some POC, as follows -


So what we have in the first select box is -

'ABC intDEF',
'XYZ intABC',
'qwerty',
'abcdefgh',
'blah blah intDUMMY',
'blah blah hello',
'hello int'


I need to filter only those values having ‘int’, by hiding the non-matching ones.
Now the box would be showing -

'ABC intDEF',
'XYZ intABC',
'blah blah intDUMMY',
'hello int'

Shift + select End-To-End and append in the second box.

So far, looks good.


Try this code in Chrome, it will look perfect.



But now comes the interesting part, try in Mozilla Firefox, and inspect the second box.

“BOOM”




All those values that were hidden due to filter in the first box, have also been included if present within the range. What it can lead to is the angry set of users who prefer Firefox. :P


Clearly, Chrome is able to understand not to include hidden options, while Firefox fails here, and being a browser issue, it becomes difficult to comprehend.


What can be done?

A neat and clean work-around!

function pushSelectedToRight(pushObj) {
pushObj = $(pushObj);
var leftBox = $("#tempLeft");
var rightBox = $("#tempRight");
if(leftBox.find("option:selected").length > 0){
var tmp = leftBox.find("option:selected");
tmp.each(function() {
        if($(this).css("display")=="block"){
    rightBox.append($(this));
    }
    });
  rightBox.find("option").removeAttr("selected");
}
else{
alert("Please select atleast one item to move");
}
}

Speaking in terms of jQuery, it selects out the values using selected flag - leftBox.find("option:selected")

Apart from this better use ‘each’ method as well for checking the visible elements.
It won’t cause any issue on the Chrome side, but will also work for Firefox -

var tmp = leftBox.find("option:selected");
tmp.each(function() {
        if($(this).css("display")=="block"){
    rightBox.append($(this));
    }
    });

And this is how a day is saved!

Happy Coding!!

JSP and POJO


Hello Buddies


A quick tutorial this time, for buddies not comfortable with the concepts of MVC and Servlets, and want to access Java classes with JSPs.

For your reference -

https://github.com/namitsharma99/jspPojoExample.git



1st JSPs -

myForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Enter the form details here</title>
</head>
<body>
<form action="processForm.jsp">
<label>Enter the info</label>
<input type="text" name="info">
<input type="submit" value="Submit!">
</form>
</body>
</html>



POJO class -

MyPojo.java


package com.java;

public class MyPojo {

private String info;

public String getInfo() {
System.out.println("Getter called!");
return info;
}

public void setInfo(String info) {
System.out.println("Setter called!");
this.info = info;
}

}



2nd JSP -

processForm.jsp 


<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.java.MyPojo"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Form Processed!!</title>
</head>
<body>
<jsp:useBean id="myBean" class="com.java.MyPojo">
<jsp:setProperty name="myBean" property="info" />
<jsp:getProperty name="myBean" property="info" />
</jsp:useBean>
</body>
</html>


Run the form jsp on the localhost server and ENJOY the output.

http://localhost:xxxx/jspAndPojo/myForm.jsp

>>

http://localhost:xxxx/jspAndPojo/processForm.jsp?info=hello


>> hello

Javascript Debugging & Mathematical Operators



Hello Buddies,


Here are 2 javascript encounters, few more are about to come.



1. While working with JSP and JS, a person habitual of using debug mode in Eclipse, might feel that something is missing, in understanding the UI flow.


For such incidents, one can always use either of the ways to confirm what values are being set or how the flow is being considered.

Common UI debugging techniques -


1. console.log() - to print variables’ values in javascripts, without impacting the UI.

2. F12 debugs – it gives you power to put breakpoints in the scripts listed in ‘sources’ window, check the requests and responses of various APIs invoked, time taken for the calls made, as well as make minor changes in the style section, or other HTML components.

3. document.write() – it writes any value you want to display on the UI, without any format.

4. alert() - it shows the immediate values of javascripts’ variables, and this method is often used by developers to make sure if the desired javascript is invoked.




2. Secondly, while having the hands on with some javascript basics, encountered a behavior which I felt might come handy in evaluating javascript skills.


Quoted literals (either single or double quotes), in a mathematical expression, will make the entire line as a string, somewhat like concatenation, as far as I could understand.


Following are some observations -

2 + 3 * 5 = 17
'2' + 3 * 5 = 215
'2' + '3' * 5 = 215
'2' + '3' * '5' = 215
'2' + '3' - '5' = 18
'2' + '3' / '5' = 20.6


So beware of such scenarios if asked. What we observed here is that though the literals are being regarded as string, but that holds true only or ‘+’ operator. For any other mathematical operator, literals are still regarded as numbers, and the results will be accordingly. Please have a thorough look at the above results.


Feel free to put your inputs.

Happy coding.

RESTFul CRUD with a pinch of AJAX and Hibernate





Hello Buddies...



Let's try something bigger this time.




A commonly known task developers generally come across for sure, in their coding tenure, is working with the REST APIs.



While consuming these can be easy, thanks to various tools like POSTMAN and SOAPUI, what can be challenging is writing these APIs. We can go through so many online materials available these days that can share ins and outs of the REST architecture, but what we want is to save time and get the code working. So here we set the stage for this discussion.



What I am going to follow is an approach that will pick 4 commonly asked-for HTTP methods - POST, GET, PUT, DELETE (for Create, Read, Update and Delete respectively), with a few bonus code snippets for you - using AJAX for making calls from the JSPs and our very own Mr. Popular - Hibernate. This will make you get your hands dirty, over the journey, with database related tasks using Hibernate and MySQL workbench.



The above plan is not going to cost you anything, but it demands satisfactory code writing and mind-boggling for behind the scenes' theory.




The working code is available @







You are welcome if you still wish to have a discussion. Let's start.




1. Do we have DB ready?



Make good use of MySQL workbench and have a local schema up and available with your table that you wish to use further.



Here, we have 'myEmployees' under 'namit_schema' and the table records will be impacted by the CRUD UI operations.



A snapshot of the table currently in my local -




CREATE TABLE `myEmployees` (
`id` int(11) NOT NULL,
`firstName` varchar(255) DEFAULT NULL,
`lastName` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SELECT `myEmployees`.`id`,
`myEmployees`.`firstName`,
`myEmployees`.`lastName`
FROM `namit_schema`.`myEmployees`;




Don't mind the vague entries :P


Please note - Keep the DB credentials handy.




2.  Are we ready to integrate our JAVA code with the DB?



For fun, we will be using Hibernate for this task. You are free to use other techniques like pure JDBC or JPA.



Following some commonly available tutorials, I saved time and got the hibernate connection up and running.



Please note - Since consuming requisite jars can be a headache, hence it's always better to go for a maven project with the dependencies listed in pom.xml.



POM.xml


<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>RestPathAnnotationExample</groupId>
<artifactId>RestPathAnnotationExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.6.Final</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0-b01</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.17.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>

</dependencies>

</project>









Create the backing bean





package com.myBeans;
public class Employee {
private int id;
private String firstName, lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}



Set up the 2 essential XMLs here -



a. employee.hbm.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.myBeans.Employee" table="myEmployees">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="firstName"></property>
<property name="lastName"></property>
</class>
</hibernate-mapping>



b. hibernate.cfg.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hbm2ddl.auto">update</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.url">jdbc:mysql://localhost:XXXX/namit_schema</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<mapping resource="employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>



3. Can we create layers of abstraction and logic segregation?



Why not. As a good practice, have atleast 3 layers (especially for enterprise app projects). Here we can have Service Classes <-> Facade Layers <-> DAO Layers.





EmployeeService.java 



This class will provide you the API declarations and will help in providing endpoints per various http methods.


package com.myCode;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import org.json.simple.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.myFacade.ServiceFacade;
/**
 * @author namit
 *
 * */
@Path("/employees")
public class EmployeeService {
/* Landing page configured = http://localhost:XXXX/RestPathAnnotationExample/
* Can be changed in web.xml (welcome.jsp) */
/**
*
* This is a default message providing method
* Can be checked using - http://localhost:XXXX/RestPathAnnotationExample/rest/employees
*
* */
@GET
@Produces("text/html")
public Response testMethod() {
String output = "this is employee service test...";
return Response.status(200).entity(output).build();
}
/**
*
* This is a method to fetch the list of employees available
* Can be checked using - http://localhost:XXXX/RestPathAnnotationExample/rest/employees/list
*
* */
@GET
@Path("list")
@Produces("application/json")
public Response getEmployees() {
ServiceFacade serviceFacade = new ServiceFacade();
String output = null;
HashMap<String, String> errorMap = new HashMap<String, String>();
errorMap.put("Error", "No Record Found!");
JSONObject jsonError = new JSONObject(errorMap);
try {
output = serviceFacade.getEmployees();
if (null == output || output.isEmpty()) {
output = jsonError.toJSONString();
}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println("JSON list = " + output);
return Response.status(200).entity(output).build();
}
/**
*
* This is a method to persist new employee's details
* Can be checked using - http://localhost:XXXX/RestPathAnnotationExample/rest/employees/save
*
* */
@POST
@Path("/save")
@Consumes("application/json")
public Response saveEmployee(String str) {
String[] inputArray = str.split("&");
String fname = inputArray[0].split("=")[1];
String lname = inputArray[1].split("=")[1];
String result = "Record created : " + str;
Map<String, Object> map = new HashMap<String, Object>();
map.put("firstname", fname);
map.put("lastname", lname);
ServiceFacade serviceFacade = new ServiceFacade();
serviceFacade.saveEmployees(map);
return Response.status(201).entity(result).build();
}
/**
*
* This is a method to update an existing employee, identified using employee id
* Can be checked using - http://localhost:XXXX/RestPathAnnotationExample/rest/employees/update
*
* */
@PUT
@Path("/update")
@Consumes("application/json")
public Response updateEmployee(String str) {
String[] inputArray = str.split("&");
String id = inputArray[0].split("=")[1];
String fname = inputArray[1].split("=")[1];
String lname = inputArray[2].split("=")[1];
String result = "Record updated : " + str;
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", id);
map.put("firstname", fname);
map.put("lastname", lname);
ServiceFacade serviceFacade = new ServiceFacade();
serviceFacade.updateEmployees(map);
return Response.status(201).entity(result).build();
}
/**
*
* This is a method to delete an employee, identified by employee id
* Can be checked using - http://localhost:XXXX/RestPathAnnotationExample/rest/employees/delete
*
* */
@DELETE
@Path("/delete")
@Consumes("application/json")
public Response deleteEmployee(String str) {
String result = "Record deleted : " + str;
int i = Integer.valueOf(str.split("=")[1]);
ServiceFacade serviceFacade = new ServiceFacade();
serviceFacade.deleteEmployee(i);
return Response.status(200).entity(result).build();
}
}


ServiceFacade.java - 

This class acts as an intermediate step while passing data from front end to the backend and vice versa. It can be advantageous if we need to alter the request/ response as per destination methods.

package com.myFacade;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.myBeans.Employee;
import com.myDB.ServiceDAO;
/**
 * @author namit
 *
 * */
public class ServiceFacade {
public String getEmployees() throws JsonProcessingException {
ServiceDAO serviceDAO = new ServiceDAO();
List<Employee> ls = serviceDAO.getEmployees();
ObjectMapper objectMapper = new ObjectMapper();
String jsonStr = objectMapper.writeValueAsString(ls);
return jsonStr;
}
public void saveEmployees(Map<String, Object> map) {
ServiceDAO serviceDAO = new ServiceDAO();
serviceDAO.saveEmployees(map);
}
public void updateEmployees(Map<String, Object> map) {
ServiceDAO serviceDAO = new ServiceDAO();
serviceDAO.updateEmployees(map);
}
public void deleteEmployee(int i) {
ServiceDAO serviceDAO = new ServiceDAO();
serviceDAO.deleteEmployee(i);
}
}
ServiceDAO.java -
This class holds the important DB related code.
package com.myDB;
import java.util.List;
import java.util.Map;
import org.hibernate.Query;
import org.hibernate.Session;
import com.connectors.HibernateConnector;
import com.myBeans.Employee;
/**
 * @author namit
 *
 * */
@SuppressWarnings("deprecation")
public class ServiceDAO {
@SuppressWarnings({ "unchecked" })
public List<Employee> getEmployees() {
Session session = null;
session = HibernateConnector.getInstance().getSession();
Query<Employee> q = session.createQuery("from Employee emp");
List<Employee> qList = q.list();
if (qList != null && qList.isEmpty()) {
return null;
} else {
System.out.println("list " + qList);
return (List<Employee>) qList;
}
}
public void saveEmployees(Map<String, Object> map) {
Session session = HibernateConnector.getInstance().getSession();
session.beginTransaction();
String fname = (String) map.get("firstname");
String lname = (String) map.get("lastname");
Employee employee = new Employee();
employee.setFirstName(fname);
employee.setLastName(lname);
session.save(employee);
session.getTransaction().commit();
session.close();
}
public void updateEmployees(Map<String, Object> map) {
Session session = HibernateConnector.getInstance().getSession();
session.beginTransaction();
int id = Integer.valueOf((String) map.get("id"));
String fname = (String) map.get("firstname");
String lname = (String) map.get("lastname");
Employee employee = new Employee();
employee.setId(id);
employee.setFirstName(fname);
employee.setLastName(lname);
session.update(employee);
session.getTransaction().commit();
session.close();
}
public void deleteEmployee(int i) {
Session session = HibernateConnector.getInstance().getSession();
session.beginTransaction();
Object o = session.load(Employee.class, new Integer(i));
Employee e = (Employee) o;
session.delete(e);
session.getTransaction().commit();
session.close();
}
}

Since we are using Hibernate for DB access, I wanted to have a common place for Hibernate connection, hence following class came into the picture.


HibernateConnector.java

package com.connectors;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateConnector {
private static HibernateConnector hibConn;
private Configuration cfg;
private SessionFactory sessionFactory;
private HibernateConnector() throws HibernateException {
cfg = new Configuration();
cfg.configure("hibernate.cfg.xml");
cfg.addResource("employee.hbm.xml");
sessionFactory = cfg.buildSessionFactory();
}
public static synchronized HibernateConnector getInstance() throws HibernateException {
if (hibConn == null) {
hibConn = new HibernateConnector();
}
return hibConn;
}
public Session getSession() throws HibernateException {
Session session = sessionFactory.openSession();
if (!session.isConnected()) {
this.reconnect();
}
return session;
}
private void reconnect() throws HibernateException {
this.sessionFactory = cfg.buildSessionFactory();
}
}


Once you have your code in place, your project folder structure may look somewhat like this -



Please ignore the com.ignore package, it was just for created to see some if-else flows, I came across in an interview for a big investment firm. Have a look if that interests you, I will share more of such questions if someone needs.
Anyway, coming back to our quest, now we have the code ready, I mean from APIs perspective.

Have a look at the javadocs for service class, you will get an idea what API to hit, to check the response directly through the browser.

Well that's said, now its time to try some UI related stuff to make you proficient at both backend as well as front end.

What I have came across so far is that majority of java developers are assigned evaluation projects during onboarding times, to come up with APIs and UI to consume them.

So the below section of the discussion will help you to get a taste of such assignment.

Have a jsp as follows -

welcome.jsp

%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Welcome Page</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
function getList() {
$("#loaderDiv").attr("style", "display: block");
var request = $.ajax({
url: "rest/employees/list",
type: "GET"
});
request.done(function(msg) {
console.log("Request successful!");
$("#loaderDiv").attr("style", "display: none");
$("#selectionDiv").attr("style", "display: block");
$("#drop").empty();
$("#drop").append($("<option></option>").val(0).html("<i> -- Employee Names -- <i>")) for (i in msg) {
$("#drop").append($("<option></option>").val(msg[i].id).html(msg[i].firstName + " " + msg[i].lastName));
}
});
request.fail(function(jqXHR, textStatus) {
$("#loaderDiv").attr("style", "display: none");
console.log("Request failed: " + textStatus);
});
}
function prepareEdit() {
$("#editDiv").attr("style", "display: block");
console.log('The option with value ' + $("#drop").val() + ' and text ' + $("#drop option:selected").text() + ' was selected.');
$("#editId").val($("#drop").val());
var fullName = $("#drop option:selected").text();
var splittedSource = fullName.replace(/\s{2,}/g, ' ').split(' ');
$("#editFName").val(splittedSource[0]);
$("#editLName").val(splittedSource[1]);
$("#storageInput").val($("#editId").val() + ":" + $("#editFName").val() + ":" + $("#editLName").val());
console.log('value stored -- ' + $("#storageInput").val());
}
function updateName() {
var temp = $("#storageInput").val();
var request = $.ajax({
url: "rest/employees/update",
type: 'PUT',
contentType: 'application/json; charset=utf-8',
data: {
id: $("#editId").val(),
fname: $("#editFName").val(),
lname: $("#editLName").val()
}
});
request.done(function(msg) {
console.log("Request successful: " + msg);
getList();
$("#editDiv").attr("style", "display: none");
});
request.fail(function(jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
}
function deleteName() {
var request = $.ajax({
url: "rest/employees/delete",
type: 'DELETE',
contentType: 'application/json; charset=utf-8',
data: {
id: $("#editId").val()
}
});
request.done(function(msg) {
console.log("Request successful: " + msg);
getList();
$("#editDiv").attr("style", "display: none");
});
request.fail(function(jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
}
function addName() {
$("#addName").attr("style", "display: block");
}
function hide() {
$("#addName").attr("style", "display: none");
}
function hide2() {
$("#editDiv").attr("style", "display: none");
$("#selectionDiv").attr("style", "display: none");
}
function add() {
var request = $.ajax({
url: "rest/employees/save",
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: {
fname: $("#addFName").val(),
lname: $("#addLName").val()
}
});
request.done(function(msg) {
console.log("Request successful: " + msg);
hide();
});
request.fail(function(jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
}
</script>
</head>
<body>
<div class="container" style="background-image:url(green2.jpg); background-position: center center; background-repeat: no-repeat; background-size: cover">
<div class="row" align="center" style="color:darkgreen">
<h3>Hello Buddies</h3>
</div>
<div class="row" align="center" style="color:gray">
<h4>Let's try some RESTFul CRUDs</h4>
</div>
<div class="row" align="center" style="display: none" id="loaderDiv"><img alt="loading" src="loadinfo.gif">
</div>
<hr>
<div class="row" align="center">
<input type="button" class="btn-success" value="Get List" onclick="getList()">
<input type="button" class="btn-success" value="Add Name" onclick="addName()"> </div>
<hr>
<div class="row" style="display: none" id="selectionDiv" align="center" class="btn-success">
<select name="Employee List" id="drop" onchange="prepareEdit()"></select>
<!-- <input type="button" class="btn-danger" onclick="hide2()" value="Click to Hide"><br> -->
<a href="#" onclick="hide2()" style="color: red; font-size: 18px"> <span class="glyphicon glyphicon-remove-sign"></span> </a>
<br> </div>
<hr>
<div class="row" style="display: none" id="editDiv" align="center">
<label>EmpID : </label>
<input id="editId" disabled="disabled">
<br>
<label>FNAME : </label>
<input id="editFName">
<br>
<label>LNAME : </label>
<input id="editLName">
<br>
<label>EDIT : </label>
<input type="button" class="btn-success" onclick="updateName()" value="Click to Save">
<br>
<label>DELETE : </label>
<input type="button" class="btn-success" onclick="deleteName()" value="Click to Delete">
<br>
<!-- option to use for using hidden variable as local storage -->
<input type="text" style="display: none" id="storageInput"> </div>
<hr>
<div class="row" style="display: none" id="addName" align="center">
<label>FNAME :</label>
<input id="addFName">
<br>
<label>LNAME :</label>
<input id="addLName">
<br>
<label>ADD : </label>
<input type="button" class="btn-success" onclick="add()" value="Click to Add">
<!-- <input type="button" class="btn-danger" onclick="hide()" value="Click to Hide"><br> -->
<a href="#" onclick="hide()" style="color: red; font-size: 18px"> <span class="glyphicon glyphicon-remove-sign"></span> </a>
<br> </div>
</div>
</body>
</html>

And web.xml entries as follows -

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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" id="WebApp_ID" version="3.1">
<display-name>RestPathAnnotationExample</display-name>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.myCode</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>welcome.jsp</welcome-file>
</welcome-file-list>
</web-app>



This will give your application a nice UI for interacting with the APIs already created. Some of the screenshots I took while going through this app are -





So buddies, go ahead and try this out. 

We will soon discuss about the UI components, why they are being used and how they are makig life easier.

Your suggestions and thoughts are always welcome, and will surely improve my knowledge as well. ;)

Happy Coding....





Featured post

Oracle SQL Scheduled Jobs - An Interesting Approach

  Oracle SQL Scheduled Jobs A DB Scheduler is the best way to automate any backend database job. For instance, if you want to process the p...