客户端与服务器同步数据

需求: 1、服务器端程序是J2EE架构,运行在J2EE服务器上。数据库是Oracle. 2、客户端是Java应用程序,数据库使用的是SQLite; 3、客户端从服务器同步数据。 4、客户端与服务器上数据库中表结构基本相同。 5、客户端发出同步请求时,同步。 总体设计 流程: 1、客户发出同步请求,包含同步哪些数据的条件; 2、服务器响应请求:根据客户端发出的条件准备SQL语句; 3、 创建SimpleOracleJDBCReader实例,该实例可以根据一条SQL查询语句从数据库中获得对应的数据,以中间类型的数据结构存在;创建 SimpleXMLWriter实例,该实例可将中间类型数据写出到XML文档中。创建一个搬运器,将数据从Oracle数据库搬运到XML文件中。 4、服务器返回给客户端一个数据流.该数据流从第3步中生成的xml文件中取数据,发送到客户端 5、客户端接收从服务器发来的xml数据流,生成xml文件,保存在本地 6、在客户端创建SimpleXMLReader从下载的xml读出数据,以中间类型的形式存在;创建SimpleSQLiteJDBCWriter,将中间类型的数据写入到SQLite中;创建一个搬运器,将数据从XML搬运到SQLite数据库文件中。 服务器端程序 private IBaseDAO copyDAO; private String cachePath = "d:/test/"; /** * 组装更新数据 * * @date 2010-11-2 * @param os * @return */ public String getUpdateData(String xmlName, OutputStream os){ if(xmlName != null){ try { getXML(xmlName , os); } catch (Exception e) { e.printStackTrace(); } return null; } else { List<String> sqlList = getSql(); if(sqlList.size()==0){ return null; } String result = null; try { result = createXMLS(sqlList); os.write(result.getBytes()); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally{ if(os != null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } } /** * 生成多个xml * * @date 2010-11-2 * @param sqlList * @return * @throws Exception */ private String createXMLS(List<String> sqlList) throws Exception{ StringBuffer sb = new StringBuffer(); String temp = null; for(String sql : sqlList){ temp = createXML(sql); if(temp != null){ sb.append(temp).append(","); } } return sb.toString(); } /** * 生成xml * * @date 2010-11-2 * @param sql * @return * @throws Exception */ private String createXML(String sql) throws Exception{ Reader reader = new SimpleJdbcReader(sql, copyDAO.getConnection()); String objectName = reader.getHeader().getObjectName(); String name = "data_"+objectName+"_"+System.currentTimeMillis()+".xml"; File xmlfile = new File(cachePath + name); if(!xmlfile.exists()){ xmlfile.createNewFile(); } Writer xmlWriter = new SimpleXmlWriter(reader.getHeader(), xmlfile); new SimpleTractor(reader, xmlWriter).start(); return objectName+":"+name; } /** * 下载一个xml文档 * * @date 2010-11-2 * @param xmlName * @param os * @return * @throws Exception */ public InputStream getXML(String xmlName, OutputStream os) throws Exception{ File file = new File(cachePath + xmlName); FileInputStream is = null; try { if(file.exists()){ is = new FileInputStream(file); byte[] buffer = new byte[8096]; int length = -1; while((length = is.read(buffer)) != -1){ os.write(buffer, 0, length); } } else { return null; } } catch (RuntimeException e) { e.printStackTrace(); } finally{ if(is != null){ try { is.close(); } catch (RuntimeException e) { e.printStackTrace(); } } if(os != null){ try { os.close(); } catch (RuntimeException e) { e.printStackTrace(); } } file.delete(); } return null; } /** * 组装sql * * @date 2010-11-2 * @return */ private List<String> getSql(){ List<String> sqlList = new ArrayList<String>(); sqlList.add("select * from users"); return sqlList; } 客户端程序 /** * 更新数据 * * @date 2010-11-2 * @param types * @param verison */ private void updateData(String[] types, String verison){ try { // 请求服务器准备xml格式的更新数据,每个表一个xml文档,返回xmlName格式是 // tableName1:xml文件名1,tableName2:xml文件名2,.... String[] xmlNames = getXMLNames(types, verison); if (xmlNames != null && xmlNames.length > 0) { String urlString = serverUrl + "?copyBean.xmlName="; File xmlFile = null; for (String xml : xmlNames) { if (xml == null) { continue; } // xml格式是 tableName1:xml文件名1 String[] temp = xml.split(":"); if (temp == null || temp.length < 2) { continue; } // 下载xml文件 xmlFile = getFileResponse(urlString + temp[1]); // 插入新数据 Reader reader = new SimpleXmlReader(xmlFile); Writer writer = new SimpleSQLiteJdbcWriter(copyDAO.getConnection(), reader.getHeader()); new SimpleTractor(reader, writer).start(); // 删除临时文件 xmlFile.delete(); } //更新版本号 updateVersion(verison); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * 请求服务器准备xml格式的更新数据,每个表一个xml文档,返回xmlName格式是 * * @date 2010-11-2 * @throws IOException */ private String[] getXMLNames(String[] types, String version) throws IOException { String typeStr = ""; for (String t : types) { typeStr += "&copyBean.allInfoTypes=" + t; } String orgId = SysContext.getCurrentUserFromSession().getGroup() .getId(); String urlString = serverUrl + "?copyBean.fromGroupId=" + orgId + typeStr; if (version != null) { urlString += "&copyBean.verison=" + version; } String result = getStringResponse(urlString); if (result != null) { String[] fileNames = result.split(","); return fileNames; } else { return null; } } /** * 获得字符串请求 * * @date 2010-11-2 * @param urlString * @return * @throws IOException */ private String getStringResponse(String urlString) throws IOException { InputStream is = sendHttpRequest(urlString); StringBuffer sb = new StringBuffer(); try { byte[] buffer = new byte[8096]; int length = -1; while ((length = is.read(buffer)) != -1) { sb.append(new String(buffer, 0, length)); } } catch (RuntimeException e) { e.printStackTrace(); } finally { try { is.close(); } catch (RuntimeException e) { } } return sb.toString(); } /** * 获取文件 * * @date 2010-11-2 * @param urlString * @return * @throws IOException */ private File getFileResponse(String urlString) throws IOException { InputStream is = sendHttpRequest(urlString); File xmlfile = new File("data_client_" + System.currentTimeMillis() + ".xml"); OutputStream os = null; if (!xmlfile.exists()) { xmlfile.createNewFile(); } os = new FileOutputStream(xmlfile); try { byte[] buffer = new byte[8096]; int length = -1; while ((length = is.read(buffer)) != -1) { os.write(buffer, 0, length); } } catch (RuntimeException e) { e.printStackTrace(); } finally { try { os.close(); } catch (RuntimeException e) { } try { is.close(); } catch (RuntimeException e) { } } return xmlfile; } /** * 发送请求 * * @date 2010-11-2 * @param urlString * @return * @throws IOException */ private InputStream sendHttpRequest(String urlString) throws IOException { HttpURLConnection httpConnection = null; URL url; int code = -1; for (int i = RETRY; i > 0; i--) { try { url = new URL(urlString.toString()); httpConnection = (HttpURLConnection) url.openConnection(); httpConnection.setRequestMethod("GET"); httpConnection.setDoOutput(true); httpConnection.setDoInput(true); httpConnection.setConnectTimeout(TIMEOUT); httpConnection.setReadTimeout(TIMEOUT); code = httpConnection.getResponseCode(); if (code != HttpURLConnection.HTTP_OK) { continue; } break; } catch (SocketTimeoutException e) { if (i == 1) { throw new RuntimeException(e); } else { continue; } } catch (UnknownHostException e) { if (i == 1) { throw new RuntimeException(e.getMessage()); } else { continue; } } catch (Exception e) { throw new RuntimeException(e); } } if (code == HttpURLConnection.HTTP_OK) { return httpConnection.getInputStream(); } else { return null; } }