`
liujunsong
  • 浏览: 77571 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

WebDW的后台服务器程序发布(Java源代码)

阅读更多
今天决定把WebDW的后台相关Java代码共享出来.
其实蛮简单的一个东西,以后根据需要再详细完善吧.
/**
 * 
 */
package com.liu;

import javax.servlet.http.*;
import javax.servlet.*;
import java.sql.*;
import java.util.*;
import javax.naming.*;
import javax.sql.DataSource;
import java.util.Hashtable;
import java.io.*;

//import oracle.jdbc.pool.*;

/**
 * @author user
 *
 */
public class TableServlet extends HttpServlet {
	//transHash里面保存了所有事务,key是事务Id,字符型,value是一个TransSql对象
	public static Hashtable transHash = new Hashtable();

	private String s_ok = "OK";

	private String s_error = "ERROR";

	private String s_oper_query = "1"; //select sql命令 

	private String s_oper_exec = "2"; //update,delete sql命令

	private String s_oper_tablelist = "3"; //得到所有表列表的命令

	private String s_oper_columnlist = "4"; //得到某张表所有列的命令

	private String s_oper_beginTrans = "begintrans"; //开始一个事务的命令

	private String s_oper_addcommand = "addcommand"; //在事务中增加sql指令

	private String s_oper_commit = "commit"; //提交一个事务,收到这个命令,后台开始执行

	private String s_oper_rollback = "rollback"; //回滚一个事务,收到这个命令后,后台终止

	private String s_oper_getdwdefine = "getdwdefine"; //从后台检索数据窗口的定义格式
	
	private String s_oper_getvbfile = "getvbfile";	//从后台检索VB相关的原始文件内容
	
	private static Integer transId = new Integer(0);		//当前事务编号,以后递增
	
	private String ClassInfo="";
	public void init(ServletConfig config) throws ServletException {
		System.out.println("____________TableServlet init....");
	}

	/**
	 * 提供后台调用服务的Servlet程序
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws javax.servlet.ServletException, java.io.IOException {
		request.setCharacterEncoding("GBK"); //设置为GBK编码方式,处理中文

		int beginpos = 0; //默认从第一条开始
		int readnum = 100; //默认读取100条记录

		System.out.println("enter service TableServlet.Welcome.");
		String operType = request.getParameter("opertype");
		String command = request.getParameter("command");
		String param = request.getParameter("param");
		String strans = request.getParameter("transid");
		
		System.out.println("command="+command);
		if (request.getParameter("beginpos") != null
				&& request.getParameter("beginpos").trim().length() > 0) {
			beginpos = Integer.parseInt(request.getParameter("beginpos"));
		}

		if (request.getParameter("readnum") != null
				&& request.getParameter("readnum").trim().length() > 0) {
			readnum = Integer.parseInt(request.getParameter("readnum"));
		}

		int col = 0;

		if (operType == null)
			operType = "";
		if (command == null)
			command = "";
		if (param == null)
			param = "";

		response.setContentType("text/html;charset=GBK");
		ServletOutputStream out = response.getOutputStream();

		Connection conn = null;
		Statement stat = null;
		ResultSet rs = null;

		if (operType.equals("")) {
			out.print(s_ok);
			return;
		}
		
		try {
			conn = getConnection();
			conn.setAutoCommit(false);
			stat = conn.createStatement();
		} catch (Exception e) {
			e.printStackTrace();
			out.print("OK");
			return;
		}



		//如果命令参数是得到所有table的列表
		//那么构建一个SQL语句出来
		//目前仅支持Oracle数据库
		//其他数据库待以后进行明确的支持(等候升级)
		if (operType.equals(s_oper_tablelist)) {
			//Warning:这一语句仅对Oracle有效
			command = "select TNAME,TABTYPE from tab";
		}

		if (operType.equals(s_oper_columnlist)) {
			//Warning:这一语句仅对Oracle有效
			command = "Select CNAME from col where TNAME='" + command + "'";
		}
		//查询请求,当请求是s_oper_query和s_oper_tablelist时执行此流程
		if (operType.equals(s_oper_query) || operType.equals(s_oper_tablelist)
				|| operType.equals(s_oper_columnlist)) {
			try {
				doExecuteSelect(stat, rs, out, command, col, beginpos, readnum);
				conn.rollback();
			} catch (Exception e) {
				try{
					conn.rollback();
				}catch(Exception e1){
					e1.printStackTrace();
				}
				e.printStackTrace();
				out.println(e.toString());
			}
		}

		//执行请求
		if (operType.equals(s_oper_exec)) {
			try {
				doExecuteUpdate(command, stat, conn);

			} catch (Exception e) {
				try{
					conn.rollback();
				}catch(Exception e1){
					e1.printStackTrace();
				}
				e.printStackTrace();
				out.println(e.toString());
			}
		}

		//接收前台请求,准备启动一个事务(虚拟事务)
		if (operType.equals(s_oper_beginTrans)){
			try{
				doBeginTransaction(out);
			}catch(Exception e){
				e.printStackTrace();
			}
		}

		//事务中增加命令请求
		if (operType.equals(s_oper_addcommand)){
			doAddCommand(strans,command);
		}

		//事务提交请求,根据事务编号,把事务中的sql命令一一提交
		if (operType.equals(s_oper_commit)){
			try{
				doCommit(strans,conn,stat);
			}catch(Exception e){
				try{
					e.printStackTrace();
					Integer transId = new Integer(strans);
					TransSql sql = (TransSql)transHash.get(transId);
					if (sql == null ){
						//do nothing
					}else{
						sql.result ="commit failed";
						sql.commitDt = new java.util.Date().toString();
					}							
					conn.rollback();
					out.println(e.toString());
				}catch(Exception e1){
					e1.printStackTrace();
				}
			}
		}
		
		//事务取消请求,根据事务变化,把事务取消掉,这样就不用和后台交互了
		if(operType.equals(s_oper_rollback)){
			doRollback(strans);
		}
		
		//得到数据窗口定义的要求
		//根据给定的数据窗口的名字,检索后台的文件名
		//如果找到这个文件,把文件打开,返回给前台
		//如果出现错误,在后台打印错误信息
		if(operType.equals(s_oper_getdwdefine)){
			try{
				doGetDWFile(command,out);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		//得到VB源文件的要求
		//根据给定的VB源代码名称,检索文件名
		//找到这个文件,将文件传回给前台
		if (operType.equals(s_oper_getvbfile)){
			try{
				doGetVBFile(command,out);
			}catch(Exception e){
				e.printStackTrace();
			}			
		}
		//其他情况下,直接返回s_ok.
		out.print(s_ok);

		//TODO:关闭数据库连接
		try {
			if (rs != null)
				rs.close();
			if (stat != null)
				stat.close();
			if (conn != null)
				conn.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Database connection close failed.");
		}finally{
			try{
				conn.close();
			}catch(Exception e2){
				e2.printStackTrace();
			}
		}
	}



	/**
	 * 得到数据库连接,此处采用weblogic配置的连接池来处理
	 * 对获得连接的方式进行修改,直接建立一个连接
	 * @return
	 * @throws Exception
	 */
	private Connection getConnection() throws Exception {
		
//		Context initCtx = new InitialContext();
//		Context envCtx = (Context) initCtx.lookup("java:comp/env");
//		DataSource ds = (DataSource) envCtx.lookup("jdbc/tableedit");
//		Connection conn = ds.getConnection();
		String configfile="com/liu/database.properties";		
		
		String url="";
		String driver="";
		String userid="";
		String passwd="";
		//Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
		//Connection conn = DriverManager.getConnection(url,"dba","sql");
	  	ClassLoader loader = (new CEmpty()).getClass().getClassLoader();
	  	InputStream stream = loader.getResourceAsStream(configfile);
	  	Properties prop = new Properties();
	    prop.load(stream);
	    
	    url = prop.getProperty("url");
	    driver = prop.getProperty("driver");
	    userid = prop.getProperty("userid");
	    passwd = prop.getProperty("passwd");
	    
	    Class.forName(driver);
	    Connection conn = DriverManager.getConnection(url,userid,passwd);
		return conn;
	}
	/**
	 * 执行Select命令的方法,从主方法中独立出来。
	 * Warning:经过测试,通过这个接口实际上可以执行任何的SQL命令
	 * 因此必须对可以执行的SQL命令进行筛选,切不可直接提交执行,否则
	 * 后果将难以预测
	 * 最好的办法是专门为这个方法开一个ReadOnly权限的用户和连接来执行
	 * @param stat
	 * @param rs
	 * @param out
	 * @param command
	 * @param col
	 * @param beginpos
	 * @param readnum
	 * @throws Exception
	 */
	private void doExecuteSelect(Statement stat, ResultSet rs,
			ServletOutputStream out, String command, int col, int beginpos,
			int readnum) throws Exception {
		System.out.println("Sql = " + command);
		//TODO:对command命令进行解析,分析是否是一个Select命令
		//如果不是,则直接拒绝执行,否则很容易造成系统的崩溃和失败
		rs = stat.executeQuery(command);
		ResultSetMetaData meta = rs.getMetaData();
		String sline = "";
		for (col = 1; col <= meta.getColumnCount(); col++) {
			if (col < meta.getColumnCount()) {
				sline += meta.getColumnName(col) + "\t";
			} else {
				sline += meta.getColumnName(col);
			}
		}
		out.println(sline);
		System.out.println("colname=" + sline);
		while (beginpos > 0) {
			if (rs.next()) {
				beginpos--;
			} else {
				break;
			}
		}
		// beginpos现在是一个指示变量,如果上面的循环正常结束
		// beginpos应该等于0
		// 否则beginpos不为0
		while (rs.next() && beginpos == 0 && readnum > 0) {
			sline = "";
			for (col = 1; col <= meta.getColumnCount(); col++) {
				if (col < meta.getColumnCount()) {
					sline += rs.getString(col) + "\t";
				} else {
					sline += rs.getString(col);
				}
			}
			readnum--;
			out.println(sline);
		}
	}

	/**
	 * 执行Update类型的SQL命令的方法
	 *
	 */
	private void doExecuteUpdate(String command, Statement stat, Connection conn)
			throws Exception {
		System.out.println("Sql = " + command);
		//TODO:对传入的SQL命令,一定要进行分析判断,避免破坏性的SQL命令插入
		if (command == null && command.trim().length() < 1) {
			// do nothing
		} else {
			String[] sqls = command.split("----------");
			int i;
			for (i = 0; i < sqls.length; i++) {
				System.out.println("sqls[i]:" + sqls[i]);
				if (sqls[i] == null || sqls[i].trim().length() == 0) {
					break;
				} else {
					stat.executeUpdate(sqls[i]);
				}
			}
			conn.commit();
		}
	}
	/**
	 * 在服务器上启动一个虚拟事务的方法
	 * @param out
	 */
	private void doBeginTransaction(ServletOutputStream out) throws Exception {
		System.out.println("enter begintrans");
		//同步化代码,避免事务编号重复
		synchronized(transId){
			int id = transId.intValue();
			id ++;
			if (id >= 1000) id =0;
			transId = new Integer(id);	//得到事务编号
		}
		TransSql sql = (TransSql)transHash.get(transId);
		if (sql!=null){
			transHash.remove(transId);	//如果事务编号已经使用,那么删除之
		}
		 sql = new TransSql();
		 sql.transId = transId.intValue();
		 sql.beginDT =new java.util.Date().toString();
		 transHash.put(transId, sql);	//将事务对象放入Hash中
		 System.out.println(transId.toString());
		 out.println(transId.toString());	//返回事务对象的编号给客户端		
	}
	
	/**
	 * 在事务中增加命令的方法,一次增加一条命令
	 * @param command
	 * @param transId
	 * @throws Exception
	 */
	private void doAddCommand(String stransId,String command){
		Integer transId = new Integer(stransId);
		TransSql sql = (TransSql)transHash.get(transId);
		if (sql == null || command == null || command.trim().equals("")){
			//do nothing
		}else{
			if (sql.transSQL.equals("") ){
				sql.transSQL = command;
			}else{
				sql.transSQL = sql.transSQL + "\r\n" +command;
			}
		}
	}
	/**
	 * 提交指定的事务对象
	 * @param stransId
	 */
	private void doCommit(String stransId,Connection conn,Statement stat) throws Exception{
		Integer transId = new Integer(stransId);
		TransSql sql = (TransSql)transHash.get(transId);
		if (sql == null || sql.result.trim().length()>0  ){
			//do nothing
		}else{
			sql.result ="commit begin";
			String[] sqls = sql.transSQL.split("\r\n");
			int i;
			for (i = 0; i < sqls.length; i++) {
				System.out.println("sqls[i]:" + sqls[i]);
				if (sqls[i] == null || sqls[i].trim().length() == 0) {
					break;
				} else {
					stat.executeUpdate(sqls[i]);
				}
			}
			conn.commit();	
			sql.commitDt = new java.util.Date().toString();
			sql.result = "commit finish";
		}		
	}
	
	/**
	 * 废弃指定的事务对象
	 * @param stransId
	 */
	private void doRollback(String stransId){
		Integer transId = new Integer(stransId);
		TransSql sql = (TransSql)transHash.get(transId);
		if (sql == null || sql.result.trim().length()>0  ){
			//do nothing
		}else{
			sql.result ="rollback";
			sql.commitDt = new java.util.Date().toString();
		}		
	}	
	/**
	 * 从后台服务器上检索DW的文件内容,传递到前台去
	 * @param command	command中代表数据窗口的文件名,如果无后缀,代表.srd文件
	 * @param out		输出流
	 */
	private void doGetDWFile(String command,ServletOutputStream out)throws Exception{
		String filepath="C://webdwfile//dwfile//";
		String filename="";
		if (command.indexOf(".") > 0){
			filename = filepath + command;
		}else{
			filename = filepath + command+".srd" ;
		}
		System.out.println("Want file:"+filename);			
		File dwfile = new File(filename);
		if (dwfile.exists()){//如果文件存在,才操作,否则不操作
			FileReader  fstream = new FileReader(filename);
			BufferedReader  in = new BufferedReader(fstream);
			String record = "";
            while ((record = in.readLine()) !=null) {
            	out.println (record);	//文件输出到输出流去
            }
            in.close(); //关闭文件输入流
		}		
	}

	/**
	 * 从后台服务器上检索VB项目的相关文件内容,传递到前台去
	 * 只读取C://VBSource//目录下文件
	 * 目前只支持这一个目录
	 * @param command	command中代表数据窗口的文件名,如果无后缀,代表.srd文件
	 * @param out		输出流
	 */
	private void doGetVBFile(String command,ServletOutputStream out)throws Exception{
		String filepath="C://webdwfile//VBfile//";
		String filename="";
		filename = filepath + command;

		System.out.println("Want VB file:"+filename);			
		File vbfile = new File(filename);
		if (vbfile.exists()){//如果文件存在,才操作,否则不操作
			FileReader  fstream = new FileReader(filename);
			BufferedReader  in = new BufferedReader(fstream);
			String record = "";
            while ((record = in.readLine()) !=null) {
            	out.println (record);	//文件输出到输出流去
            }
            in.close(); //关闭文件输入流
		}		
	}

}


上面的代码是一个Servlet,在web.xml里面映射成/Table这样一个名字.
另外有个类TransSql,这个类用来存储事务的结构.
package com.liu;

public class TransSql {

	public int transId = 0; // 事务的编号,0代表无事务

	public String transSQL = ""; // 事务所要执行的多个SQL命令,相互之间用:\r\n进行分割

	public String beginDT = ""; // 事务开始时间

	public String commitDt = ""; // 事务提交时间

	public String result = ""; // 事务执行结果

}


另外有一个database.properties文件,配置数据库的连接信息,Servlet里面调用
#driver for EA Demo V5 odbc
#url		=jdbc:odbc:EAS Demo DB V3
#driver	=sun.jdbc.odbc.JdbcOdbcDriver
#userid	=dba
#passwd	=sql

#driver for Oracle scott user
url		=jdbc:oracle:thin:@localhost:1521:finance
driver	=oracle.jdbc.OracleDriver
userid	=scott
passwd	=tiger


0
0
分享到:
评论

相关推荐

    WebDW产品介绍202001211

    WebDW服务器是产品核心,使用JAVA和SpringBoot框架开发,提供API供前端调用,实现与数据存储层的交互。服务器加载不同的数据窗口对象以对应不同的业务逻辑功能。 客户端产品多样化,包括8种C/S开发工具(如Power...

    WebDW0.2版本隆重发布,敬请下载试用

    对于压缩包中的"webdw0.2发布版本",这通常包含了安装程序或可执行文件,以及可能的文档、示例代码和许可证文件。安装程序将引导用户完成软件的安装过程,文档可能包含详细的使用指南和技术参考,示例代码能帮助用户...

    WebDW2代码说明1

    首先,VB客户端通过发送HTTP请求到后台服务器来启动交互。这个请求的目标地址是`http://localhost/webdw/retrieve`,并带有参数`dwname`,用于指定要获取的数据窗口名称。例如,如果请求`dwname=d_products`,后台则...

    webdw源代码

    NULL 博文链接:https://liujunsong.iteye.com/blog/1338944

    WebDW-API定义202001311

    【WebDW-API定义202001311】文档详细阐述了WebDW后台服务器提供的API接口,这些接口主要用于前端与后台数据交互,确保不同语言的前端工具能够有效地访问和调用数据窗口对象。以下是关于这些API的详细说明: 1. **...

    webdw on vb version

    “源码”标签表明这里可能涉及到WebDW的源代码,意味着读者或用户有机会查看、学习和修改软件的内部工作原理。这对于开发者来说是一个宝贵的资源,他们可以深入理解软件的设计,并对其进行定制以满足特定需求。 ...

    webdw.rar_HTML 网页_html_webdw_网页_网页制作html

    它构成了互联网的基础,让开发者能够构建结构化的文档,并通过超链接将信息组织在一起。...对于那些希望学习网页制作的人,这是一个很好的起点,通过分析这个小网页的源代码,可以深入理解网页开发的基本原理和技术。

    WebDW.zip_PowerBuilder_powerbuilder web_zip

    然后,通过发布到 Web 服务器,用户可以在任何支持浏览器的设备上访问这些应用程序。 此外,Web DataWindow 也支持多种 Web 服务器和应用程序服务器,例如 IIS、Apache、Tomcat 等,并且可以与各种 Web 开发框架如 ...

    WDW 2.0汉化版

    汉化过程中修正了几处错误,几个连接图形文件名错误,更重要的是,原来的程序没有区分cgi和nocgi目录,导致在许多系统上安装失败(大多系统的cgi目录下是不允许调用html和图形文件的),这几乎是许多CGI程序的通病

    WebDW2.0的前端Web项目,介绍WebDW项目的相关资料,演示Demo功能。前端项目(毕设&课设&实训&大作业&竞赛&项目

    可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关...

    提取Powerbuilder 12里自带的Code Samples,共12个

    总共12个Projects 包含: Advanced GUI Benchmark dotNET CAS DWGradientTransparency DWRichTextEditStyle Example App FeedReader Mobilink Treeview DataWindow and DatePicker Web Reports ...WebDW

Global site tag (gtag.js) - Google Analytics