Initial Comit
This commit is contained in:
66
DPMMobileB4X/test/MyWebApi/CorsFilter.bas
Normal file
66
DPMMobileB4X/test/MyWebApi/CorsFilter.bas
Normal file
@@ -0,0 +1,66 @@
|
||||
B4J=true
|
||||
Group=Filters
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=9.1
|
||||
@EndOfDesignText@
|
||||
' Cross-Origin Resource Sharing (CORS) Filter class
|
||||
Sub Class_Globals
|
||||
Private cPath As String
|
||||
Private cSettings As Map
|
||||
End Sub
|
||||
|
||||
'Initializes the object. You can add parameters to this method if needed.
|
||||
Public Sub Initialize (Path As String, Settings As Map)
|
||||
cPath = Path
|
||||
cSettings = Settings
|
||||
End Sub
|
||||
|
||||
'Return True to allow the request to proceed.
|
||||
'Public Sub Filter (req As ServletRequest, resp As ServletResponse) As Boolean
|
||||
' Return True
|
||||
'End Sub
|
||||
|
||||
Public Sub AddToServer (ServerObject As Server)
|
||||
Dim joServerWrapper As JavaObject = ServerObject
|
||||
Dim joMe As JavaObject = Me
|
||||
joMe.RunMethod("addFilter", Array As Object(joServerWrapper.GetField("context"), cPath, cSettings))
|
||||
End Sub
|
||||
|
||||
#If JAVA
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
|
||||
import anywheresoftware.b4a.objects.collections.Map.MyMap;
|
||||
|
||||
public void addFilter(ServletContextHandler context, String path, MyMap settings) throws Exception {
|
||||
FilterHolder fh = new FilterHolder((Class<? extends Filter>) Class.forName("org.eclipse.jetty.servlets.CrossOriginFilter"));
|
||||
if (settings != null) {
|
||||
HashMap<String,String> m = new HashMap<String, String>();
|
||||
copyMyMap(settings, m, true); //integerNumbersOnly!
|
||||
fh.setInitParameters(m);
|
||||
}
|
||||
context.addFilter(fh, path, EnumSet.of(DispatcherType.REQUEST));
|
||||
}
|
||||
|
||||
private void copyMyMap(MyMap m, java.util.Map<String, String> o, boolean integerNumbersOnly) {
|
||||
for (Entry<Object, Object> e : m.entrySet()) {
|
||||
String value;
|
||||
if (integerNumbersOnly && e.getValue() instanceof Number) {
|
||||
value = String.valueOf(((Number)e.getValue()).longValue());
|
||||
} else {
|
||||
value = String.valueOf(e.getValue());
|
||||
o.put(String.valueOf(e.getKey()), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#End If
|
||||
120
DPMMobileB4X/test/MyWebApi/DataUtils.bas
Normal file
120
DPMMobileB4X/test/MyWebApi/DataUtils.bas
Normal file
@@ -0,0 +1,120 @@
|
||||
B4J=true
|
||||
Group=Modules
|
||||
ModulesStructureVersion=1
|
||||
Type=StaticCode
|
||||
Version=9.1
|
||||
@EndOfDesignText@
|
||||
' DataUtils Code module
|
||||
' Version 1.08
|
||||
Sub Process_Globals
|
||||
Dim pool As ConnectionPool
|
||||
End Sub
|
||||
|
||||
Public Sub CreateDatabaseIfNotExist
|
||||
Try
|
||||
Dim DBFound As Boolean
|
||||
Dim strSQL As String
|
||||
Dim DBName As String = Main.Conn.DbName.As(String)
|
||||
' SQLite
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("sqlite") Then
|
||||
Log("Checking database...")
|
||||
|
||||
If File.Exists(File.DirApp, DBName) Then
|
||||
Log("Database found!")
|
||||
'DB.InitializeSQLite(File.DirApp, DBName, False)
|
||||
Else
|
||||
Log("Database not found!")
|
||||
Log("Creating database...")
|
||||
Dim DB As SQL
|
||||
DB.InitializeSQLite(File.DirApp, DBName, True)
|
||||
DB.ExecNonQuery("PRAGMA journal_mode = wal")
|
||||
|
||||
strSQL = Main.queries.Get("CREATE_TABLE_TBL_CATEGORY")
|
||||
If strSQL <> "" Then DB.AddNonQueryToBatch(strSQL, Null)
|
||||
strSQL = Main.queries.Get("INSERT_DUMMY_TBL_CATEGORY")
|
||||
If strSQL <> "" Then DB.AddNonQueryToBatch(strSQL, Null)
|
||||
strSQL = Main.queries.Get("CREATE_TABLE_TBL_PRODUCTS")
|
||||
If strSQL <> "" Then DB.AddNonQueryToBatch(strSQL, Null)
|
||||
strSQL = Main.queries.Get("INSERT_DUMMY_TBL_PRODUCTS")
|
||||
If strSQL <> "" Then DB.AddNonQueryToBatch(strSQL, Null)
|
||||
|
||||
Dim SenderFilter As Object = DB.ExecNonQueryBatch("SQL")
|
||||
Wait For (SenderFilter) SQL_NonQueryComplete (Success As Boolean)
|
||||
If Success Then
|
||||
Log("Database is created successfully!")
|
||||
Else
|
||||
Log("Database creation failed!")
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
' MySQL
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("mysql") Then
|
||||
Main.Conn.JdbcUrl = Main.Conn.JdbcUrl.Replace(DBName, "information_schema")
|
||||
Dim con As SQL = OpenDB
|
||||
If con.IsInitialized Then
|
||||
Log($"Checking database..."$)
|
||||
strSQL = Main.queries.Get("CHECK_DATABASE")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(DBName))
|
||||
Do While res.NextRow
|
||||
DBFound = True
|
||||
Loop
|
||||
res.Close
|
||||
If DBFound Then
|
||||
Log("Database found!")
|
||||
Else
|
||||
Log("Database not found!")
|
||||
Log("Creating database...")
|
||||
|
||||
strSQL = Main.queries.Get("CREATE_DATABASE").As(String).Replace("{DBNAME}", DBName) ' Can't use prepared statement
|
||||
If strSQL <> "" Then con.AddNonQueryToBatch(strSQL, Null)
|
||||
strSQL = Main.queries.Get("USE_DATABASE").As(String).Replace("{DBNAME}", DBName)
|
||||
If strSQL <> "" Then con.AddNonQueryToBatch(strSQL, Null)
|
||||
'strSQL = Main.queries.Get("DROP_TABLE_IF_EXIST_TBL_CATEGORY")
|
||||
'If strSQL <> "" Then con.AddNonQueryToBatch(strSQL, Null)
|
||||
strSQL = Main.queries.Get("CREATE_TABLE_TBL_CATEGORY")
|
||||
If strSQL <> "" Then con.AddNonQueryToBatch(strSQL, Null)
|
||||
strSQL = Main.queries.Get("INSERT_DUMMY_TBL_CATEGORY")
|
||||
If strSQL <> "" Then con.AddNonQueryToBatch(strSQL, Null)
|
||||
'strSQL = Main.queries.Get("DROP_TABLE_IF_EXIST_TBL_PRODUCTS")
|
||||
'If strSQL <> "" Then con.AddNonQueryToBatch(strSQL, Null)
|
||||
strSQL = Main.queries.Get("CREATE_TABLE_TBL_PRODUCTS")
|
||||
If strSQL <> "" Then con.AddNonQueryToBatch(strSQL, Null)
|
||||
strSQL = Main.queries.Get("INSERT_DUMMY_TBL_PRODUCTS")
|
||||
If strSQL <> "" Then con.AddNonQueryToBatch(strSQL, Null)
|
||||
|
||||
Dim SenderFilter As Object = con.ExecNonQueryBatch("SQL")
|
||||
Wait For (SenderFilter) SQL_NonQueryComplete (Success As Boolean)
|
||||
If Success Then
|
||||
Log("Database is created successfully!")
|
||||
Else
|
||||
Log("Database creation failed!")
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Catch
|
||||
LogError(LastException)
|
||||
CloseDB(con)
|
||||
Log("Error creating database!")
|
||||
Log("Application is terminated.")
|
||||
ExitApplication
|
||||
End Try
|
||||
CloseDB(con)
|
||||
' Revert jdbcUrl to normal
|
||||
Main.Conn.JdbcUrl = Main.config.Get("JdbcUrl")
|
||||
End Sub
|
||||
|
||||
Sub OpenDB As SQL
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("mysql") Then
|
||||
pool = Main.OpenConnection(pool)
|
||||
Return pool.GetConnection
|
||||
End If
|
||||
Return Null
|
||||
End Sub
|
||||
|
||||
Sub CloseDB (con As SQL)
|
||||
If con <> Null And con.IsInitialized Then con.Close
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("mysql") Then
|
||||
If pool.IsInitialized Then pool.ClosePool
|
||||
End If
|
||||
End Sub
|
||||
18
DPMMobileB4X/test/MyWebApi/DefaultHandler.bas
Normal file
18
DPMMobileB4X/test/MyWebApi/DefaultHandler.bas
Normal file
@@ -0,0 +1,18 @@
|
||||
B4J=true
|
||||
Group=Default Group
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=9.1
|
||||
@EndOfDesignText@
|
||||
'Handler class
|
||||
Sub Class_Globals
|
||||
|
||||
End Sub
|
||||
|
||||
Public Sub Initialize
|
||||
|
||||
End Sub
|
||||
|
||||
Sub Handle(req As ServletRequest, resp As ServletResponse)
|
||||
|
||||
End Sub
|
||||
154
DPMMobileB4X/test/MyWebApi/Files/index.html
Normal file
154
DPMMobileB4X/test/MyWebApi/Files/index.html
Normal file
@@ -0,0 +1,154 @@
|
||||
<div class="content m-3">
|
||||
<div class="p-2">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>$HOME_TITLE$</h3>
|
||||
<span class="small">Version: $VERSION$</span>
|
||||
<div class="small">Local time: <span id="datetime"></span>
|
||||
<script type="text/javascript">
|
||||
var datetime = document.getElementById('datetime');
|
||||
var d = new Date();
|
||||
var formatted = d.getFullYear() + '-' +
|
||||
('0' + (d.getMonth()+1)).slice(-2) + '-' +
|
||||
('0' + d.getDate()).slice(-2) + ' ' +
|
||||
('0' + d.getHours()).slice(-2) + ':' +
|
||||
('0' + d.getMinutes()).slice(-2) + ':' +
|
||||
('0' + d.getSeconds()).slice(-2);
|
||||
datetime.innerHTML = formatted;
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-12">
|
||||
<h3 class="text-uppercase text-primary"><span class='fa fa-layer-group mr-1'></span> <strong>Category</strong></h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered rounded table-light small">
|
||||
<thead class="bg-secondary text-white">
|
||||
<th class="col-md-5 h6"><strong>Description</strong></th>
|
||||
<th class="col-md-1 h6 text-center"><strong>Method</strong></th>
|
||||
<th class="col-md-3 h6"><strong>Payload</strong></th>
|
||||
<th class="col-md-3 h6"><strong>API Endpoint</strong></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>List all categories</td>
|
||||
<td class="text-center text-success">GET</td>
|
||||
<td></td>
|
||||
<td><a href="$ROOT_URL$$ROOT_PATH$category" target="_blank">/category</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Get a category by id</td>
|
||||
<td class="text-center text-success">GET</td>
|
||||
<td></td>
|
||||
<td><a href="$ROOT_URL$$ROOT_PATH$category/2" target="_blank">/category/{cat_id}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Add a new category</td>
|
||||
<td class="text-center text-warning">POST</td>
|
||||
<td>{<br>
|
||||
"name": "category_name"<br>
|
||||
}</td>
|
||||
<td>/category</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Update existing category by id</td>
|
||||
<td class="text-center text-primary">PUT</td>
|
||||
<td>{<br>
|
||||
"name": "category_name"<br>
|
||||
}</td>
|
||||
<td>/category/{cat_id}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Delete existing category by id</td>
|
||||
<td class="text-center text-danger">DELETE</td>
|
||||
<td></td>
|
||||
<td>/category/{cat_id}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-12">
|
||||
<h3 class="text-uppercase text-primary"><span class='fa fa-cart-arrow-down mr-1'></span> <strong>Product</strong></h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered rounded table-light small">
|
||||
<thead class="bg-secondary text-white">
|
||||
<th class="col-md-5 h6"><strong>Description</strong></th>
|
||||
<th class="col-md-1 h6 text-center"><strong>Method</strong></th>
|
||||
<th class="col-md-3 h6"><strong>Payload</strong></th>
|
||||
<th class="col-md-3 h6"><strong>API Endpoint</strong></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>List all products by category id</td>
|
||||
<td class="text-center text-success">GET</td>
|
||||
<td></td>
|
||||
<td><a href="$ROOT_URL$$ROOT_PATH$category/2/product" target="_blank">/category/{cat_id}/product</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Get a product by category and id</td>
|
||||
<td class="text-center text-success">GET</td>
|
||||
<td></td>
|
||||
<td><a href="$ROOT_URL$$ROOT_PATH$category/2/product/3" target="_blank">/category/{cat_id}/product/{id}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Add a new product by category id</td>
|
||||
<td class="text-center text-warning">POST</td>
|
||||
<td>{<br>
|
||||
"code": "product_code",<br>
|
||||
"name": "product_name",<br>
|
||||
"price": product_price<br>
|
||||
}</td>
|
||||
<td>/category/{cat_id}/product</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Update existing product by category id and id</td>
|
||||
<td class="text-center text-primary">PUT</td>
|
||||
<td>{<br>
|
||||
"code": "product_code",<br>
|
||||
"name": "product_name",<br>
|
||||
"price": product_price<br>
|
||||
}</td>
|
||||
<td>/category/{cat_id}/product/{id}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Delete existing product by category id and id</td>
|
||||
<td class="text-center text-danger">DELETE</td>
|
||||
<td></td>
|
||||
<td>/category/{cat_id}/product/{id}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-12">
|
||||
<form class="form mb-3" action="">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm">Keywords</span>
|
||||
</div>
|
||||
<input class="form-control col-md-3" type="text" id="keywords" name="keywords">
|
||||
<button class="btn btn-danger btn-sm pl-3 pr-3 ml-3" type="hidden" id="btnsearch">Search</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="results" class="table">
|
||||
<table class="table table-bordered rounded small">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
30
DPMMobileB4X/test/MyWebApi/Files/main.html
Normal file
30
DPMMobileB4X/test/MyWebApi/Files/main.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<title>$APP_TITLE$</title>
|
||||
<link rel="icon" type="image/png" href="$ROOT_URL$/assets/img/favicon.png"/>
|
||||
<link rel="stylesheet" href="$ROOT_URL$/assets/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="$ROOT_URL$/assets/css/fontawesome.min.css">
|
||||
<link rel="stylesheet" href="$ROOT_URL$/assets/css/solid.min.css">
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Arial, Helvetica, Tahoma, Times New Roman;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<nav class="navbar navbar-expand navbar-dark bg-primary">
|
||||
<a class="text-white mr-3" href="#"><i class="fas fa-rocket"></i></a>
|
||||
<a class="navbar-brand font-weight-bold" href="$ROOT_URL$$ROOT_PATH$">$APP_TRADEMARK$</a>
|
||||
</nav>
|
||||
@VIEW@
|
||||
<div class="footer small m-4"><caption>$APP_COPYRIGHT$</caption></div>
|
||||
<script src="$ROOT_URL$/assets/js/jquery.min.js"></script>
|
||||
<script src="$ROOT_URL$/assets/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="$ROOT_URL$/assets/js/webapisearch.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
101
DPMMobileB4X/test/MyWebApi/HomeHandler.bas
Normal file
101
DPMMobileB4X/test/MyWebApi/HomeHandler.bas
Normal file
@@ -0,0 +1,101 @@
|
||||
B4J=true
|
||||
Group=Handlers
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=8.1
|
||||
@EndOfDesignText@
|
||||
' Home Handler class
|
||||
Sub Class_Globals
|
||||
Dim Request As ServletRequest
|
||||
Dim Response As ServletResponse
|
||||
Dim pool As ConnectionPool
|
||||
End Sub
|
||||
|
||||
Public Sub Initialize
|
||||
|
||||
End Sub
|
||||
|
||||
Sub Handle(req As ServletRequest, resp As ServletResponse)
|
||||
Request = req
|
||||
Response = resp
|
||||
|
||||
' Search e.g. ' http://127.0.0.1:19800/v1/?search=ha
|
||||
If Request.GetParameter("search") <> "" Then ' GET
|
||||
Search(Request.GetParameter("search"))
|
||||
Else if Request.Method.ToUpperCase = "POST" Then
|
||||
Dim keywords As String = req.GetParameter("keywords").Trim
|
||||
Search(keywords)
|
||||
Else
|
||||
ShowHomePage
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Private Sub ShowHomePage
|
||||
Dim strMain As String = Utility.ReadTextFile("main.html")
|
||||
Dim strView As String = Utility.ReadTextFile("index.html")
|
||||
strMain = Utility.BuildView(strMain, strView)
|
||||
strMain = Utility.BuildHtml(strMain, Main.config)
|
||||
Utility.ReturnHTML(strMain, Response)
|
||||
End Sub
|
||||
|
||||
Sub Search (SearchForText As String)
|
||||
Dim con As SQL = OpenDB
|
||||
Dim strSQL As String
|
||||
Try
|
||||
Dim keys() As String = Regex.Split2(" ", 2, SearchForText)
|
||||
|
||||
If keys.Length < 2 Then
|
||||
Dim s1 As String = SearchForText.Trim
|
||||
'Log(s1)
|
||||
strSQL = Main.queries.Get("SEARCH_PRODUCT_BY_CATEGORY_CODE_AND_NAME_ONEWORD_ORDERED")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String("%" & s1 & "%", "%" & s1 & "%", "%" & s1 & "%"))
|
||||
Else
|
||||
Dim s1 As String = keys(0).Trim
|
||||
Dim s2 As String = SearchForText.Replace(keys(0), "").Trim
|
||||
'Log(s1 & "," & s2)
|
||||
strSQL = Main.queries.Get("SEARCH_PRODUCT_BY_CATEGORY_CODE_AND_NAME_TWOWORDS_ORDERED")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String("%" & s1 & "%", "%" & s1 & "%", "%" & s1 & "%", _
|
||||
"%" & s2 & "%", "%" & s2 & "%", "%" & s2 & "%"))
|
||||
End If
|
||||
|
||||
Dim List1 As List
|
||||
List1.Initialize
|
||||
Do While res.NextRow
|
||||
Dim Map2 As Map
|
||||
Map2.Initialize
|
||||
For i = 0 To res.ColumnCount - 1
|
||||
If res.GetColumnName(i) = "aa" Then
|
||||
Map2.Put(res.GetColumnName(i), res.GetInt2(i))
|
||||
Else If res.GetColumnName(i) = "ee" Then
|
||||
Map2.Put(res.GetColumnName(i), NumberFormat2(res.GetDouble2(i), 1, 2, 2, True))
|
||||
Else
|
||||
Map2.Put(res.GetColumnName(i), res.GetString2(i))
|
||||
End If
|
||||
Next
|
||||
List1.Add(Map2)
|
||||
Loop
|
||||
Utility.ReturnSuccess2(List1, 200, Response)
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
Utility.ReturnError("Error Execute Query", 422, Response)
|
||||
End Try
|
||||
CloseDB(con)
|
||||
End Sub
|
||||
|
||||
Sub OpenDB As SQL
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("mysql") Then
|
||||
pool = Main.OpenConnection(pool)
|
||||
Return pool.GetConnection
|
||||
End If
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("sqlite") Then
|
||||
Return Main.OpenSQLiteDB
|
||||
End If
|
||||
Return Null
|
||||
End Sub
|
||||
|
||||
Sub CloseDB (con As SQL)
|
||||
If con <> Null And con.IsInitialized Then con.Close
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("mysql") Then
|
||||
If pool.IsInitialized Then pool.ClosePool
|
||||
End If
|
||||
End Sub
|
||||
25
DPMMobileB4X/test/MyWebApi/HttpsFilter.bas
Normal file
25
DPMMobileB4X/test/MyWebApi/HttpsFilter.bas
Normal file
@@ -0,0 +1,25 @@
|
||||
B4J=true
|
||||
Group=Filters
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=8.5
|
||||
@EndOfDesignText@
|
||||
' Https Filter class
|
||||
Sub Class_Globals
|
||||
|
||||
End Sub
|
||||
|
||||
Public Sub Initialize
|
||||
|
||||
End Sub
|
||||
|
||||
'Return True to allow the request to proceed.
|
||||
Public Sub Filter (req As ServletRequest, resp As ServletResponse) As Boolean
|
||||
If req.Secure Then
|
||||
Return True
|
||||
Else
|
||||
resp.SendRedirect(req.FullRequestURI.Replace("http:", "https:") _
|
||||
.Replace(Main.srvr.Port, Main.srvr.SslPort))
|
||||
Return False
|
||||
End If
|
||||
End Sub
|
||||
196
DPMMobileB4X/test/MyWebApi/MyWebApi.b4j
Normal file
196
DPMMobileB4X/test/MyWebApi/MyWebApi.b4j
Normal file
@@ -0,0 +1,196 @@
|
||||
AppType=StandardJava
|
||||
Build1=Default,b4j.webapi
|
||||
File1=index.html
|
||||
File2=main.html
|
||||
FileGroup1=Default Group
|
||||
FileGroup2=Default Group
|
||||
Group=Default Group
|
||||
Library1=byteconverter
|
||||
Library2=jcore
|
||||
Library3=jserver
|
||||
Library4=json
|
||||
Library5=jsql
|
||||
Library6=javaobject
|
||||
Module1=CorsFilter
|
||||
Module2=DataUtils
|
||||
Module3=DefaultHandler
|
||||
Module4=HomeHandler
|
||||
Module5=HttpsFilter
|
||||
Module6=ProductHandler
|
||||
Module7=Utility
|
||||
Module8=WebUtils
|
||||
NumberOfFiles=2
|
||||
NumberOfLibraries=6
|
||||
NumberOfModules=8
|
||||
Version=9.1
|
||||
@EndOfDesignText@
|
||||
' Name: Web API Lite
|
||||
' Description: Non-UI application (console / server application)
|
||||
' Version: 1.08
|
||||
|
||||
#Region Project Attributes
|
||||
#CommandLineArgs:
|
||||
#MergeLibraries: True
|
||||
#End Region
|
||||
|
||||
#Region AdditionalJar
|
||||
' MySQL connector
|
||||
'#AdditionalJar: mysql-connector-java-5.1.49-bin
|
||||
' SQLite connector
|
||||
#AdditionalJar: sqlite-jdbc-3.36.0.2
|
||||
#End Region
|
||||
|
||||
Sub Process_Globals
|
||||
Public const VERSION As Float = 1.08
|
||||
Public srvr As Server
|
||||
Public ROOT_PATH As String
|
||||
Public ROOT_URL As String
|
||||
Public SERVER_PORT As Int
|
||||
Public SSL_PORT As Int
|
||||
Public config As Map
|
||||
Public queries As Map
|
||||
Public Conn As Conn
|
||||
Public Element As Element
|
||||
Type Conn (DbName As String, DbType As String, DriverClass As String, JdbcUrl As String, User As String, Password As String, MaxPoolSize As Int)
|
||||
Type Element (Root As Int, Parent As Int, Parent_Id As Int, Child As Int, Child_Id As Int, Max_Elements As Int)
|
||||
End Sub
|
||||
|
||||
Sub AppStart (Args() As String)
|
||||
config = Utility.ReadMapFile(File.DirApp, "config.ini")
|
||||
If config.Get("DbType").As(String).EqualsIgnoreCase("mysql") Then
|
||||
queries = Utility.ReadMapFile(File.DirApp, "queries-mysql.ini")
|
||||
End If
|
||||
If config.Get("DbType").As(String).EqualsIgnoreCase("sqlite") Then
|
||||
queries = Utility.ReadMapFile(File.DirApp, "queries-sqlite.ini")
|
||||
End If
|
||||
|
||||
ROOT_PATH = config.Get("ROOT_PATH")
|
||||
ROOT_URL = config.Get("ROOT_URL")
|
||||
SERVER_PORT = config.Get("ServerPort")
|
||||
SSL_PORT = config.Get("SSLPort") : If IsNumber(SSL_PORT) = False Then SSL_PORT = 0
|
||||
|
||||
If SERVER_PORT = 0 Then
|
||||
Log($"Server Port is not set!"$)
|
||||
Log($"Application is terminated."$)
|
||||
ExitApplication
|
||||
End If
|
||||
ROOT_URL = ROOT_URL & ":" & SERVER_PORT
|
||||
|
||||
srvr.Initialize("")
|
||||
srvr.Port = SERVER_PORT
|
||||
|
||||
If SSL_PORT > 0 Then
|
||||
ConfigureSSL(SSL_PORT)
|
||||
ROOT_URL = config.Get("ROOT_URL") & ":" & SSL_PORT
|
||||
End If
|
||||
' Update ROOT URL
|
||||
config.Put("ROOT_URL", ROOT_URL)
|
||||
config.Put("VERSION", VERSION)
|
||||
|
||||
Conn.Initialize
|
||||
Conn.DbName = config.Get("DbName")
|
||||
Conn.DbType = config.Get("DbType")
|
||||
Conn.DriverClass = config.Get("DriverClass")
|
||||
Conn.JdbcUrl = config.Get("JdbcUrl")
|
||||
If Conn.DbType.EqualsIgnoreCase("mysql") Then
|
||||
Conn.User = config.Get("User")
|
||||
Conn.Password = config.Get("Password")
|
||||
Conn.MaxPoolSize = config.Get("MaxPoolSize")
|
||||
End If
|
||||
|
||||
' Check if database exists
|
||||
DataUtils.CreateDatabaseIfNotExist
|
||||
|
||||
Element.Initialize
|
||||
If ROOT_PATH <> "/" Then ' If webroot is using subdirectory
|
||||
srvr.AddHandler(ROOT_PATH, "HomeHandler", False)
|
||||
Element.Root = 1
|
||||
Element.Parent = 2
|
||||
Element.Parent_Id = 3
|
||||
Element.Child = 4
|
||||
Element.Child_Id = 5
|
||||
Element.Max_Elements = 6
|
||||
Else
|
||||
Element.Root = 0
|
||||
Element.Parent = 1
|
||||
Element.Parent_Id = 2
|
||||
Element.Child = 3
|
||||
Element.Child_Id = 4
|
||||
Element.Max_Elements = 5
|
||||
End If
|
||||
|
||||
srvr.StaticFilesFolder = File.Combine(File.DirApp, "www")
|
||||
srvr.SetStaticFilesOptions(CreateMap("dirAllowed": False))
|
||||
|
||||
' Add a home page
|
||||
srvr.AddHandler("", "HomeHandler", False)
|
||||
|
||||
' Add more handlers here
|
||||
srvr.AddHandler(ROOT_PATH & "default/*", "DefaultHandler", False)
|
||||
srvr.AddHandler(ROOT_PATH & "category/*", "ProductHandler", False)
|
||||
|
||||
' Add CrossOriginFilter
|
||||
'ConfigureCORS("/*", "*", "*", "*")
|
||||
'ConfigureCORS(ROOT_PATH & "category/*", "http://127.0.0.1:19800", "", "") ' test.html
|
||||
ConfigureCORS(ROOT_PATH & "category/*", "*", "", "")
|
||||
|
||||
' Server starts
|
||||
srvr.Start
|
||||
|
||||
Log($"Web API server (version = $1.2{VERSION}) is running on port ${srvr.Port}"$)
|
||||
Log($"Open the following URL from your web browser"$)
|
||||
Log(ROOT_URL & ROOT_PATH)
|
||||
' Open a web browser and navigate to: http://127.0.0.1:19800/v1/
|
||||
StartMessageLoop
|
||||
End Sub
|
||||
|
||||
Public Sub OpenConnection (pool As ConnectionPool) As ConnectionPool
|
||||
Try
|
||||
pool.Initialize(Conn.DriverClass, Conn.JdbcUrl, Conn.User, Conn.Password)
|
||||
|
||||
Dim jo As JavaObject = pool
|
||||
jo.RunMethod("setMaxPoolSize", Array(Conn.MaxPoolSize))
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
End Try
|
||||
Return pool
|
||||
End Sub
|
||||
|
||||
Public Sub OpenSQLiteDB As SQL
|
||||
Dim DB As SQL
|
||||
DB.InitializeSQLite(File.DirApp, Conn.DbName, False)
|
||||
Return DB
|
||||
End Sub
|
||||
|
||||
#Region ConfigureSSL
|
||||
Private Sub ConfigureSSL (SslPort As Int)
|
||||
Dim KeyStoreDir As String = config.Get("SSL_KEYSTORE_DIR")
|
||||
Dim KeyStoreFile As String = config.Get("SSL_KEYSTORE_FILE")
|
||||
Dim KeyStorePassword As String = config.Get("SSL_KEYSTORE_PASSWORD")
|
||||
Dim ssl As SslConfiguration
|
||||
ssl.Initialize
|
||||
ssl.SetKeyStorePath(KeyStoreDir, KeyStoreFile)
|
||||
ssl.KeyStorePassword = KeyStorePassword
|
||||
'ssl.KeyManagerPassword = ""
|
||||
srvr.SetSslConfiguration(ssl, SslPort)
|
||||
'add filter to redirect all traffic from http to https (optional)
|
||||
srvr.AddFilter("/*", "HttpsFilter", False)
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
#Region ConfigureCORS
|
||||
' allowedOrigins = "*" or "http://google.com"
|
||||
' allowedMethods = "*" or "GET,POST,HEAD"
|
||||
' allowedHeaders = "*" or "X-Requested-With,Content-Type,Accept,Origin"
|
||||
Private Sub ConfigureCORS (Path As String, allowedOrigins As String, allowedMethods As String, allowedHeaders As String)
|
||||
' Reference: https://www.b4x.com/android/forum/threads/jetty-cross-origin-filter-to-be-added-to-jserver-library.85641/
|
||||
Dim cors As CorsFilter
|
||||
cors.Initialize(Path, CreateMap("allowedOrigins": allowedOrigins, _
|
||||
"allowedMethods": allowedMethods, _
|
||||
"allowedHeaders": allowedHeaders, _
|
||||
"allowCredentials": "true", _
|
||||
"preflightMaxAge": 1800, _
|
||||
"chainPreflight": "false"))
|
||||
cors.AddToServer(srvr)
|
||||
End Sub
|
||||
#End Region
|
||||
43
DPMMobileB4X/test/MyWebApi/Objects/config.ini
Normal file
43
DPMMobileB4X/test/MyWebApi/Objects/config.ini
Normal file
@@ -0,0 +1,43 @@
|
||||
# Product: Web API (server)
|
||||
# Version: 1.08
|
||||
# Developer: Aeric Poon
|
||||
# License: Open Source
|
||||
# Thanks to Erel, Anywhere Software for the great products and B4X community for encouragement and supports ;)
|
||||
# Lines starting with '#' are comments.
|
||||
# Backslash character at the end of line means that the command continues in the next line.
|
||||
|
||||
# Server Path
|
||||
ROOT_PATH=/v1/
|
||||
ROOT_URL=http://127.0.0.1
|
||||
|
||||
# Java server port
|
||||
ServerPort=19800
|
||||
SSLPort=0
|
||||
|
||||
# SSL Keystores
|
||||
SSL_KEYSTORE_DIR=/etc/letsencrypt/live/mydomain.com
|
||||
SSL_KEYSTORE_FILE=keystore.jks
|
||||
SSL_KEYSTORE_PASSWORD=xxxxxx
|
||||
|
||||
# Define App Constants
|
||||
HOME_TITLE=WEB API
|
||||
APP_TITLE=Web API
|
||||
APP_TRADEMARK=B4X
|
||||
APP_COPYRIGHT=Copyright B4X 2021
|
||||
|
||||
# DATABASE CONFIGURATION
|
||||
|
||||
# SQLite
|
||||
DbName=webapi.db
|
||||
DbType=sqlite
|
||||
DriverClass=com.sqlite.JdbcUrl
|
||||
JdbcUrl=jdbc:sqlite:webapi.db
|
||||
|
||||
# MySQL
|
||||
# DbName=webapi
|
||||
# DbType=mysql
|
||||
# DriverClass=com.mysql.jdbc.Driver
|
||||
# JdbcUrl=jdbc:mysql://localhost/webapi?characterEncoding=utf8&useSSL=false
|
||||
# User=root
|
||||
# Password=password
|
||||
# MaxPoolSize=100
|
||||
78
DPMMobileB4X/test/MyWebApi/Objects/queries-mysql.ini
Normal file
78
DPMMobileB4X/test/MyWebApi/Objects/queries-mysql.ini
Normal file
@@ -0,0 +1,78 @@
|
||||
# Product: SQL commands for Web API (for MySQL Backend)
|
||||
# Version: 1.08
|
||||
# Lines starting with '#' are comments.
|
||||
# Backslash character at the end of line means that the command continues in the next line.
|
||||
|
||||
# Check and create database
|
||||
CHECK_DATABASE=SELECT * FROM SCHEMATA WHERE SCHEMA_NAME = ?
|
||||
|
||||
CREATE_DATABASE=CREATE DATABASE {DBNAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
||||
|
||||
USE_DATABASE=USE {DBNAME}
|
||||
|
||||
# DROP_TABLE_IF_EXIST_TBL_CATEGORY=DROP TABLE IF EXISTS `tbl_category`
|
||||
|
||||
CREATE_TABLE_TBL_CATEGORY=CREATE TABLE `tbl_category` ( \
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, \
|
||||
`category_name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, \
|
||||
PRIMARY KEY (`id`) \
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
|
||||
INSERT_DUMMY_TBL_CATEGORY=INSERT INTO `tbl_category` (`category_name`) VALUES \
|
||||
('Hardwares'), \
|
||||
('Toys')
|
||||
|
||||
# DROP_TABLE_IF_EXIST_TBL_PRODUCTS=DROP TABLE IF EXISTS `tbl_products`
|
||||
|
||||
CREATE_TABLE_TBL_PRODUCTS=CREATE TABLE `tbl_products` ( \
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, \
|
||||
`category_id` int(11) NOT NULL, \
|
||||
`product_code` varchar(12) COLLATE utf8mb4_unicode_ci DEFAULT NULL, \
|
||||
`product_name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, \
|
||||
`product_price` decimal(10,2) DEFAULT '0.00', \
|
||||
PRIMARY KEY (`id`), \
|
||||
KEY `category_id` (`category_id`), \
|
||||
CONSTRAINT `tbl_products_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `tbl_category` (`id`) \
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
|
||||
INSERT_DUMMY_TBL_PRODUCTS=INSERT INTO `tbl_products` \
|
||||
(`category_id`, `product_code`, `product_name`, `product_price`) VALUES \
|
||||
(2, 'T001', 'Teddy Bear', 99.9), \
|
||||
(1, 'H001', 'Hammer', 15.75), \
|
||||
(2, 'T002', 'Optimus Prime', 1000.00)
|
||||
|
||||
# CATEGORY
|
||||
GET_ALL_CATEGORIES=SELECT * FROM `tbl_category`
|
||||
GET_CATEGORY_BY_ID=SELECT * FROM `tbl_category` WHERE `id` = ?
|
||||
ADD_NEW_CATEGORY=INSERT INTO `tbl_category` (`category_name`) SELECT ?
|
||||
EDIT_CATEGORY_BY_ID=UPDATE `tbl_category` SET `category_name` = ? WHERE `id` = ?
|
||||
REMOVE_CATEGORY_BY_ID=DELETE FROM `tbl_category` WHERE `id` = ?
|
||||
GET_ID_BY_CATEGORY_NAME=SELECT `id` FROM `tbl_category` WHERE `category_name` = ?
|
||||
|
||||
# PRODUCT
|
||||
GET_ALL_PRODUCTS_BY_CATEGORY=SELECT * FROM `tbl_products` \
|
||||
WHERE `category_id` = ?
|
||||
GET_PRODUCT_BY_CATEGORY_AND_ID=SELECT * FROM `tbl_products` \
|
||||
WHERE `category_id` = ? AND `id` = ?
|
||||
ADD_NEW_PRODUCT_BY_CATEGORY=INSERT INTO `tbl_products` \
|
||||
(`category_id`, `product_code`, `product_name`, `product_price`) SELECT ?, ?, ?, ?
|
||||
EDIT_PRODUCT_BY_CATEGORY_AND_ID=UPDATE `tbl_products` \
|
||||
SET `category_id` = ?, `product_code` = ?, `product_name` = ?, `product_price` = ? \
|
||||
WHERE `category_id` = ? AND `id` = ?
|
||||
REMOVE_PRODUCT_BY_CATEGORY_AND_ID=DELETE FROM `tbl_products` \
|
||||
WHERE `category_id` = ? AND `id` = ?
|
||||
GET_ID_BY_CATEGORY_ID_AND_PRODUCT_NAME=SELECT `id` FROM `tbl_products` \
|
||||
WHERE `category_id` = ? AND `product_name` = ?
|
||||
|
||||
# SEARCH
|
||||
SEARCH_PRODUCT_BY_CATEGORY_CODE_AND_NAME_ONEWORD_ORDERED=SELECT P.id AS aa, \
|
||||
P.product_code AS bb, C.`category_name` AS cc, P.product_name AS dd, P.product_price AS ee \
|
||||
FROM `tbl_products` P JOIN `tbl_category` C ON P.`category_id` = C.`id` \
|
||||
WHERE C.`category_name` LIKE ? OR P.`product_code` LIKE ? OR P.`product_name` LIKE ?
|
||||
SEARCH_PRODUCT_BY_CATEGORY_CODE_AND_NAME_TWOWORDS_ORDERED=SELECT P.id AS aa, \
|
||||
P.product_code AS bb, C.`category_name` AS cc, P.product_name AS dd, P.product_price AS ee \
|
||||
FROM `tbl_products` P JOIN `tbl_category` C ON P.`category_id` = C.`id` \
|
||||
WHERE C.`category_name` LIKE ? OR P.`product_code` LIKE ? OR P.`product_name` LIKE ? \
|
||||
OR C.`category_name` LIKE ? OR P.`product_code` LIKE ? OR P.`product_name` LIKE ?
|
||||
|
||||
GET_LAST_INSERT_ID=SELECT LAST_INSERT_ID()
|
||||
65
DPMMobileB4X/test/MyWebApi/Objects/queries-sqlite.ini
Normal file
65
DPMMobileB4X/test/MyWebApi/Objects/queries-sqlite.ini
Normal file
@@ -0,0 +1,65 @@
|
||||
# Product: SQL commands for Web API (for SQLite Backend)
|
||||
# Version: 1.08
|
||||
# Lines starting with '#' are comments.
|
||||
# Backslash character at the end of line means that the command continues in the next line.
|
||||
|
||||
# Create tables
|
||||
CREATE_TABLE_TBL_CATEGORY=CREATE TABLE IF NOT EXISTS `tbl_category` ( \
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT, \
|
||||
`category_name` varchar(200) NULL \
|
||||
)
|
||||
|
||||
INSERT_DUMMY_TBL_CATEGORY=INSERT INTO `tbl_category` (`category_name`) VALUES \
|
||||
('Hardwares'), \
|
||||
('Toys')
|
||||
|
||||
CREATE_TABLE_TBL_PRODUCTS=CREATE TABLE IF NOT EXISTS `tbl_products` ( \
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT, \
|
||||
`category_id` INTEGER NOT NULL, \
|
||||
`product_code` varchar(12) NULL, \
|
||||
`product_name` varchar(200) NULL, \
|
||||
`product_price` decimal(10,2) DEFAULT '0.00', \
|
||||
FOREIGN KEY (`category_id`) REFERENCES `tbl_category` (`id`) \
|
||||
)
|
||||
|
||||
INSERT_DUMMY_TBL_PRODUCTS=INSERT INTO `tbl_products` \
|
||||
(`category_id`, `product_code`, `product_name`, `product_price`) VALUES \
|
||||
(2, 'T001', 'Teddy Bear', 99.9), \
|
||||
(1, 'H001', 'Hammer', 15.75), \
|
||||
(2, 'T002', 'Optimus Prime', 1000.00)
|
||||
|
||||
# CATEGORY
|
||||
GET_ALL_CATEGORIES=SELECT * FROM `tbl_category`
|
||||
GET_CATEGORY_BY_ID=SELECT * FROM `tbl_category` WHERE `id` = ?
|
||||
ADD_NEW_CATEGORY=INSERT INTO `tbl_category` (`category_name`) SELECT ?
|
||||
EDIT_CATEGORY_BY_ID=UPDATE `tbl_category` SET `category_name` = ? WHERE `id` = ?
|
||||
REMOVE_CATEGORY_BY_ID=DELETE FROM `tbl_category` WHERE `id` = ?
|
||||
GET_ID_BY_CATEGORY_NAME=SELECT `id` FROM `tbl_category` WHERE `category_name` = ?
|
||||
|
||||
# PRODUCT
|
||||
GET_ALL_PRODUCTS_BY_CATEGORY=SELECT * FROM `tbl_products` \
|
||||
WHERE `category_id` = ?
|
||||
GET_PRODUCT_BY_CATEGORY_AND_ID=SELECT * FROM `tbl_products` \
|
||||
WHERE `category_id` = ? AND `id` = ?
|
||||
ADD_NEW_PRODUCT_BY_CATEGORY=INSERT INTO `tbl_products` \
|
||||
(`category_id`, `product_code`, `product_name`, `product_price`) SELECT ?, ?, ?, ?
|
||||
EDIT_PRODUCT_BY_CATEGORY_AND_ID=UPDATE `tbl_products` \
|
||||
SET `category_id` = ?, `product_code` = ?, `product_name` = ?, `product_price` = ? \
|
||||
WHERE `category_id` = ? AND `id` = ?
|
||||
REMOVE_PRODUCT_BY_CATEGORY_AND_ID=DELETE FROM `tbl_products` \
|
||||
WHERE `category_id` = ? AND `id` = ?
|
||||
GET_ID_BY_CATEGORY_ID_AND_PRODUCT_NAME=SELECT `id` FROM `tbl_products` \
|
||||
WHERE `category_id` = ? AND `product_name` = ?
|
||||
|
||||
# SEARCH
|
||||
SEARCH_PRODUCT_BY_CATEGORY_CODE_AND_NAME_ONEWORD_ORDERED=SELECT P.id AS aa, \
|
||||
P.product_code AS bb, C.`category_name` AS cc, P.product_name AS dd, P.product_price AS ee \
|
||||
FROM `tbl_products` P JOIN `tbl_category` C ON P.`category_id` = C.`id` \
|
||||
WHERE C.`category_name` LIKE ? OR P.`product_code` LIKE ? OR P.`product_name` LIKE ?
|
||||
SEARCH_PRODUCT_BY_CATEGORY_CODE_AND_NAME_TWOWORDS_ORDERED=SELECT P.id AS aa, \
|
||||
P.product_code AS bb, C.`category_name` AS cc, P.product_name AS dd, P.product_price AS ee \
|
||||
FROM `tbl_products` P JOIN `tbl_category` C ON P.`category_id` = C.`id` \
|
||||
WHERE C.`category_name` LIKE ? OR P.`product_code` LIKE ? OR P.`product_name` LIKE ? \
|
||||
OR C.`category_name` LIKE ? OR P.`product_code` LIKE ? OR P.`product_name` LIKE ?
|
||||
|
||||
GET_LAST_INSERT_ID=SELECT LAST_INSERT_ROWID()
|
||||
14
DPMMobileB4X/test/MyWebApi/Objects/start.bat
Normal file
14
DPMMobileB4X/test/MyWebApi/Objects/start.bat
Normal file
@@ -0,0 +1,14 @@
|
||||
REM ================================================================
|
||||
REM Run this batch file in Windows Command Prompt as Administrator
|
||||
REM ================================================================
|
||||
|
||||
@ECHO OFF
|
||||
TITLE Web API server is starting...
|
||||
|
||||
REM CD C:\Java\jdk-11.0.1\bin
|
||||
REM java --module-path C:\Java\jdk-11.0.1\javafx\lib --add-modules ALL-MODULE-PATH -jar "C:\Development\B4J\WebAPI\Objects\webapi.jar"
|
||||
|
||||
C:
|
||||
CD C:\Program Files\Java\jdk1.8.0_181\bin
|
||||
java -jar "C:\Development\B4J\WebAPI\Objects\webapi.jar"
|
||||
::PAUSE
|
||||
7
DPMMobileB4X/test/MyWebApi/Objects/www/assets/css/bootstrap.min.css
vendored
Normal file
7
DPMMobileB4X/test/MyWebApi/Objects/www/assets/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
DPMMobileB4X/test/MyWebApi/Objects/www/assets/css/fontawesome.min.css
vendored
Normal file
5
DPMMobileB4X/test/MyWebApi/Objects/www/assets/css/fontawesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
DPMMobileB4X/test/MyWebApi/Objects/www/assets/css/solid.min.css
vendored
Normal file
5
DPMMobileB4X/test/MyWebApi/Objects/www/assets/css/solid.min.css
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/*!
|
||||
* Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
*/
|
||||
@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:"Font Awesome 5 Free";font-weight:900}
|
||||
BIN
DPMMobileB4X/test/MyWebApi/Objects/www/assets/img/favicon.png
Normal file
BIN
DPMMobileB4X/test/MyWebApi/Objects/www/assets/img/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 865 B |
7
DPMMobileB4X/test/MyWebApi/Objects/www/assets/js/bootstrap.bundle.min.js
vendored
Normal file
7
DPMMobileB4X/test/MyWebApi/Objects/www/assets/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
DPMMobileB4X/test/MyWebApi/Objects/www/assets/js/jquery.min.js
vendored
Normal file
2
DPMMobileB4X/test/MyWebApi/Objects/www/assets/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,50 @@
|
||||
$( document ).ready(function() {
|
||||
$("#btnsearch").click(function(e) {
|
||||
e.preventDefault();
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/",
|
||||
data: $("form").serialize(),
|
||||
success: function(response)
|
||||
{
|
||||
if (response.s == "ok") {
|
||||
// console.log(response.r);
|
||||
var tbl_head = "";
|
||||
var tbl_body = "";
|
||||
if (response.r.length) {
|
||||
tbl_head = "<thead class=\"bg-light\"><th style=\"text-align: right\">#</th><th>Code</th><th>Category</th><th>Name</th><th style=\"text-align: right\">Price</th></thead>";
|
||||
tbl_body += "<tbody>";
|
||||
$.each(response.r, function() {
|
||||
var tbl_row = "";
|
||||
$.each(this, function(key, value) {
|
||||
if (key == "ee" || key == "aa")
|
||||
{
|
||||
tbl_row += "<td style=\"text-align: right\">"+value+"</td>";
|
||||
}
|
||||
else
|
||||
{
|
||||
tbl_row += "<td>"+value+"</td>";
|
||||
}
|
||||
});
|
||||
tbl_body += "<tr>"+tbl_row+"</tr>";
|
||||
});
|
||||
tbl_body += "</tbody>";
|
||||
}
|
||||
else
|
||||
{
|
||||
tbl_body = "<tr><td>No results</td></tr>";
|
||||
}
|
||||
$("#results table").html(tbl_head+tbl_body);
|
||||
}
|
||||
else {
|
||||
$(".alert").html(response.e);
|
||||
$(".alert").fadeIn();
|
||||
}
|
||||
},
|
||||
error: function (xhr, ajaxOptions, thrownError) {
|
||||
$(".alert").html(thrownError);
|
||||
$(".alert").fadeIn();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
403
DPMMobileB4X/test/MyWebApi/ProductHandler.bas
Normal file
403
DPMMobileB4X/test/MyWebApi/ProductHandler.bas
Normal file
@@ -0,0 +1,403 @@
|
||||
B4J=true
|
||||
Group=Handlers
|
||||
ModulesStructureVersion=1
|
||||
Type=Class
|
||||
Version=9.1
|
||||
@EndOfDesignText@
|
||||
' Product Handler class
|
||||
Sub Class_Globals
|
||||
Dim Request As ServletRequest
|
||||
Dim Response As ServletResponse
|
||||
Dim pool As ConnectionPool
|
||||
Dim Elements() As String
|
||||
End Sub
|
||||
|
||||
Public Sub Initialize
|
||||
|
||||
End Sub
|
||||
|
||||
Sub Handle (req As ServletRequest, resp As ServletResponse)
|
||||
Request = req
|
||||
Response = resp
|
||||
|
||||
Elements = Regex.Split("/", req.RequestURI)
|
||||
If CheckMaxElements = False Then
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
Return
|
||||
End If
|
||||
If CheckAllowedVerb = False Then
|
||||
Utility.ReturnError("Method Not Allowed", 405, Response)
|
||||
Return
|
||||
End If
|
||||
ProcessRequest
|
||||
End Sub
|
||||
|
||||
Private Sub ProcessRequest
|
||||
Select Case Request.Method.ToUpperCase
|
||||
Case "GET"
|
||||
Select Case Elements.Length - 1
|
||||
Case Main.Element.Root ' /
|
||||
|
||||
Case Main.Element.Parent ' /category
|
||||
If Elements(Main.Element.Parent) = "category" Then
|
||||
GetCategories("")
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Main.Element.Parent_Id ' /category/{cat_id}
|
||||
If Elements(Main.Element.Parent) = "category" Then
|
||||
GetCategories(Elements(Main.Element.Parent_Id))
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Main.Element.Child ' /category/{cat_id}/product
|
||||
If Elements(Main.Element.Parent) = "category" And Elements(Main.Element.Child) = "product" Then
|
||||
GetProductsByCategories(Elements(Main.Element.Parent_Id), "")
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Main.Element.Child_Id ' /category/{cat_id}/product/{product_id}
|
||||
If Elements(Main.Element.Parent) = "category" And Elements(Main.Element.Child) = "product" Then
|
||||
GetProductsByCategories(Elements(Main.Element.Parent_Id), Elements(Main.Element.Child_Id))
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End Select
|
||||
Case "POST"
|
||||
Select Case Elements.Length - 1
|
||||
Case Main.Element.Parent ' /category
|
||||
If Elements(Main.Element.Parent) = "category" Then
|
||||
PostCategory
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Main.Element.Child ' /category/{cat_id}/product
|
||||
If Elements(Main.Element.Parent) = "category" And Elements(Main.Element.Child) = "product" Then
|
||||
PostProductByCategory(Elements(Main.Element.Parent_Id))
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End Select
|
||||
Case "PUT"
|
||||
Select Case Elements.Length - 1
|
||||
Case Main.Element.Parent_Id ' /category/{cat_id}
|
||||
If Elements(Main.Element.Parent) = "category" Then
|
||||
PutCategoryById(Elements(Main.Element.Parent_Id))
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Main.Element.Child_Id ' /category/{cat_id}/product/{product_id}
|
||||
If Elements(Main.Element.Parent) = "category" And Elements(Main.Element.Child) = "product" Then
|
||||
PutProductByCategoryAndId(Elements(Main.Element.Parent_Id), Elements(Main.Element.Child_Id))
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End Select
|
||||
Case "DELETE"
|
||||
Select Case Elements.Length - 1
|
||||
Case Main.Element.Parent_Id ' /category/{cat_id}
|
||||
If Elements(Main.Element.Parent) = "category" Then
|
||||
DeleteCategoryById(Elements(Main.Element.PARENT_ID))
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Main.Element.Child_Id ' /category/{cat_id}/product/{product_id}
|
||||
If Elements(Main.Element.Parent) = "category" And Elements(Main.Element.Child) = "product" Then
|
||||
DeleteProductsByCategoryAndId(Elements(Main.Element.Parent_Id), Elements(Main.Element.Child_Id))
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Case Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End Select
|
||||
End Select
|
||||
End Sub
|
||||
|
||||
Private Sub CheckMaxElements As Boolean
|
||||
If Elements.Length > Main.Element.Max_Elements Or Elements.Length = 0 Then
|
||||
Return False
|
||||
End If
|
||||
Return True
|
||||
End Sub
|
||||
|
||||
Private Sub CheckAllowedVerb As Boolean
|
||||
'Methods: POST, GET, PUT, PATCH, DELETE
|
||||
Dim SupportedMethods As List = Array As String("POST", "GET", "PUT", "DELETE")
|
||||
If SupportedMethods.IndexOf(Request.Method) = -1 Then
|
||||
Return False
|
||||
End If
|
||||
Return True
|
||||
End Sub
|
||||
|
||||
Sub OpenDB As SQL
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("mysql") Then
|
||||
pool = Main.OpenConnection(pool)
|
||||
Return pool.GetConnection
|
||||
End If
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("sqlite") Then
|
||||
Return Main.OpenSQLiteDB
|
||||
End If
|
||||
Return Null
|
||||
End Sub
|
||||
|
||||
Sub CloseDB (con As SQL)
|
||||
If con <> Null And con.IsInitialized Then con.Close
|
||||
If Main.Conn.DbType.EqualsIgnoreCase("mysql") Then
|
||||
If pool.IsInitialized Then pool.ClosePool
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Sub GetCategories (cat_id As String)
|
||||
Dim con As SQL = OpenDB
|
||||
Dim strSQL As String
|
||||
Try
|
||||
If cat_id = "" Then
|
||||
strSQL = Main.queries.Get("GET_ALL_CATEGORIES")
|
||||
Dim res As ResultSet = con.ExecQuery(strSQL)
|
||||
Else
|
||||
strSQL = Main.queries.Get("GET_CATEGORY_BY_ID")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(cat_id))
|
||||
End If
|
||||
|
||||
Dim List1 As List
|
||||
List1.Initialize
|
||||
Do While res.NextRow
|
||||
Dim Map2 As Map
|
||||
Map2.Initialize
|
||||
For i = 0 To res.ColumnCount - 1
|
||||
Map2.Put(res.GetColumnName(i), res.GetString2(i))
|
||||
Next
|
||||
List1.Add(Map2)
|
||||
Loop
|
||||
If List1.Size = 0 Then
|
||||
Utility.ReturnError("Category Not Found", 404, Response)
|
||||
Else
|
||||
Utility.ReturnSuccess2(List1, 200, Response)
|
||||
End If
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
Utility.ReturnError("Error Execute Query", 422, Response)
|
||||
End Try
|
||||
CloseDB(con)
|
||||
End Sub
|
||||
|
||||
Sub GetProductsByCategories (cat_id As String, id As String)
|
||||
Dim con As SQL = OpenDB
|
||||
Dim strSQL As String
|
||||
Try
|
||||
If id = "" Then
|
||||
strSQL = Main.queries.Get("GET_ALL_PRODUCTS_BY_CATEGORY")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(cat_id))
|
||||
Else
|
||||
strSQL = Main.queries.Get("GET_PRODUCT_BY_CATEGORY_AND_ID")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(cat_id, id))
|
||||
End If
|
||||
|
||||
Dim List1 As List
|
||||
List1.Initialize
|
||||
Do While res.NextRow
|
||||
Dim Map2 As Map
|
||||
Map2.Initialize
|
||||
For i = 0 To res.ColumnCount - 1
|
||||
If res.GetColumnName(i) = "product_price" Then
|
||||
Map2.Put(res.GetColumnName(i), res.GetDouble2(i))
|
||||
Else If res.GetColumnName(i) = "category_id" Or res.GetColumnName(i) = "id" Then
|
||||
Map2.Put(res.GetColumnName(i), res.GetInt2(i))
|
||||
Else
|
||||
Map2.Put(res.GetColumnName(i), res.GetString2(i))
|
||||
End If
|
||||
Next
|
||||
List1.Add(Map2)
|
||||
Loop
|
||||
If List1.Size = 0 Then
|
||||
Utility.ReturnError("Product Not Found", 404, Response)
|
||||
Else
|
||||
Utility.ReturnSuccess2(List1, 200, Response)
|
||||
End If
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
Utility.ReturnError("Error Execute Query", 422, Response)
|
||||
End Try
|
||||
CloseDB(con)
|
||||
End Sub
|
||||
|
||||
Sub PostCategory
|
||||
Dim con As SQL = OpenDB
|
||||
Dim strSQL As String
|
||||
Try
|
||||
Dim data As Map = Utility.RequestData(Request)
|
||||
If data.IsInitialized Then
|
||||
strSQL = Main.queries.Get("GET_ID_BY_CATEGORY_NAME")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(data.Get("name")))
|
||||
If res.NextRow Then
|
||||
Utility.ReturnError("Category Already Exist", 409, Response)
|
||||
Else
|
||||
strSQL = Main.queries.Get("ADD_NEW_CATEGORY")
|
||||
con.BeginTransaction
|
||||
con.ExecNonQuery2(strSQL, Array As String(data.Get("name")))
|
||||
strSQL = Main.queries.Get("GET_LAST_INSERT_ID")
|
||||
Dim NewId As Int = con.ExecQuerySingleResult(strSQL)
|
||||
strSQL = Main.queries.Get("GET_CATEGORY_BY_ID")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(NewId))
|
||||
con.TransactionSuccessful
|
||||
Dim List1 As List
|
||||
List1.Initialize
|
||||
Do While res.NextRow
|
||||
Dim Map2 As Map
|
||||
Map2.Initialize
|
||||
For i = 0 To res.ColumnCount - 1
|
||||
Map2.Put(res.GetColumnName(i), res.GetString2(i))
|
||||
Next
|
||||
List1.Add(Map2)
|
||||
Loop
|
||||
Utility.ReturnSuccess2(List1, 201, Response)
|
||||
'Dim URL As String = $"${Main.ROOT_URL}${Main.ROOT_PATH}category/${NewId}"$
|
||||
'Utility.ReturnLocation(URL, 201, Response)
|
||||
End If
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
Utility.ReturnError("Error Execute Query", 422, Response)
|
||||
End Try
|
||||
CloseDB(con)
|
||||
End Sub
|
||||
|
||||
Sub PostProductByCategory (cat_id As String)
|
||||
Dim con As SQL = OpenDB
|
||||
Dim strSQL As String
|
||||
Try
|
||||
strSQL = Main.queries.Get("GET_CATEGORY_BY_ID")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(cat_id))
|
||||
If res.NextRow Then
|
||||
Dim data As Map = Utility.RequestData(Request)
|
||||
If data.IsInitialized Then
|
||||
strSQL = Main.queries.Get("ADD_NEW_PRODUCT_BY_CATEGORY")
|
||||
con.BeginTransaction
|
||||
con.ExecNonQuery2(strSQL, Array As String(cat_id, data.Get("code"), data.Get("name"), data.Get("price")))
|
||||
strSQL = Main.queries.Get("GET_LAST_INSERT_ID")
|
||||
Dim NewId As Int = con.ExecQuerySingleResult(strSQL)
|
||||
strSQL = Main.queries.Get("GET_PRODUCT_BY_CATEGORY_AND_ID")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(cat_id, NewId))
|
||||
con.TransactionSuccessful
|
||||
Dim List1 As List
|
||||
List1.Initialize
|
||||
Do While res.NextRow
|
||||
Dim Map2 As Map
|
||||
Map2.Initialize
|
||||
For i = 0 To res.ColumnCount - 1
|
||||
Map2.Put(res.GetColumnName(i), res.GetString2(i))
|
||||
Next
|
||||
List1.Add(Map2)
|
||||
Loop
|
||||
Utility.ReturnSuccess2(List1, 201, Response)
|
||||
'Dim URL As String = $"${Main.ROOT_URL}${Main.ROOT_PATH}category/${cat_id}/${NewId}"$
|
||||
'Utility.Returnlocation(URL, 201, Response)
|
||||
Return
|
||||
End If
|
||||
Else
|
||||
Utility.ReturnError("Category Not Found", 404, Response)
|
||||
End If
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
Utility.ReturnError("Error Execute Query", 422, Response)
|
||||
End Try
|
||||
CloseDB(con)
|
||||
End Sub
|
||||
|
||||
Sub PutCategoryById (cat_id As String)
|
||||
Dim con As SQL = OpenDB
|
||||
Dim strSQL As String
|
||||
Try
|
||||
strSQL = Main.queries.Get("GET_CATEGORY_BY_ID")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(cat_id))
|
||||
If res.NextRow Then
|
||||
Dim data As Map = Utility.RequestData(Request)
|
||||
If data.IsInitialized Then
|
||||
strSQL = Main.queries.Get("EDIT_CATEGORY_BY_ID")
|
||||
con.ExecNonQuery2(strSQL, Array As Object(data.Get("name"), cat_id))
|
||||
Utility.ReturnSuccess(CreateMap("result": "success"), 200, Response)
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Else
|
||||
Utility.ReturnError("Category Not Found", 404, Response)
|
||||
End If
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
Utility.ReturnError("Error Execute Query", 422, Response)
|
||||
End Try
|
||||
CloseDB(con)
|
||||
End Sub
|
||||
|
||||
Sub PutProductByCategoryAndId (cat_id As String, id As String)
|
||||
Dim con As SQL = OpenDB
|
||||
Dim strSQL As String
|
||||
Try
|
||||
strSQL = Main.queries.Get("GET_PRODUCT_BY_CATEGORY_AND_ID")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As String(cat_id, id))
|
||||
If res.NextRow Then
|
||||
Dim data As Map = Utility.RequestData(Request)
|
||||
If data.IsInitialized Then
|
||||
strSQL = Main.queries.Get("EDIT_PRODUCT_BY_CATEGORY_AND_ID")
|
||||
con.ExecNonQuery2(strSQL, Array As Object(cat_id, data.Get("code"), data.Get("name"), data.Get("price"), cat_id, id))
|
||||
Utility.ReturnSuccess(CreateMap("result": "success"), 200, Response)
|
||||
Else
|
||||
Utility.ReturnError("Bad Request", 400, Response)
|
||||
End If
|
||||
Else
|
||||
Utility.ReturnError("Product Not Found", 404, Response)
|
||||
End If
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
Utility.ReturnError("Error Execute Query", 422, Response)
|
||||
End Try
|
||||
CloseDB(con)
|
||||
End Sub
|
||||
|
||||
Sub DeleteCategoryById (cat_id As String)
|
||||
Dim con As SQL = OpenDB
|
||||
Dim strSQL As String
|
||||
Try
|
||||
strSQL = Main.queries.Get("GET_CATEGORY_BY_ID")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As Int(cat_id))
|
||||
If res.NextRow Then
|
||||
strSQL = Main.queries.Get("REMOVE_CATEGORY_BY_ID")
|
||||
con.ExecNonQuery2(strSQL, Array As Int(cat_id))
|
||||
Utility.ReturnSuccess(CreateMap("result": "success"), 200, Response)
|
||||
Else
|
||||
Utility.ReturnError("Category Not Found", 404, Response)
|
||||
End If
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
Utility.ReturnError("Error Execute Query", 422, Response)
|
||||
End Try
|
||||
CloseDB(con)
|
||||
End Sub
|
||||
|
||||
Sub DeleteProductsByCategoryAndId (cat_id As String, id As String)
|
||||
Dim con As SQL = OpenDB
|
||||
Dim strSQL As String
|
||||
Try
|
||||
strSQL = Main.queries.Get("GET_PRODUCT_BY_CATEGORY_AND_ID")
|
||||
Dim res As ResultSet = con.ExecQuery2(strSQL, Array As Int(cat_id, id))
|
||||
If res.NextRow Then
|
||||
strSQL = Main.queries.Get("REMOVE_PRODUCT_BY_CATEGORY_AND_ID")
|
||||
con.ExecNonQuery2(strSQL, Array As Int(cat_id, id))
|
||||
Utility.ReturnSuccess(CreateMap("result": "success"), 200, Response)
|
||||
Else
|
||||
Utility.ReturnError("Product Not Found", 404, Response)
|
||||
End If
|
||||
Catch
|
||||
LogDebug(LastException)
|
||||
Utility.ReturnError("Error Execute Query", 422, Response)
|
||||
End Try
|
||||
CloseDB(con)
|
||||
End Sub
|
||||
102
DPMMobileB4X/test/MyWebApi/Utility.bas
Normal file
102
DPMMobileB4X/test/MyWebApi/Utility.bas
Normal file
@@ -0,0 +1,102 @@
|
||||
B4J=true
|
||||
Group=Modules
|
||||
ModulesStructureVersion=1
|
||||
Type=StaticCode
|
||||
Version=8.1
|
||||
@EndOfDesignText@
|
||||
' Utility Code module
|
||||
' Version 1.08
|
||||
Sub Process_Globals
|
||||
Private const CONTENT_TYPE_JSON As String = "application/json"
|
||||
Private const CONTENT_TYPE_HTML As String = "text/html"
|
||||
End Sub
|
||||
|
||||
Public Sub BuildHtml (strHTML As String, Settings As Map) As String
|
||||
' Replace $KEY$ tag with new content from Map
|
||||
strHTML = WebUtils.ReplaceMap(strHTML, Settings)
|
||||
Return strHTML
|
||||
End Sub
|
||||
|
||||
Public Sub BuildView (strHTML As String, View As String) As String
|
||||
' Replace @VIEW@ tag with new content
|
||||
strHTML = strHTML.Replace("@VIEW@", View)
|
||||
Return strHTML
|
||||
End Sub
|
||||
|
||||
Public Sub ReadMapFile (FileDir As String, FileName As String) As Map
|
||||
Dim strPath As String = File.Combine(FileDir, FileName)
|
||||
Log($"Reading file (${strPath})..."$)
|
||||
Return File.ReadMap(FileDir, FileName)
|
||||
End Sub
|
||||
|
||||
Public Sub ReadTextFile (FileName As String) As String
|
||||
Return File.ReadString(File.DirAssets, FileName)
|
||||
End Sub
|
||||
|
||||
Public Sub Map2Json (M As Map) As String
|
||||
Return M.As(JSON).ToString
|
||||
End Sub
|
||||
|
||||
public Sub RequestData (Request As ServletRequest) As Map
|
||||
Dim mdl As String = "RequestData"
|
||||
Try
|
||||
Dim data As Map
|
||||
Dim ins As InputStream = Request.InputStream
|
||||
If ins.BytesAvailable <= 0 Then
|
||||
Return data
|
||||
End If
|
||||
Dim tr As TextReader
|
||||
tr.Initialize(ins)
|
||||
Dim json As JSONParser
|
||||
json.Initialize(tr.ReadAll)
|
||||
data = json.NextObject
|
||||
Catch
|
||||
LogDebug($"${mdl} "$ & LastException)
|
||||
End Try
|
||||
Return data
|
||||
End Sub
|
||||
|
||||
Public Sub ReturnHTML (str As String, resp As ServletResponse)
|
||||
resp.ContentType = CONTENT_TYPE_HTML
|
||||
resp.Write(str)
|
||||
End Sub
|
||||
|
||||
Public Sub ReturnConnect (resp As ServletResponse)
|
||||
Dim Result As List
|
||||
Result.Initialize
|
||||
Result.Add(CreateMap("connect": "true"))
|
||||
resp.ContentType = CONTENT_TYPE_JSON
|
||||
resp.Write(Map2Json(CreateMap("s": "ok", "m": "success", "r": Result, "e": Null)))
|
||||
End Sub
|
||||
|
||||
Public Sub ReturnError (Error As String, Code As Int, resp As ServletResponse)
|
||||
If Error = "" Then Error = "unknown"
|
||||
Dim Result As List
|
||||
Result.Initialize
|
||||
resp.ContentType = CONTENT_TYPE_JSON
|
||||
resp.Status = Code
|
||||
resp.Write(Map2Json(CreateMap("s": "error", "m": Null, "r": Result, "e": Error)))
|
||||
End Sub
|
||||
|
||||
Public Sub ReturnSuccess (Data As Map, Code As Int, resp As ServletResponse)
|
||||
If Data.IsInitialized = False Then Data.Initialize
|
||||
Dim Result As List
|
||||
Result.Initialize
|
||||
Result.Add(Data)
|
||||
Dim Map1 As Map = CreateMap("s": "ok", "m": "success", "r": Result, "e": Null)
|
||||
resp.ContentType = CONTENT_TYPE_JSON
|
||||
resp.Status = Code
|
||||
resp.Write(Map2Json(Map1))
|
||||
End Sub
|
||||
|
||||
Public Sub ReturnSuccess2 (Data As List, Code As Int, resp As ServletResponse)
|
||||
If Data.IsInitialized = False Then Data.Initialize
|
||||
Dim Map1 As Map = CreateMap("s": "ok", "m": "success", "r": Data, "e": Null)
|
||||
resp.ContentType = CONTENT_TYPE_JSON
|
||||
resp.Status = Code
|
||||
resp.Write(Map2Json(Map1))
|
||||
End Sub
|
||||
|
||||
Public Sub ReturnLocation (Location As String, resp As ServletResponse) ' Code = 302
|
||||
resp.SendRedirect(Location)
|
||||
End Sub
|
||||
91
DPMMobileB4X/test/MyWebApi/WebUtils.bas
Normal file
91
DPMMobileB4X/test/MyWebApi/WebUtils.bas
Normal file
@@ -0,0 +1,91 @@
|
||||
B4J=true
|
||||
Group=Modules
|
||||
ModulesStructureVersion=1
|
||||
Type=StaticCode
|
||||
Version=8.31
|
||||
@EndOfDesignText@
|
||||
' WebUtils Code module
|
||||
' Version 1.00
|
||||
Sub Process_Globals
|
||||
Public bc As ByteConverter
|
||||
End Sub
|
||||
|
||||
Public Sub init
|
||||
bc.LittleEndian = True
|
||||
End Sub
|
||||
|
||||
#Region Test
|
||||
|
||||
Public Sub EscapeHtml(Raw As String) As String
|
||||
Dim sb As StringBuilder
|
||||
sb.Initialize
|
||||
For i = 0 To Raw.Length - 1
|
||||
Dim C As Char = Raw.CharAt(i)
|
||||
Select C
|
||||
Case QUOTE
|
||||
sb.Append(""")
|
||||
Case "'"
|
||||
sb.Append("'")
|
||||
Case "<"
|
||||
sb.Append("<")
|
||||
Case ">"
|
||||
sb.Append(">")
|
||||
Case "&"
|
||||
sb.Append("&")
|
||||
Case Else
|
||||
sb.Append(C)
|
||||
End Select
|
||||
Next
|
||||
Return sb.ToString
|
||||
End Sub
|
||||
|
||||
Public Sub ReplaceMap(Base As String, Replacements As Map) As String
|
||||
Dim pattern As StringBuilder
|
||||
pattern.Initialize
|
||||
For Each k As String In Replacements.Keys
|
||||
If pattern.Length > 0 Then pattern.Append("|")
|
||||
pattern.Append("\$").Append(k).Append("\$")
|
||||
Next
|
||||
Dim m As Matcher = Regex.Matcher(pattern.ToString, Base)
|
||||
Dim result As StringBuilder
|
||||
result.Initialize
|
||||
Dim lastIndex As Int
|
||||
Do While m.Find
|
||||
result.Append(Base.SubString2(lastIndex, m.GetStart(0)))
|
||||
Dim replace As String = Replacements.Get(m.Match.SubString2(1, m.Match.Length - 1))
|
||||
If m.Match.ToLowerCase.StartsWith("$h_") Then replace = EscapeHtml(replace)
|
||||
result.Append(replace)
|
||||
lastIndex = m.GetEnd(0)
|
||||
Loop
|
||||
If lastIndex < Base.Length Then result.Append(Base.SubString(lastIndex))
|
||||
Return result.ToString
|
||||
End Sub
|
||||
|
||||
Public Sub RedirectTo(ws As WebSocket, TargetUrl As String)
|
||||
ws.Eval("window.location = arguments[0]", Array As Object(TargetUrl))
|
||||
End Sub
|
||||
|
||||
Public Sub ReadString(In As InputStream) As String
|
||||
Dim len As Int = bc.IntsFromBytes(ReadBytesFromStream(In, 4))(0)
|
||||
Return BytesToString(ReadBytesFromStream(In, len), 0, len, "UTF8")
|
||||
End Sub
|
||||
|
||||
#End Region
|
||||
|
||||
Sub ReadBytesFromStream(In As InputStream, Length As Int) As Byte()
|
||||
If Length > 5000 Then
|
||||
Log("Error reading from stream")
|
||||
Return Null
|
||||
End If
|
||||
Dim b(Length) As Byte
|
||||
Dim count As Int = 0
|
||||
Do While count < Length
|
||||
Dim read As Int = In.ReadBytes(b, count, Length - count)
|
||||
If read <= 0 Then
|
||||
Log("Error reading from stream.")
|
||||
Return Null
|
||||
End If
|
||||
count = count + read
|
||||
Loop
|
||||
Return b
|
||||
End Sub
|
||||
Reference in New Issue
Block a user