?在数据库中创建表(表名最好为单数英文形式)
CREATE TABLE `book` (
`bid` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
`author` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`status` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`title` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
PRIMARY KEY (`bid`) USING BTREE
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
;
在NetBeans IDE中创建maven web应用
?
?
?
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<!-- Define Persistence Unit -->
<persistence-unit name="my_persistence_unit" transaction-type="JTA">
<!-- <jta-data-source>java:app/ee</jta-data-source>-->
<jta-data-source>java:/MySqlDS</jta-data-source>
<properties>
</properties>
</persistence-unit>
</persistence>
?把?@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})修改成
? ? @Produces({MediaType.APPLICATION_JSON}),仅使用JSON输出,如下:
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package com.example.bookrestwildfly.service;
import com.example.bookrestwildfly.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
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.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
*
* @author Administrator
*/
@Stateless
@Path("com.example.bookrestwildfly.book")
public class BookFacadeREST extends AbstractFacade<Book> {
@PersistenceContext(unitName = "com.example_bookrestwildfly_war_1.0-SNAPSHOTPU")
private EntityManager em;
public BookFacadeREST() {
super(Book.class);
}
@POST
@Override
@Consumes({MediaType.APPLICATION_JSON})
public void create(Book entity) {
super.create(entity);
}
@PUT
@Path("{id}")
@Consumes({MediaType.APPLICATION_JSON})
public void edit(@PathParam("id") String id, Book entity) {
super.edit(entity);
}
@DELETE
@Path("{id}")
public void remove(@PathParam("id") String id) {
super.remove(super.find(id));
}
@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_JSON})
public Book find(@PathParam("id") String id) {
return super.find(id);
}
@GET
@Override
@Produces({MediaType.APPLICATION_JSON})
public List<Book> findAll() {
return super.findAll();
}
@GET
@Path("{from}/{to}")
@Produces({MediaType.APPLICATION_JSON})
public List<Book> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
return super.findRange(new int[]{from, to});
}
@GET
@Path("count")
@Produces(MediaType.TEXT_PLAIN)
public String countREST() {
return String.valueOf(super.count());
}
@Override
protected EntityManager getEntityManager() {
return em;
}
}
使用POSTMAN测试
POSTMAN会提供各种语言参考请求代码:
?编写HTML和JavaScript客户端访问API进行CRUD
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Books</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<!--New Driver Form-->
<div class="content">
<form id="new-book" method="POST" action="">
<fieldset>
<legend>New Book</legend>
<label for="new-book-bid">bid</label>
<input id="new-book-bid" type="text" name="book-bid">
<label for="new-book-author">author</label>
<input id="new-book-author" type="text" name="book-author">
<label for="new-book-status">status</label>
<input id="new-book-status" type="text" name="book-status">
<label for="new-book-status">title</label>
<input id="new-book-title" type="text" name="book-title">
<input type="submit" value="Save">
</fieldset>
</form>
</div>
<!--Drivers Table-->
<div class="content">
<div id="books-table" style="display:table;width:100%;">
<div style="display:table-row;">
<div id="book-bid-header" style="display:table-cell;"><b>bid</b></div>
<div id="book-author-header" style="display:table-cell;"><b>author</b></div>
<div id="book-status-header" style="display:table-cell;"><b>status</b></div>
<div id="book-title-header" style="display:table-cell;"><b>title</b></div>
<div id="book-udpate" style="display:table-cell;"><b> </b></div>
<div id="book-delete" style="display:table-cell;"><b> </b></div>
</div>
</div>
</div>
<!--Javascript-->
<script src="script.js"></script>
</body>
</html>
//var SERVER = 'http://localhost:3001/books';
var SERVER = 'http://localhost:8080/bookrestwildfly-1.0-SNAPSHOT/webresources/com.example.bookrestwildfly.book';
/*
Adds an event listener to the submit button. Retreieves attributes from html form and puts them
into attributes. Checks for nulls. Opens a http request and puts variables in url string. Sends
request with attributes in url string to the server. Emtpys the table and rebuilds the tale with
the update rows.
*/
function htmlCreateBook() {
// Get create form
var form = document.getElementById('new-book');
// Add create form event listener
form.addEventListener('submit', function (e) {
e.preventDefault();
var bid = document.getElementById('new-book-bid').value || null;
var author = document.getElementById('new-book-author').value || null;
var status = document.getElementById('new-book-status').value || null;
var title = document.getElementById('new-book-title').value || null;
if (bid === null || author === null || status === null || title === null) {
emptyForm();
return;
}
var data = JSON.stringify({
"bid": bid,
"author": author,
"status": status,
"title": title
});
var req = new XMLHttpRequest();
req.withCredentials = true;
var url = `${SERVER}`;
req.open('POST', url, true);
req.onload = function () {
console.log(req.status);
if (req.status === 204) {
emptyForm();
emptyBooksTable();
htmlReadBooks();
}
};
req.setRequestHeader("Content-Type", "application/json");
req.send(data);
});
}
function emptyForm() {
/**
* Empty new shift form
*/
document.getElementById('new-book-author').value = null;
document.getElementById('new-book-status').value = null;
document.getElementById('new-book-title').value = null;
}
function htmlReadBooks() {
/**
* Build books table from database read over HTML
*/
var req = new XMLHttpRequest();
req.open('GET', SERVER, true);
req.onload = function () {
if (req.status === 200) {
emptyBooksTable();
var books = JSON.parse(req.responseText);
fillBooksTable(books);
}
};
req.send();
}
function emptyBooksTable() {
/**
* Empty books table data
*/
var table = document.getElementById('books-table');
Array.from(table.children).slice(1).forEach(function () {
table.removeChild(table.children[1]);
});
}
function fillBooksTable(books) {
/**
* Fill books table with data
*/
books.forEach(function (book) {
appendBooksTableRow(book);
});
}
function appendBooksTableRow(book) {
/**
* Append books table row with data
*/
var bid = book.bid;
var author = book.author;
var status = book.status;
var title = book.title;
// Get table
var table = document.getElementById('books-table');
// Append table row
var tableRow = document.createElement('div');
tableRow.style.display = 'table-row';
tableRow.width = '100%';
tableRow.id = `row-${bid}`;
table.appendChild(tableRow);
// Append book ID table cell
var bidCell = document.createElement('div');
bidCell.style.display = 'table-cell';
var bidInput = document.createElement('input');
bidInput.id = `book-id-${bid}`;
bidInput.disabled = true;
bidInput.name = 'shift-id';
bidInput.value = bid;
bidCell.appendChild(bidInput);
tableRow.appendChild(bidCell);
// Append book first name table cell
var authorCell = document.createElement('div');
authorCell.style.display = 'table-cell';
var authorInput = document.createElement('input');
authorInput.id = `book-author-${bid}`;
authorInput.type = 'text';
authorInput.name = 'book-author';
authorInput.value = author;
authorCell.appendChild(authorInput);
tableRow.appendChild(authorCell);
// Append book last name table cell
var statusCell = document.createElement('div');
statusCell.style.display = 'table-cell';
var statusInput = document.createElement('input');
statusInput.id = `book-last-name-${bid}`;
statusInput.type = 'text';
statusInput.name = 'book-status';
statusInput.value = status;
statusCell.appendChild(statusInput);
tableRow.appendChild(statusCell);
// Append orders assigned table cell
var titleCell = document.createElement('div');
titleCell.style.display = 'table-cell';
var titleInput = document.createElement('input');
titleInput.id = `book-title-${bid}`;
titleInput.type = 'text';
titleInput.name = 'book-title';
titleInput.value = title;
titleCell.appendChild(titleInput);
tableRow.appendChild(titleCell);
// Append update table cell
var updateCell = document.createElement('div');
updateCell.style.display = 'table-cell';
var updateInput = document.createElement('input');
updateInput.id = `update-${bid}`;
updateInput.type = 'button';
updateInput.name = 'update';
updateInput.value = 'Update';
updateCell.appendChild(updateInput);
tableRow.appendChild(updateCell);
// Add update event listener
updateInput.addEventListener('click', function (e) {
e.preventDefault();
var book = {
bid: bidInput.value,
author: authorInput.value,
status: statusInput.value,
title: titleInput.value
};
htmlUpdateBook(book);
});
// Append book table cell
var deleteCell = document.createElement('div');
deleteCell.style.display = 'table-cell';
var deleteInput = document.createElement('input');
deleteInput.id = `delete-${bid}`;
deleteInput.type = 'button';
deleteInput.name = 'delete';
deleteInput.value = 'Delete';
deleteCell.appendChild(deleteInput);
tableRow.appendChild(deleteCell);
// Add delete event listener
deleteInput.addEventListener('click', function (e) {
e.preventDefault();
htmlDeleteBook(bid);
});
}
function htmlUpdateBook(book) {
/**
* Update Books table with database update over HTML
*/
var bid = book.bid;
var author = book.author;
var status = book.status;
var title = book.title;
var data = JSON.stringify({
"bid": bid,
"author": author,
"status": status,
"title": title
});
var req = new XMLHttpRequest();
var url = `${SERVER}/${bid}`;
req.open('PUT', url, true);
req.onload = function () {
if (req.status === 204) {
emptyBooksTable();
htmlReadBooks();
}
};
req.setRequestHeader("Content-Type", "application/json");
req.send(data);
}
function htmlDeleteBook(bid) {
/**
* Delete from books table with database delete over HTML
*/
var req = new XMLHttpRequest();
var url = `${SERVER}/${bid}`;
req.open('DELETE', url, true);
req.onload = function () {
if (req.status === 204) {
emptyBooksTable();
htmlReadBooks();
}
};
req.send();
}
/**
* Main
*/
document.addEventListener('DOMContentLoaded', htmlCreateBook());
document.addEventListener('DOMContentLoaded', htmlReadBooks());
@charset "UTF-8";
body{
margin: 20px;
background-color: lightgray;
}
.content{
margin: 30px 0px 30px 0px;
}
div a{
margin: 0px 30px 0px 0px;
}
a, a:visited, a:hover, a:active{
color: blue;
}
另一种表格形式的JavaScript的客户端:
?
<!DOCTYPE html>
<html>
<head>
<title>Books</title>
</head>
<body>
<div class="container">
<h1>Books CRUD</h1>
<fieldset>
<legend>New Book</legend>
<form id="addcustomerform">
<div class="form-group">
<label>bid:</label>
<input type="text" name="txtbid" id="txtbid" class="form-control" value="" required="">
</div>
<div class="form-group">
<label>author:</label>
<input type="text" name="txtauthor" id="txtauthor" class="form-control" value="" required="">
</div>
<div class="form-group">
<label>status:</label>
<input type="text" name="txtstatus" id="txtstatus" class="form-control" value="" required="">
</div>
<div class="form-group">
<label>title:</label>
<input type="text" name="txttitle" id="txttitle" class="form-control" value="" required="">
</div>
<button type="submit" id="btnaddBook" class="btn btn-primary save-btn">Save</button>
</form>
</fieldset>
<br />
<fieldset>
<legend>Book List
</legend>
<table class="table" border="1">
<thead>
<tr>
<th>bid</th>
<th>author</th>
<th>status</th>
<th>title</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="tblbody">
</tbody>
</table>
</fieldset>
</div>
<script type="text/javascript">
var SERVER = 'http://localhost:8080/bookwildfly-1.0-SNAPSHOT/resources/com.example.bookwildfly.book';
document.addEventListener('DOMContentLoaded', function (event) {
/**
* Build books table from database read over HTML
*/
var req = new XMLHttpRequest();
req.open('GET', SERVER, true);
req.onload = function () {
if (req.status === 200) {
var books = JSON.parse(req.responseText);
/**
* Fill books table with data
*/
books.forEach(function (book) {
var bid = book.bid;
var author = book.author;
var status = book.status;
var title = book.title;
var btneditId = "btnedit" + bid;
var btndeleteId = "btndelete" + bid;
var tablerow = "<tr Id='" + bid + "' data-bid='" + bid + "' data-author='" + author + "' data-status='" + status + "' data-title='" + title + "'>"
+ "<td class='td-data'>" + bid + "</td>"
+ "<td class='td-data'>" + author + "</td>"
+ "<td class='td-data'>" + status + "</td>"
+ "<td class='td-data'>" + title + "</td>"
+ "<td class='td-data'>" +
"<button id='" + btneditId + "' class='btn btn-info btn-xs btn-editcustomer' onclick='showEditRow(" + bid + ")'><i class='fa fa-pencil' aria-hidden='true'></i>Edit</button>" +
"<button id='" + btndeleteId + "' class='btn btn-danger btn-xs btn-deleteBook' onclick='deleteBookRow(" + bid + ")'><i class='fa fa-trash' aria-hidden='true'>Delete</button>"
+ "</td>"
+ "</tr>";
document.getElementById('tblbody').innerHTML += tablerow;
document.getElementById('txtbid').value = "";
document.getElementById('txtauthor').value = "";
document.getElementById('txtstatus').value = "";
document.getElementById('txttitle').value = "";
});
}
};
req.send();
});
document.getElementById("btnaddBook").addEventListener("click", function (event) {
event.preventDefault()
var bid = document.getElementById("txtbid").value;
var author = document.getElementById("txtauthor").value;
var status = document.getElementById("txtstatus").value;
var title = document.getElementById("txttitle").value;
var data = JSON.stringify({
bid: bid,
author: author,
status: status,
title: title
});
var req = new XMLHttpRequest();
req.withCredentials = true;
var url = `${SERVER}`;
req.open('POST', url, true);
req.onload = function () {
console.log(req.status);
if (req.status === 204) {
var btneditId = "btnedit" + bid;
var btndeleteId = "btndelete" + bid;
var tablerow = "<tr Id='" + bid + "' data-bid='" + bid + "' data-author='" + author + "' data-status='" + status + "' data-title='" + title + "'>"
+ "<td class='td-data'>" + bid + "</td>"
+ "<td class='td-data'>" + author + "</td>"
+ "<td class='td-data'>" + status + "</td>"
+ "<td class='td-data'>" + title + "</td>"
+ "<td class='td-data'>" +
"<button id='" + btneditId + "' class='btn btn-info btn-xs btn-editcustomer' onclick='showEditRow(" + bid + ")'><i class='fa fa-pencil' aria-hidden='true'></i>Edit</button>" +
"<button id='" + btndeleteId + "' class='btn btn-danger btn-xs btn-deleteBook' onclick='deleteBookRow(" + bid + ")'><i class='fa fa-trash' aria-hidden='true'>Delete</button>"
+ "</td>"
+ "</tr>";
document.getElementById('tblbody').innerHTML += tablerow;
document.getElementById('txtbid').value = "";
document.getElementById('txtauthor').value = "";
document.getElementById('txtstatus').value = "";
document.getElementById('txttitle').value = "";
}
};
req.setRequestHeader("Content-Type", "application/json");
req.send(data);
});
function showEditRow(bid)
{
var BookRow = document.getElementById(bid); //this gives tr of whose button was clicked
var data = BookRow.querySelectorAll(".td-data");
/*returns array of all elements with
"row-data" class within the row with given id*/
var bid = data[0].innerHTML;
var author = data[1].innerHTML;
var status = data[2].innerHTML;
var title = data[3].innerHTML;
var btneditId = "btnedit" + bid;
data[0].innerHTML = '<input name="txtupdate_bid" disabled id="txtupdate_bid" value="' + bid + '"/>';
data[1].innerHTML = '<input name="txtupdate_author" id="txtupdate_author" value="' + author + '"/>';
data[2].innerHTML = '<input name="txtupdate_status" id="txtupdate_status" value="' + status + '"/>';
data[3].innerHTML = '<input name="txtupdate_title" id="txtupdate_title" value="' + title + '"/>';
data[4].innerHTML =
"<button class='btn btn-primary btn-xs btn-updateBook' onclick='updateBookRow(" + bid + ")'>" +
"<i class='fa fa-pencil' aria-hidden='true'></i>Update</button>"
+ "<button class='btn btn-warning btn-xs btn-cancelUpdate' onclick='cancelUpdate(" + bid + ")'><i class='fa fa-times' aria-hidden='true'></i>Cancel</button>"
+ "<button class='btn btn-danger btn-xs btn-deleteBook' onclick='deleteBookRow(" + bid + ")'>"
+ "<i class='fa fa-trash' aria-hidden='true'></i>Delete</button>"
}
function cancelUpdate(bid)
{
var btneditId = "btnedit" + bid;
var btndeleteId = "btndelete" + bid;
var BookRow = document.getElementById(bid); //this gives tr of whose button was clicked
var data = BookRow.querySelectorAll(".td-data");
var author = BookRow.getAttribute("data-author");
var status = BookRow.getAttribute("data-status");
var title = BookRow.getAttribute("data-title");
data[0].innerHTML = bid;
data[1].innerHTML = author;
data[2].innerHTML = status;
data[3].innerHTML = title;
var actionbtn = "<button id='" + btneditId + "' class='btn btn-info btn-xs btn-editcustomer' onclick='showEditRow(" + bid + ")'><i class='fa fa-pencil' aria-hidden='true'></i>Edit</button>" +
"<button id='" + btndeleteId + "' class='btn btn-danger btn-xs btn-deleteBook' onclick='deleteBookRow(" + bid + ")'><i class='fa fa-trash' aria-hidden='true'>Delete</button>"
data[4].innerHTML = actionbtn;
}
function deleteBookRow(bid)
{
var req = new XMLHttpRequest();
var url = `${SERVER}/${bid}`;
req.open('DELETE', url, true);
req.onload = function () {
if (req.status === 204) {
document.getElementById(bid).remove();
}
};
req.send();
}
function updateBookRow(bid)
{
var BookRow = document.getElementById(bid); //this gives tr of whose button was clicked
var data = BookRow.querySelectorAll(".td-data");
var author = data[1].querySelector("#txtupdate_author").value;
var status = data[2].querySelector("#txtupdate_status").value;
var title = data[3].querySelector("#txtupdate_title").value;
var data = JSON.stringify({
bid: bid,
author: author,
status: status,
title: title
});
var req = new XMLHttpRequest();
var url = `${SERVER}/${bid}`;
req.open('PUT', url, true);
req.onload = function () {
if (req.status === 204) {
var btneditId = "btnedit" + bid;
var btndeleteId = "btndelete" + bid;
var BookRow = document.getElementById(bid); //this gives tr of whose button was clicked
var data = BookRow.querySelectorAll(".td-data");
var author = data[1].querySelector("#txtupdate_author").value;
var status = data[2].querySelector("#txtupdate_status").value;
var title = data[3].querySelector("#txtupdate_title").value;
data[0].innerHTML = bid;
data[1].innerHTML = author;
data[2].innerHTML = status;
data[3].innerHTML = title;
var actionbtn = "<button id='" + btneditId + "' class='btn btn-info btn-xs btn-editcustomer' onclick='showEditRow(" + bid + ")'><i class='fa fa-pencil' aria-hidden='true'></i>Edit</button>" +
"<button id='" + btndeleteId + "' class='btn btn-danger btn-xs btn-deleteBook' onclick='deleteBookRow(" + bid + ")'><i class='fa fa-trash' aria-hidden='true'>Delete</button>"
data[4].innerHTML = actionbtn;
}
};
req.setRequestHeader("Content-Type", "application/json");
req.send(data);
}
</script>
</body>
</html>
源码下载:
GitHub - allwaysoft/NetBeans-IDE-Wildfly-MYSQL-CRUD-REST-API-Pure-JavaScript-Clienthttps://github.com/allwaysoft/NetBeans-IDE-Wildfly-MYSQL-CRUD-REST-API-Pure-JavaScript-Client
|