[项目]WebService涉及到的部分核心代码

时间:2021-08-29 08:39:28

 前言:

  博客园似乎不太喜欢设计模式的东西,一连写了几篇设计模式的东西,都没什么人气,也许是写的水平有些不够,另外设计模式属于内功,怎们都得修炼一下,否则,设计混乱,不成体系,对于大型项目来说,就会显的特别的小儿科,因此,无论如何,都得继续学习与修炼。今天就写点之前项目涉及到的Webservice处的一些关键设计与部分源码,这里只是描述关键部分,因为涉及到之前公司的一些东西,特别是对于数据库操作部分没有展示,另外对于部分内容,也进行了重构与简化,希望各位了解。

业务场景:

  先描述一下业务场景,我们系统运行稳健,由于某些原因,有部分业务功能需要切换到另外的系统去处理,但是,需要保证双方系统数据在业务层面的实时更新[因此仅数据库层面的同步更新是不可取,以后,会开源自己开发的数据库层面的同步工具,有需要可以留言,以便尽快整理],所以主要是利用webservice技术,由于双方系统的固有差距,相关webservice的互联调试费了些功夫,这里不做太多介绍,双方通信的基础是互相传递Xml数据,这就涉及到了xml的解析,xml的构造等。另外,由于业务的多样化,这里用到了类似简单工厂的设计方法,现在看来,当时只是为了尽快的解决的问题,对于设计的深层考虑还是缺乏的,有很多地方都是不尽合理的,还需要继续深究设计模式。还有一部分就是数据持久化的过程,这一块对于不同的业务需求做了封装,具体这里就不做介绍。其他如日志记录等也就不赘述了。用到的开源类库有Jdom,axis,cxf等

核心实现代码:

webservice互联部分:

服务器端ServiceRun.java:

package me.service;
public class ServiceRun {
public static void main(String[] args) { System.out.println("Starting Server");
ZC zc = new ZCImpl();
String address = "http://localhost:8090/ZC";
javax.xml.ws.Endpoint.publish(address, zc);
System.out.println("服务启动完成。。。。");
}
}

客户端访问:

package me.service;

import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode; import org.apache.axis.client.Call;
import org.apache.axis.client.Service; public class ClientRun { public static void main(String[] args) throws Exception { String url = "http://localhost:8090/ZC";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new URL(url));
String targetNamespace = "http://service.me/";
QName qName = new QName(targetNamespace,"getZcmethod");
call.setOperationName(qName);
call.addParameter("text", null,ParameterMode.IN);
String message = (String) call.invoke( new Object[]{"test"});
System.out.println(message);
}
}

辅助实现类:

package me.service;

import javax.jws.WebService;

@WebService(endpointInterface="me.service.ZC",name="ZC")
public class ZCImpl implements ZC{ @Override
public String getZcmethod(String text) throws Exception {
System.out.println("parameter is =======>>>> " + text);
return "parameter is =======>>>> " + text;
} }

这一部分代码,较为简单而且属于固定模式的。不多介绍。

==================================华丽分割线=======================================

xml服务类,包括解析与构造,这里使用了单例模式(发现之前使用的很不规范,现在仍然使用了饿汉模式,又重新写了双重锁机制)。另外使用了反射机制机制,主要目的是将解析得到的结果转化为类的结果。还是看代码吧。

/**
* <p>File Name:xmlService.java</p>
* <p>Create Time:2014-9-22</p>
* <p>Create Author:ljl</p>
* <p>Description:</p>
* <p>Version:1.0</p>
* <p>Modify:</p>
*/
package com.service.xmlService; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder; import com.service.business.bean.ZC_GDZC;
import com.service.serviceHelper.StrUtil;
import com.service.xmlService.node.CWROW;
import com.service.xmlService.node.CWROWDATA;
import com.service.xmlService.node.DATAPACKAGE; /**
* <p>Class Name:xmlService.java</p>
* <p>Create Time:2014-9-22</p>
* <p>Create Author:ljl</p>
* <p>Description:</p>
* <p>Version:1.0</p>
* <p>Modify:</p>
*/
public class XmlService {
/** 不重复随机号*/
private static String PACKAGEID = "";
/** 调用监控服务*/
private static String PACKAGETYPE = "";
private static List sendRdList = new ArrayList();
private static String sendStrXml = "";
private static Object Bean;
private static XmlService instance=null;
/**
* <p>Method Name:</p>
* <p>Create Time:2014-9-22</p>
* <p>Create Author:ljl</p>
* <p>Description:</p>
* <p>Version:1.0</p>
* <p>Modify:</p>
*/
private XmlService(){ }
public static XmlService getInstance(){
if(null==instance){
synchronized (XmlService.class) {
if(null==instance){
instance=new XmlService();
}
}
}
return instance;
}
public void setBean(Object bean) {
Bean = bean;
}
public Object getBean() {
return Bean;
} /**
*
* <p>Method Name:</p>
* <p>Create Time:2014-9-24</p>
* <p>Create Author:ljl</p>
* <p>Description:make the bean to xml</p>
* <p>Version:1.0</p>
* <p>Modify:</p>
*/
public String beansToStrXml(Object []beans) throws Exception{
sendRdList = new ArrayList();
sendStrXml = "";
for(int i=0;i<beans.length;i++){
sendRdList.add(beans[i]);
}
DATAPACKAGE dpSend = new DATAPACKAGE();
CWROWDATA cwSend = new CWROWDATA();
CWROW row = new CWROW();
cwSend.setPACKAGEID(PACKAGEID);
cwSend.setPACKAGETYPE(PACKAGETYPE);
row.setROW(sendRdList);
cwSend.setROWDATA(row);
dpSend.setCW(cwSend);
Document document = XMLDocumentUtil.createXMLDocument(dpSend);
sendStrXml = XMLDocumentUtil.getStrFromDoc(document);
return sendStrXml;
}
/**
*
* <p>Method Name:</p>
* <p>Create Time:2014-9-24</p>
* <p>Create Author:ljl</p>
* <p>Description:get the data node list</p>
* <p>Version:1.0</p>
* <p>Modify:</p>
*/
public ArrayList parseXML(String recStrXml){
// System.out.println(recStrXml);
LinkedHashMap map=new LinkedHashMap();
ArrayList retArr=new ArrayList();
if(StrUtil.isEmpty(recStrXml)){
return null;
}else{
SAXBuilder builder = new SAXBuilder();
Document doc=null;
try {
doc = builder.build(new ByteArrayInputStream(recStrXml.getBytes("GB2312")));
Element cw = null;
if (doc.getRootElement()!=null&&doc.getRootElement().getChild(IXmlMemberUtil.CWNAME) != null){
cw = doc.getRootElement().getChild(IXmlMemberUtil.CWNAME);
PACKAGEID = cw.getChildText(IXmlMemberUtil.PACKANGEIDNAME); //
PACKAGETYPE = cw.getChildText(IXmlMemberUtil.PACKAGETYPENAME); //
} if (cw.getChild(IXmlMemberUtil.ROWDATA)!=null&&cw.getChild(IXmlMemberUtil.ROWDATA).getChildren(IXmlMemberUtil.ROW)!= null){
List rds = cw.getChild(IXmlMemberUtil.ROWDATA).getChildren(IXmlMemberUtil.ROW);
for(int i=0;i<rds.size();i++){
Element row=((Element)rds.get(i));
List rows=row.getChildren();
for(int j=0;j<rows.size();j++){
Element rs=((Element)rows.get(j));
map.put(rs.getName(), rs.getValue());
}
retArr.add(map);
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return retArr;
}
/**
*
* <p>Method Name:</p>
* <p>Create Time:2014-9-26</p>
* <p>Create Author:ljl</p>
* <p>Description:change the bean to linkedhashmap.</p>
* <p>Version:1.0</p>
* <p>Modify:</p>
*/
public LinkedHashMap beanToLinkedHashMap(Object bean){
java.lang.reflect.Field []f= bean.getClass().getFields();
LinkedHashMap lmap=new LinkedHashMap();
for(int i=0;i<f.length;i++){
try {
lmap.put(f[i].getName(), f[i].get(bean));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return lmap;
}
/**
*
* <p>Method Name:</p>
* <p>Create Time:2014-9-26</p>
* <p>Create Author:ljl</p>
* <p>Description:chage the linkedhashmap to the bean.</p>
* <p>Version:1.0</p>
* <p>Modify:</p>
*/
public void LinkedHashMapToBean(LinkedHashMap lmap){
if(lmap==null){
return;
}
Class bClass=Bean.getClass();
Iterator it=lmap.entrySet().iterator();
Method []method=bClass.getMethods();
while(it.hasNext()){
Map.Entry entry=(Map.Entry)it.next();
String kName=entry.getKey().toString().toUpperCase();
for(int i=0;i<method.length;i++){
Method m=method[i];
String mName=m.getName().toUpperCase();
if((mName.indexOf(kName)!=-1)&&(mName.indexOf(IXmlMemberUtil.SET)!=-1)){
try {
Class [] o= new Class[1];
o[0]=String.class;
Method mSet=bClass.getDeclaredMethod(m.getName(), o);
try {
String [] s=new String[1];
s[0]=entry.getValue().toString();
mSet.invoke(Bean,s);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
}
}
/**
*
* <p>Create Auther:ljl</p>
* <p>Create Time:2014-10-29</p>
* <p>Description:</p>
* <p>Version:1.0</p>
* <p>Modify Time:</p>
* <p>Modify Author:</p>
* <p>Modify Content:</p>
*/
public Object invokeMehtod(Object bean,String methodName,Object[]args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
Class bClass=bean.getClass();
Class []argClass=new Class[args.length];
for(int i=0;i<args.length;i++){
argClass[i] = args.getClass();
}
Method method=bClass.getDeclaredMethod(methodName, argClass);
return method.invoke(bean, args);
}
public static void main(String[] args) {
XmlService c =XmlService.getInstance();
StringBuffer sb=new StringBuffer();
sb.append("<?xml version='1.0' encoding='GB2312'?>"
+"<DATAPACKAGE>"
+"<CW>"
+"<PACKAGEID>001</PACKAGEID>"
+"<PACKAGETYPE>GDZC</PACKAGETYPE>"
+"<ROWDATA>"
+"<ROW>"
+"<JLHH>123122312</JLHH>"
+"<ZCMC>你好</ZCMC>"
+"</ROW>"
+"<ROW>"
+"<JLHH>1213545</JLHH>"
+"<ZCMC>你好adds</ZCMC>"
+"</ROW>"
+"</ROWDATA>"
+"</CW>"
+"</DATAPACKAGE>");
ArrayList arr=new ArrayList();
arr=c.parseXML(sb.toString());
c.setBean(new ZC_GDZC());
ZC_GDZC z[] =new ZC_GDZC[arr.size()];
for(int i=0;i<arr.size();i++){
LinkedHashMap lmap= (LinkedHashMap)arr.get(i);
Iterator it=lmap.entrySet().iterator();
while(it.hasNext()){
Map.Entry entry=(Map.Entry)it.next();
String kName=entry.getKey().toString().toUpperCase();
String kValue=entry.getValue().toString().toUpperCase();
System.out.println(kName+":"+kValue);
}
c.LinkedHashMapToBean(lmap);
System.out.println("+++"+((ZC_GDZC)c.getBean()).getJLHH());
System.out.println("+++"+((ZC_GDZC)c.getBean()).getZCMC());
z[i]=(ZC_GDZC)c.getBean();
System.out.println("==="+z[i].getJLHH());
System.out.println("==="+z[i].getZCMC());
}
try {
System.out.println(c.beansToStrXml(z));
} catch (Exception e) {
e.printStackTrace();
}
//
//
// try {
// PACKAGEID="001";
// PACKAGETYPE="MESSAGE";
// try {
// MESSAGE m=new MESSAGE();
//// Class bClass=Class.forName(getBean().getClass().getName());
// try {
//// m = (MESSAGE)bClass.newInstance();
// m.setMsgResult("1");
// m.setMsgType("GDZC");
// Bean=m;
// System.out.println("msg:"+m.getMsgType());
// System.out.println(c.beanToLinkedHashMap(m));
// System.out.println(c.beanToStrXml(m));
//
// ArrayList arr=c.parseXML(c.beanToStrXml(m));
// for(int i=0;i<arr.size();i++){
// LinkedHashMap lmap= (LinkedHashMap)arr.get(i);
// c.LinkedHashMapToBean(lmap);
// }
// } catch (InstantiationException e) {
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// }
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
}
}

另外将xml的基础类,写在下边:

package com.service.xmlService;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set; import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter; public class XMLDocumentUtil { /**
* 利用对象生产相应的xml数据信息
* @param obj 数据源
* @return document xml文档对象
* @throws Exception
*/
public static Document createXMLDocument(Object obj) throws Exception {
Element headerNode = getElementFromName(obj.getClass().getName());
Document document = new Document(headerNode);
int flag = estimateNestingNode(obj);
if (0 == flag) {
headerNode.addContent("" + obj);
} else {
distributeCreateNodeTask(null, obj, headerNode, flag);
}
return document;
} /**
* 根据属性类型选择相应的处理方法
* @param name 父节点的名称
* @param obj 数据源
* @param element 父节点
* @flag 相应方法的选择依据
* throws Exception
*
*/
private static void distributeCreateNodeTask(String name, Object obj,
Element element, int flag) throws Exception {
if (flag == 1) {
createNodeProperties(name, obj, element);
} else if (flag == 2) {
createSingleNode(name, obj, element);
} else if (flag == 3) {
createListNode(name, obj, element);
} else if (flag == 4) {
createMapNode(name, obj, element);
} else if (flag == 5) {
createSetNode(name, obj, element);
}
} /**
* 生成对象数组结点
* @param name 父节点的名称
* @param obj 数据源
* @param element 父节点
* @flag 相应方法的选择依据
* throws Exception
*/
public static void createNodeProperties(String name, Object obj,
Element element) throws Exception {
Element nodes;
if (null == name || name.equals("") || name.trim().equals("")) {
nodes = element;
} else {
nodes = new Element(name);
element.addContent(nodes);
}
Object[] objects = (Object[]) obj;
for (int i = 0; i < objects.length; i++) {
Element node = getElementFromName(objects[i].getClass().getName());
nodes.addContent(node);
createSingleElement(objects[i], node);
}
}
/**
* @Title createSingleNode
* @Description TODO
* @param name
* @param obj
* @param element
* @throws Exception
* @Return void
* @Throws
* @user Administrator
* @Date 2016年1月20日
*/
public static void createSingleNode(String name, Object obj, Element element)
throws Exception {
Element node;
if (null == name || name.equals("") || name.trim().equals("")) {
node = element;
} else {
node = new Element(name);
element.addContent(node);
}
createSingleElement(obj, node);
} /**
* 将类属性所有数据依次写入相应xml的类结点中
*
* @param obj 数据源
* @param element 类结点
* throws Exception
*/
public static void createSingleElement(Object obj, Element element)
throws Exception {
Field[] fields = obj.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
int flag = estimateNestingNode(fields[i], obj);
String name = fields[i].getName();
if (0 == flag) {
setNodeProperties(fields[i], obj, element);
} else {
distributeCreateNodeTask(name, fields[i].get(obj), element,flag);
}
}
} /**
* 生成List类型的结点
*
* @param name 结点名称
* @param obj 数据源
* @param element 父结点
* throws Exception
*/
public static void createListNode(String name, Object obj, Element element)
throws Exception {
Element node;
// if (null != name && !name.trim().equals("")) {
// node = new Element(name);
// //node.setAttribute("name", name);
// element.addContent(node);
// } else {
node = element;
// }
List list = (List) obj;
for(int i=0;i<list.size();i++){
Object object = (Object)list.get(i);
createListElement(object, node,name);
} } /**
* 将List类型数据写入相应xml的List结点
*
* @param name 结点名称
* @param obj 数据源
* @param element 类结点
* throws Exception
*/
public static void createListElement(Object obj, Element element,String name)
throws Exception {
int flag = estimateNestingNode(obj);
//String name = "value";
if (0 == flag) {
Element node = new Element(name);
node.addContent("" + obj);
element.addContent(node);
} else {
distributeCreateNodeTask(name, obj, element, flag);
}
} /**
* 将Map类型数据写入相应xml的Map结点
*
* @param name 结点名称
* @param obj 数据源
* @param element 类结点
* throws Exception
*/
public static void createMapNode(String name, Object obj, Element element)
throws Exception {
Element node;
if (null != name && !name.trim().equals("")) {
node = new Element("Map");
node.setAttribute("name", name);
element.addContent(node);
} else {
node = element;
}
Map map = (Map) obj;
for (Iterator key= map.keySet().iterator();key.hasNext();) {
if (null == key) {
continue;
}
Object object = (Object)key.next();
Element ele = new Element("entry");
ele.setAttribute("key", "" + object);
node.addContent(ele);
createMapElement(map.get(object), ele);
}
} /**
* 将Map类型数据写入相应xml的Map结点
* @param name 结点名称
* @param obj 数据源
* @param element 类结点
* throws Exception
*/
public static void createMapElement(Object obj, Element node)
throws Exception {
int flag = estimateNestingNode(obj);
String name = "value";
if (0 == flag) {
node.setAttribute(name, "" + obj);
} else {
distributeCreateNodeTask(name, obj, node, flag);
}
} /**
* 将Set类型数据写入相应xml的Set结点
* @param name 结点名称
* @param obj 数据源
* @param element 类结点
* throws Exception
*/
public static void createSetNode(String name, Object obj, Element element)
throws Exception {
Element node;
if (null != name && !name.trim().equals("")) {
node = new Element("Set");
node.setAttribute("name", name);
element.addContent(node);
} else {
node = element;
}
Set set = (Set) obj;
for (Iterator key= set.iterator(); key.hasNext();) {
Object object = (Object)key.next();
createListElement(object, node,name);// set、list结构一样
}
} /**
* 将单个基础java类型(flag==0)的属性数据写入相应xml的类节点的子结点中
* @param field 属性信息
* @param obj 数据源
* @param element 类结点
* throws Exception
*/ private static void setNodeProperties(Field field, Object obj,
Element element) throws Exception {
String name = field.getName();
boolean accFlag = field.isAccessible();
field.setAccessible(true);
Object value = field.get(obj);
field.setAccessible(accFlag);
Element node;
if (null == name || name.equals("") || name.trim().equals("")) {
node = element;
} else {
node = new Element(name);
element.addContent(node);
}
node.setText(String.valueOf(value));
} /**
* @Title estimateNestingNode
* @Description
* 0--基本数据类型、String
* 1--数组
* 2--自定义类
* 3--List
* 4--Map
* 5--Set
* @param obj
* @return
* @Return int
* @Throws
* @user Administrator
* @Date 2016年1月20日
*/
private static int estimateNestingNode(Object obj) {
String str = "";
if (obj instanceof List) {
return 3;// 表示该属性是list
}
if (obj instanceof Map) {
return 4;// 表示该属性是Map
}
if (obj instanceof Set) {
return 5;// 表示该属性是Set
}
if (null != obj) {
str = obj.getClass().getName();
}
if (str.indexOf("[") != -1) {
return 1;
}
if (str.indexOf("java") != -1) {
return 0;
}
return 2;
} private static int estimateNestingNode(Field field, Object obj)
throws Exception {
String str = "";
Object value = null;
value = field.get(obj);
if (value instanceof List) {
return 3;// 表示该属性是list
}
if (value instanceof Map) {
return 4;// 表示该属性是list
}
if (value instanceof Set) {
return 5;// 表示该属性是list
}
if (null != value) {
str = value.getClass().getName();
if (str.indexOf("[") != -1) {
return 1;
}
if (str.indexOf("java") != -1) {
return 0;
}
}
return 2;
} /**
* @Title getElementFromName
* @Description TODO
* @param name
* @return
* @Return Element
* @Throws
* @user Administrator
* @Date 2016年1月20日
*/
private static Element getElementFromName(String name) {
String[] namesplit = name.split("\\.");
if (namesplit[namesplit.length - 1].endsWith(";")) {
namesplit[namesplit.length - 1] = namesplit[namesplit.length - 1].replace(';', 'S');
}
return new Element(namesplit[namesplit.length - 1]);
} public static String getCurrentTime(){
Calendar cal = Calendar.getInstance();
java.util.Date date = cal.getTime();
SimpleDateFormat sdFormat = new SimpleDateFormat("HHmmssSSS");
String myTime = sdFormat.format(date);
return myTime;
}
public static String getCurrentDate(){
Calendar cal = Calendar.getInstance();
java.util.Date date = cal.getTime();
SimpleDateFormat sdFormat = new SimpleDateFormat("yyyyMMdd");
String myTime = sdFormat.format(date);
return myTime;
}
public static String getCurrentDateMiles(){
Calendar cal = Calendar.getInstance();
java.util.Date date = cal.getTime();
SimpleDateFormat sdFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String myTime = sdFormat.format(date);
return myTime;
}
/**
* @Title getStrFromDoc
* @Description 从document生成xml
* @param document
* @return
* @throws IOException
* @Return String
* @Throws
* @user Administrator
* @Date 2016年1月20日
*/
public static String getStrFromDoc(Document document) throws IOException{
Format format = Format.getPrettyFormat();
format.setEncoding("GB2312");
XMLOutputter xmlout = new XMLOutputter(format);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
xmlout.output(document,bo);
String xmlStr = bo.toString();
return xmlStr;
}
}

后续有用到的基础类,再在新的文章中介绍。