Веб-движок на Java

Использование и разработка софта (преимущественно на ПЦ)

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Веб-движок на Java

Post by Shaos »

Уже неделю пишу веб-движок на Java для своего сайта shabarshin.com (с java-хостингом). Движок запускается сервлетом и может анализировать параметры переданные через POST или GET, обращаться к базам данных MySQL и парсить темплейты из файлов-шаблонов лежащих на сервере. Вот какие классы уже созданы и отлажены:
WebDir.java - класс для представления доступа к файлам на сервере через объекты File
WebModule.java - интерфейс абстрактных веб-модулей
WebParam.java - класс параметров получаемых через POST или GET
WebPrint.java - интерфейс обобщенного выходного потока
WebSQL.java - класс доступа к базам данных MySQL
WebStrings.java - класс индексируемого динамического списка строк
Основной класс движка WebEngine.java (парсер для файлов-темплейтов) еще не доделан. После отладки файлов по отдельности планирую собрать их в пакет com.shabarshin.web и выложить с исходниками под лицензией GPL.
Last edited by Shaos on 21 Feb 2005 16:28, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Интерфейсный класс WebPrint.java:

Code: Select all

interface WebPrint
{
 void print(String str);
 void println(String str);
}
Интерфейсный класс WebModule.java:

Code: Select all

interface WebModule
{
 boolean init(WebPrint o, WebParam p, WebSQL s, WebDir d);
 boolean act(String s);
}
WebDir - это надстройка над File, который является описателем директория
WebParam - это надстройка над Hashtable со строковыми элементами
WebStrings - это надстройка над ArrayList со строковыми элементами
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote: Интерфейсный класс WebModule.java:

Code: Select all

interface WebModule
{
 boolean init(WebPrint o, WebParam p, WebSQL s, WebDir d);
 boolean act(String s);
}
Основная идея - отображаемая страница состоит из веб-модулей, генерируемых объектами WebModule либо составляемых из шаблонов (через WebEngine, который тоже принимает интерфейс WebModule). Будучи запущенным, главный сервлет создает объект класса WebEngine и передает ему через аргументы ссылку на печатающий объект WebPrint, ссылку на объект WebParam содержащий POST/GET параметры, ссылку на объект WebSQL связанный с уже открытой базой данных и объект WebDir связанный с катологом файлов-шаблонов. Затем главный сервлет дает парсеру WebEngine отпарсить главный шаблон (например index.web) внутри которого будут указываться коды HTML и некие простые условия сборки и вызова других модулей WebModule. Все модули через интерфейс WebPrint пишут в HTML страницу которая затем появляется в браузере пользователя.

В будущем планирую на основе этой технологии сделать сайт rwar.net с форумом.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Веб-движок com.shabarshin.web

Post by Shaos »

Shaos wrote: Основной класс движка WebEngine.java (парсер для файлов-темплейтов) еще не доделан.
Основной класс движка закончен. WebEngine принимает файлы *.web которые состоят из HTML команд и команд движка:

\MODULE name Module - загрузка модуля Module под именем name
\ACT name argument - выполнить действие в модуле name послав ему argument
\VAL param - вывести значение параметра
\IF param - блок "если" по наличию параметра
\ELIF param - блок "иначе-если" по наличию параметра
\ELSE - блок "иначе"
\ENDIF - конец блоков "елси-иначе"
Last edited by Shaos on 21 Feb 2005 10:42, edited 2 times in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Веб-движок com.shabarshin.web

Post by Shaos »

Shaos wrote:
Shaos wrote: Основной класс движка WebEngine.java (парсер для файлов-темплейтов) еще не доделан.
Основной класс движка закончен.
Движок в исходниках сейчас весит всего 655 строк (9 файлов). Для полного теста можно запустить http://shabarshin.com/servlet/Rwar (внизу страницы будет написан код из index.web) и тоже самое с параметром http://shabarshin.com/servlet/Rwar?test=1
Last edited by Shaos on 21 Feb 2005 07:03, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Вот пример тестового модуля WebTest.java с тремя действиями Base, Para, File которые тестируют базу данных, определение параметров и чтение файлов, соответственно:

Code: Select all

// WebTest.java   A.A.Shabarshin 17.02.2005-21.02.2005

import java.io.*;

public class WebTest implements WebModule
{
    WebPrint out = null;
    WebParam par = null;
    WebSQL sql = null;
    WebDir dir = null;

    public boolean init(WebPrint o, WebParam p, WebSQL s, WebDir d)
    {
	out = o;
	par = p;
	sql = s;
	dir = d;
	return true;
    }

    public boolean act(String s)
    {
	if(s.equals("Base")) return actBase();
	if(s.equals("Para")) return actPara();
	if(s.equals("File")) return actFile();
	return false;
    }

    boolean actBase()
    {
	out.println("<h1>Base</h1>");
	WebStrings f = new WebStrings();
	f.add("id");
	f.add("foo");
	f.add("bar");
	WebStrings r = new WebStrings();
	int k = sql.exec("SELECT * from testdata",f,r);
	out.println("TEST="+k+"> "+r);
	return true;        
    }

    boolean actPara()
    {
	out.println("<h1>Para</h1>");
	WebStrings keys = par.keys();
        for(int i=0;i<keys.size();i++) 
	{
	    String name = keys.get(i);
	    String value = par.get(name);
            out.println(name + " = " + value + "<br>");	
	}	
	return true;
    }

    boolean actFile()
    {
	out.println("<h1>File</h1>");
	out.println("DIR="+dir+"<p>");
	String files[] = dir.list();
	for(int i=0;i<files.length;i++)
	    out.println("file["+i+"]="+files[i]+"<p>");
	out.println("<b>index.web:</b><pre>");    
	try {
	    BufferedReader read = 
	    new BufferedReader(
		new InputStreamReader(
		    new FileInputStream(dir.file("index.web"))));
	    while(true)
	    {
	        String buffer = read.readLine();
		if(buffer!=null) out.println(buffer);
		else break;

	    }
    	    read.close();
	} catch(IOException e) {
	    out.println(" IOException "+e);
	}
	out.println("</pre>");    
	return true;    
    }

}
Вот вариант запуска модуля через web-шаблон:

\MODULE test WebTest
\ACT test Base
\ACT test Para
\ACT test File
Last edited by Shaos on 21 Feb 2005 11:52, edited 3 times in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Добавил новый класс веб-модуля WebSet.java:

Code: Select all

// WebSet.java  A.A.Shabarshin 21.02.2005

public class WebSet implements WebModule
{
    WebPrint out = null;
    WebParam par = null;
    WebSQL sql = null;
    WebDir dir = null;

    public boolean init(WebPrint o, WebParam p, WebSQL s, WebDir d)
    {
	out = o;
	par = p;
	sql = s;
	dir = d;
	return true;
    }

    public boolean act(String s)
    {
	// action in form "name=value"
	String[] para = s.split("=");
	// out.println("["+para[0]+","+para[1]+"]<br>");
	if(para.length!=2 || para[0]==null || para[1]==null) return false;
	par.put(para[0],para[1]);
	return true;
    }

}
Модуль предназначен для добавления параметров непосредственно из web-шаблонов. Например:

\MODULE set WebSet
\ACT set key1=101
\ACT set key2=102

После выполнения данного кода к списку параметров сессии добавятся два параметра с именами key1 и key2 имеющих значения 101 и 102 соответственно.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Основной плюс движка в том, что он может использоваться не только с сервлетами, но например и с автономной программой на Java (для отладки без веб-сервера).

Вот пример сервлета стартующего движок:

Code: Select all

// Rwar.java  A.A.Shabarshin 17.02.2005-21.02.2005

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Rwar extends HttpServlet implements WebPrint 
{
    final static boolean LOCAL = true;
    final static String path = "...";
    final static String host = "...";
    final static String base = "...";
    final static String user = "...";
    final static String pass = "...";    
    PrintWriter out = null;

    public void print(String str)
    {
        if(out!=null) out.print(str); 
    }

    public void println(String str)
    {
        if(out!=null) out.println(str); 
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
        doPost(request,response);
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
        response.setContentType("text/html");
        out = response.getWriter();
	WebParam param = new WebParam();
	Enumeration e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String name = (String)e.nextElement();
            String value = request.getParameter(name);
            param.put(name,value);	
	}    
	WebSQL mysql = new WebSQL(this);
	mysql.setBase(base);
	mysql.setUser(user);
	mysql.setPass(pass);
	if(!LOCAL) mysql.setHost(host);
	else mysql.setHost("localhost");
	mysql.open();
	WebEngine web = new WebEngine();	
	web.init(this,param,mysql,new WebDir(path));
        web.act("main.web");
	mysql.close();
    }
}
А вот тоже самое, но в виде автономной программы (HTML-код генерируется в стандартный выходной поток):

Code: Select all

// rwar.java  A.A.Shabarshin 21.02.2005

import java.io.*;
import java.util.*;

public class rwar implements WebPrint
{

 public void print(String str)
 {
  System.out.print(str); 
 }

 public void println(String str)
 {
  System.out.println(str); 
 }

 public static void main(String arg[])
 {
  WebPrint out = new rwar();
  WebParam param = new WebParam();
  WebSQL mysql = new WebSQL(out);
  WebDir dir = new WebDir("...");
  for(int i=0;i<arg.length;i++)
  {
   String[] para = arg[i].split("=");
   param.put(para[0],para[1]);
  }
  mysql.setBase("...");
  mysql.setUser("...");
  mysql.setPass("...");
  mysql.setHost("localhost");
  mysql.open();
  WebEngine web = new WebEngine();	
  web.init(out,param,mysql,dir);
  web.act("main.web");
  mysql.close();
 }
}
Из соображений безопасности я заменил некоторые деликатные данные на "..."

Как видно оба варианта запускают движок с шаблоном "main.web" внутри которого может быть описан как HTML-код, так и команды для движка - запуск дополнительных веб-модулей и т.д.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Веб-движок com.shabarshin.web

Post by Shaos »

Shaos wrote:Движок в исходниках сейчас весит всего 655 строк (9 файлов).
Пишу веб-модули для сайта rwar.net - уже готов общий дизайн страницы и логин (пока лишь на моем компьютере). Теперь общее кол-во классов - 14. Пока все классы валю в одну кучу - после того как обкатаю движок на боевом сайте, сделаю отдельный пакет com.shabarshin.web для самого движка, а веб-модули будут лежать отдельно.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote:
Shaos wrote: Интерфейсный класс WebModule.java:

Code: Select all

interface WebModule
{
 boolean init(WebPrint o, WebParam p, WebSQL s, WebDir d);
 boolean act(String s);
}
Основная идея - отображаемая страница состоит из веб-модулей, генерируемых объектами WebModule либо составляемых из шаблонов (через WebEngine, который тоже принимает интерфейс WebModule). Будучи запущенным, главный сервлет создает объект класса WebEngine и передает ему через аргументы ссылку на печатающий объект WebPrint, ссылку на объект WebParam содержащий POST/GET параметры, ссылку на объект WebSQL связанный с уже открытой базой данных и объект WebDir связанный с катологом файлов-шаблонов...
Что-то я подумал что было бы неразумно ограничивать кол-во передаваемых сущностей числом 4 - тогда старые приложения не будут работать с новой либой (например где может появится объект WebCookies или WebSession или WebMail) и наверное я упрячу все это в класс WebEnv, а интерфейс WebModule будет выглядеть так:

Code: Select all

interface WebModule
{
 boolean init(WebEnv w);
 boolean act(String s);
}
Из объекта WebEnv (или WebContext?) вышеозначенные ссылки можно будет получить путем вызова методов getPrint(), getParam(), getSQL() и getDir() класса WebEnv.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote: Из объекта WebEnv (или WebContext?) вышеозначенные ссылки можно будет получить путем вызова методов getPrint(), getParam(), getSQL() и getDir() класса WebEnv.
Завел класс WebContext и все адаптировал к нему - теперь имеем 15 классов ;)
Я тут за главного - если что шлите мыло на me собака shaos точка net