关键词:流程启动,通过服务启动流程,服务集成,系统集成,服务包装

O2OA允许用户自行修改源码或者增加源码来扩展系统服务,也可以包装功能更强的业务服务。本文主要介绍如何在Java代码中通过接口从第三方应用系统启动O2OA中的业务流程(通过第三方调用启动流程)

总体思络: 先用户单点获取token(因为创建流程、上传附件接口需要身份认证),接着创建流程,然后上传附件到流程实例。

一、完整样例代码

代码如下:

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class HttpClientUtil {
public static final int THREAD_POOL_SIZE = 5;
public interface HttpClientDownLoadProgress {
	public void onProgress(int progress);
}
private static HttpClientUtil httpClientDownload;
private ExecutorService downloadExcutorService;
private HttpClientUtil() {
	downloadExcutorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
}
public static HttpClientUtil getInstance() {
	if (httpClientDownload == null) {
		httpClientDownload = new HttpClientUtil();
	}
	return httpClientDownload;
}

/**
 * @param url
 * @param filePath
 */
public void download(final String url, final String filePath) {
	downloadExcutorService.execute(new Runnable() {
		@Override
		public void run() {
			httpDownloadFile(url, filePath, null, null);
		}
	});
}

/**
 *
 * @param url
 * @param filePath
 * @param progress
 */
public void download(final String url, final String filePath, final HttpClientDownLoadProgress progress) {
	downloadExcutorService.execute(new Runnable() {

		@Override
		public void run() {
			httpDownloadFile(url, filePath, progress, null);
		}
	});
}

/**
 * @param url
 * @param filePath
 */
private void httpDownloadFile(String url, String filePath, HttpClientDownLoadProgress progress,
		Map<String, String> headMap) {
	CloseableHttpClient httpclient = HttpClients.createDefault();
	try {
		HttpGet httpGet = new HttpGet(url);
		setGetHead(httpGet, headMap);
		CloseableHttpResponse response1 = httpclient.execute(httpGet);
		try {
			System.out.println(response1.getStatusLine());
			HttpEntity httpEntity = response1.getEntity();
			long contentLength = httpEntity.getContentLength();
			InputStream is = httpEntity.getContent();

			ByteArrayOutputStream output = new ByteArrayOutputStream();
			byte[] buffer = new byte[4096];
			int r = 0;
			long totalRead = 0;
			while ((r = is.read(buffer)) > 0) {
				output.write(buffer, 0, r);
				totalRead += r;
				if (progress != null) {
					progress.onProgress((int) (totalRead * 100 / contentLength));
				}
			}
			FileOutputStream fos = new FileOutputStream(filePath);
			output.writeTo(fos);
			output.flush();
			output.close();
			fos.close();
			EntityUtils.consume(httpEntity);
		} finally {
			response1.close();
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		try {
			httpclient.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

/**
 * @param url
 * @return
 */
public String httpGet(String url) {
	return httpGet(url, null);
}

/**
 * http get
 *
 * @param url
 * @return
 */
public String httpGet(String url, Map<String, String> headMap) {
	String responseContent = null;
	CloseableHttpClient httpclient = HttpClients.createDefault();
	try {
		HttpGet httpGet = new HttpGet(url);
		CloseableHttpResponse response1 = httpclient.execute(httpGet);
		setGetHead(httpGet, headMap);
		try {
			HttpEntity entity = response1.getEntity();
			responseContent = getRespString(entity);
			EntityUtils.consume(entity);
		} finally {
			response1.close();
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		try {
			httpclient.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	return responseContent;
}

public String httpPost(String url, Map<String, String> paramsMap) {
	return httpPost(url, paramsMap, null);
}

/**
 * @param url
 * @param paramsMap
 * @return
 */
public String httpPost(String url, Map<String, String> paramsMap, Map<String, String> headMap) {
	String responseContent = null;
	CloseableHttpClient httpclient = HttpClients.createDefault();
	try {
		HttpPost httpPost = new HttpPost(url);
		setPostHead(httpPost, headMap);
		setPostParams(httpPost, paramsMap);
		CloseableHttpResponse response = httpclient.execute(httpPost);
		try {
			HttpEntity entity = response.getEntity();
			responseContent = getRespString(entity);
			EntityUtils.consume(entity);
		} finally {
			response.close();
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		try {
			httpclient.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	return responseContent;
}

/**
 * @param httpPost
 * @param headMap
 */
private void setPostHead(HttpPost httpPost, Map<String, String> headMap) {
	if (headMap != null && headMap.size() > 0) {
		Set<String> keySet = headMap.keySet();
		for (String key : keySet) {
			httpPost.addHeader(key, headMap.get(key));
		}
	}
}

/**
 * 
 *
 * @param httpGet
 * @param headMap
 */
private void setGetHead(HttpGet httpGet, Map<String, String> headMap) {
	if (headMap != null && headMap.size() > 0) {
		Set<String> keySet = headMap.keySet();
		for (String key : keySet) {
			httpGet.addHeader(key, headMap.get(key));
		}
	}
}

/**
 *
 *
 * @param serverUrl       ַ
 * @param localFilePath
 * 
 * @param serverFieldName
 * @param params
 * @return
 * @throws Exception
 */
public String uploadFileImpl(String serverUrl, String localFilePath, String serverFieldName,
		Map<String, String> params, Map<String, String> paramshead) throws Exception {
	String respStr = null;
	CloseableHttpClient httpclient = HttpClients.createDefault();
	try {
		HttpPost httppost = new HttpPost(serverUrl);

		setPostHead(httppost, paramshead);

		FileBody binFileBody = new FileBody(new File(localFilePath));

		MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();

		multipartEntityBuilder.addPart(serverFieldName, binFileBody);

		setUploadParams(multipartEntityBuilder, params);

		HttpEntity reqEntity = multipartEntityBuilder.build();
		httppost.setEntity(reqEntity);

		CloseableHttpResponse response = httpclient.execute(httppost);
		try {
			HttpEntity resEntity = response.getEntity();
			respStr = getRespString(resEntity);
			EntityUtils.consume(resEntity);
		} finally {
			response.close();
		}
	} finally {
		httpclient.close();
	}
	return respStr;
}

/**
 * @param multipartEntityBuilder
 * @param params
 */
private void setUploadParams(MultipartEntityBuilder multipartEntityBuilder, Map<String, String> params) {
	if (params != null && params.size() > 0) {
		Set<String> keys = params.keySet();
		for (String key : keys) {
			multipartEntityBuilder.addPart(key, new StringBody(params.get(key), ContentType.APPLICATION_JSON));

		}
	}
}

/**
 * String
 *
 * @param entity
 * @return
 * @throws Exception
 */
private String getRespString(HttpEntity entity) throws Exception {
	if (entity == null) {
		return null;
	}
	InputStream is = entity.getContent();
	StringBuffer strBuf = new StringBuffer();
	byte[] buffer = new byte[4096];
	int r = 0;
	while ((r = is.read(buffer)) > 0) {
		strBuf.append(new String(buffer, 0, r, "UTF-8"));
	}
	return strBuf.toString();
}

/**
 * @param httpPost
 * @param paramsMap
 * @throws Exception
 */
private void setPostParams(HttpPost httpPost, Map<String, String> paramsMap) throws Exception {
	if (paramsMap != null && paramsMap.size() > 0) {
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		Set<String> keySet = paramsMap.keySet();
		for (String key : keySet) {
			nvps.add(new BasicNameValuePair(key, paramsMap.get(key)));
		}
		httpPost.setEntity(new UrlEncodedFormEntity(nvps));
	}
}

public static String sendPost(String url, String token, String paramsStr) throws IOException, Exception {

	// POST请求
	CloseableHttpClient httpclient = HttpClients.createDefault();

	// 请求参数
	StringEntity postingString = new StringEntity(paramsStr, "utf-8");
	HttpPost httpPost = new HttpPost(url);
	httpPost.setEntity(postingString);

	// 请求头设置
	httpPost.addHeader("Cookie", "x-token=" + token);
	httpPost.addHeader("accept", "*/*");
	httpPost.addHeader("connection", "Keep-Alive");
	httpPost.addHeader("Content-Type", "application/json; charset=utf-8");
	httpPost.addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

	// 执行请求
	CloseableHttpResponse execute = httpclient.execute(httpPost);

	// 处理返回结果
	String restStr = IOUtils.toString(execute.getEntity().getContent(), "utf-8");
	return restStr;
}

public static String sendPost(String url, String param) {
	PrintWriter out = null;
	BufferedReader in = null;
	String result = "";
	try {
		URL realUrl = new URL(url);
		URLConnection conn = realUrl.openConnection();
		conn.setRequestProperty("accept", "*/*");
		conn.setRequestProperty("connection", "Keep-Alive");
		conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
		conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
		conn.setDoOutput(true);
		conn.setDoInput(true);

		out = new PrintWriter(conn.getOutputStream());
		out.print(param);
		out.flush();
		in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		String line;
		while ((line = in.readLine()) != null) {
			result += line;
		}
	} catch (Exception e) {
		System.out.println(" POST" + e);
		e.printStackTrace();
	} finally {
		try {
			if (out != null) {
				out.close();
			}
			if (in != null) {
				in.close();
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
	return result;
}

public static void main(String[] args) throws IOException, Exception {
	String token = "";
	// 第一步:单点登入
	String path = "http://127.0.0.1:20020/x_organization_assemble_authentication/jaxrs/sso"; // 单点路径
	long time = new Date().getTime(); // 当前时间
	String login_uid = "kfry"; // 用户id
	String sso_key = "12345678"; // 加密密码
	String xtoken = null;
	String client = "sso"; // sso配置名称
	try {
		xtoken = Crypto.encrypt(login_uid + "#" + time, sso_key);
		System.out.println(xtoken);
	} catch (Exception e1) {
		e1.printStackTrace();
	}

	String string = "{\"token\": " + xtoken + ", \"client\": " + client + "}";
	String str = HttpClientUtil.getInstance().sendPost(path, string);
	JsonParser parser = new JsonParser();
	JsonObject object = null;
	object = (JsonObject) parser.parse(str);
	JsonObject value = object.get("data").getAsJsonObject();
	token = value.get("token").getAsString();

	// 第二步:创建流程
	String processId = "e4c77038-2964-498f-9d37-1635e26639eb";// 流程id
	path = "http://127.0.0.1:20020/x_processplatform_assemble_surface/jaxrs/work/process/"+processId;// 流程创建路径
	String datagrid = "{\"data\": [{" + "      "
			+ "   \"col1\": { \"textfield1\": \"1\" },"
			+ "         \"col2\": { \"textfield2\": \"2\" }," 
			+ "         \"col3\": { \"textfield3\": \"3\" },"
			+ "         \"col4\": { \"textfield4\": \"4\" },"
			+ "         \"col5\": { \"textfield5\": \"5\" }"
			+ "     }," + "     {"
			+ "         \"col1\": { \"textfield1\": \"11\" },"
			+ "         \"col2\": { \"textfield2\": \"12\" }," 
			+ "         \"col3\": { \"textfield3\": \"13\" },"
			+ "         \"col4\": { \"textfield4\": \"14\" }," 
			+ "         \"col5\": { \"textfield5\": \"15\" }"
			+ "     }]}"; // 数据网格数据

	JsonParser parser1 = new JsonParser();
	JsonObject jsonObj = parser1.parse(datagrid).getAsJsonObject();

	JsonObject jsonObject = new JsonObject();
	jsonObject.addProperty("latest", false);
	jsonObject.addProperty("title", "演示系统grid测试(2021-02-22)");// 标题
	jsonObject.addProperty("identity", "开发人员@932ca9a4-4c80-4a29-9e44-aed85afe21d3@I"); // 创建者身份

	JsonObject jsonObjectdata = new JsonObject();
	jsonObjectdata.addProperty("subject", "演示系统grid测试2021-02-22"); // 标题
	jsonObjectdata.addProperty("calendar", "2020-04-13 12:00:00");// 表单 上的字段名“calendar”
	jsonObjectdata.addProperty("explain", "演示系统grid测试"); // 表单 上的字段名“explain”
	jsonObjectdata.add("datagrid", jsonObj); // 表单上的数据网格

	jsonObject.add("data", jsonObjectdata);
	// 创建流程
	String strflow = HttpClientUtil.getInstance().sendPost(path, token, jsonObject.toString());
	String work = "";

	// 获取返回的workid
	JsonParser parser2 = new JsonParser();
	JsonObject object2 = null;
	object2 = (JsonObject) parser2.parse(strflow);
	JsonArray value2 = object2.getAsJsonArray("data");
	object2 = value2.get(0).getAsJsonObject();
	work = object2.get("work").getAsString();

	System.out.println("work=" + work);

	// 上传附件
	try {
		Map<String, String> uploadParams = new LinkedHashMap<String, String>();
		uploadParams.put("fileName", "明天.docx"); // 附件名
		uploadParams.put("site", "attachment"); // 表单上的附件控件标识
		uploadParams.put("extraParam", "");

		Map<String, String> headMap = new HashMap<String, String>();
		headMap.put("Cookie", "x-token=" + token); // 单点token
		headMap.put("accept", "*/*");
		headMap.put("connection", "Keep-Alive");
		headMap.put("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

		String attUrl = "http://127.0.0.1:20020/x_processplatform_assemble_surface/jaxrs/attachment/upload/work/"
				+ work;
		String filePath = "F:\\Download\\明天.docx";
		HttpClientUtil.getInstance().uploadFileImpl(attUrl, filePath, "file", uploadParams, headMap);
	} catch (Exception e) {
		e.printStackTrace();
	}
}
}

二、功能代码介绍

第一步:单点登入

一、创建SSO配置,请参考组织管理里中的SSO管理

二、通过下面代码获取token.

注意:下面代码中要调整的内容如下:
“path”:单点路径要根据实际服务器ip调整;

“login_uid”:单点用户id;

“sso_key”:加密解密密码;

“client”:sso配置名称;

       String token = "";
        //第一步:单点登入
        String path = "http://127.0.0.1:20020/x_organization_assemble_authentication/jaxrs/sso"; //单点路径
        long time = new Date().getTime(); //当前时间
        String login_uid = "kfry"; //用户id
        String sso_key = "12345678"; //加密密码
        String xtoken = null;
        String client = "sso"; //sso配置名称
		try {
			xtoken = Crypto.encrypt( login_uid + "#" + time, sso_key );
			System.out.println(xtoken);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		
        String string = "{\"token\": "+xtoken+", \"client\": " + client + "}";
        String  str =  HttpClientUtil.getInstance().sendPost(path,string);
        JsonParser parser = new JsonParser(); 
        JsonObject object = null; 
        object =(JsonObject) parser.parse(str);
        JsonObject value =object.get("data").getAsJsonObject();
        token= value.get("token").getAsString();


第二步:创建流程

一、设置x-token

注意:下面代码中要调整的内容如下:

“processId”: 流程id;

“path”:创建流程路径要根据实际服务器ip调整;

“title”:标题;

“identity”:创建者身份;

subject”:标题;

......
// 第二步:创建流程
		String processId = "e4c77038-2964-498f-9d37-1635e26639eb";// 流程id
		path = "http://127.0.0.1:20020/x_processplatform_assemble_surface/jaxrs/work/process/";// 流程创建路径
		String datagrid = "{\"data\": [{" + "      "
				+ "   \"col1\": { \"textfield1\": \"1\" },"
				+ "         \"col2\": { \"textfield2\": \"2\" }," 
				+ "         \"col3\": { \"textfield3\": \"3\" },"
				+ "         \"col4\": { \"textfield4\": \"4\" },"
				+ "         \"col5\": { \"textfield5\": \"5\" }"
				+ "     }," + "     {"
				+ "         \"col1\": { \"textfield1\": \"11\" },"
				+ "         \"col2\": { \"textfield2\": \"12\" }," 
				+ "         \"col3\": { \"textfield3\": \"13\" },"
				+ "         \"col4\": { \"textfield4\": \"14\" }," 
				+ "         \"col5\": { \"textfield5\": \"15\" }"
				+ "     }]}"; // 数据网格数据

		JsonParser parser1 = new JsonParser();
		JsonObject jsonObj = parser1.parse(datagrid).getAsJsonObject();

		JsonObject jsonObject = new JsonObject();
		jsonObject.addProperty("latest", false);
		jsonObject.addProperty("title", "演示系统grid测试(2021-02-22)");// 标题
		jsonObject.addProperty("identity", "开发人员@932ca9a4-4c80-4a29-9e44-aed85afe21d3@I"); // 创建者身份

		JsonObject jsonObjectdata = new JsonObject();
		jsonObjectdata.addProperty("subject", "演示系统grid测试2021-02-22"); // 标题
		jsonObjectdata.addProperty("calendar", "2020-04-13 12:00:00");// 表单 上的字段名“calendar”
		jsonObjectdata.addProperty("explain", "演示系统grid测试"); // 表单 上的字段名“explain”
		jsonObjectdata.add("datagrid", jsonObj); // 表单上的数据网格

		jsonObject.add("data", jsonObjectdata);
		// 创建流程
		String strflow = HttpClientUtil.getInstance().sendPost(path, token, jsonObject.toString());
		String work = "";

		// 获取返回的workid
		JsonParser parser2 = new JsonParser();
		JsonObject object2 = null;
		object2 = (JsonObject) parser2.parse(strflow);
		JsonArray value2 = object2.getAsJsonArray("data");
		object2 = value2.get(0).getAsJsonObject();
		work = object2.get("work").getAsString();
......


第三步:上传附件

一、设置x-token

二、设置workid

注意:下面代码中要调整的内容如下:

“fileName”:附件名

“site”:表单上的附件控件标识

filePath”:附件路径

“attUrl”:附件接口要根据实际服务器ip调整

	// 上传附件
		try {
			Map<String, String> uploadParams = new LinkedHashMap<String, String>();
			uploadParams.put("fileName", "明天.docx"); // 附件名
			uploadParams.put("site", "attachment"); // 表单上的附件控件标识
			uploadParams.put("extraParam", "");

			Map<String, String> headMap = new HashMap<String, String>();
			headMap.put("Cookie", "x-token=" + token); // 单点token
			headMap.put("accept", "*/*");
			headMap.put("connection", "Keep-Alive");
			headMap.put("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

			String attUrl = "http://127.0.0.1:20020/x_processplatform_assemble_surface/jaxrs/attachment/upload/work/"
					+ work;
			String filePath = "F:\\Download\\明天.docx";
			HttpClientUtil.getInstance().uploadFileImpl(attUrl, filePath, "file", uploadParams, headMap);
		} catch (Exception e) {
			e.printStackTrace();
		}

推荐文章:

系统配置-配置服务器连接O2云(V6.3后)
2021-09-13
@O2OA@开源办公系统@手机办公@O2云 @连接O2云O2OA拥有云端应用市场以及配套的移动办公APP,支持IOS和安卓端。用户可在连接O2云之后,使用APP
系统配置-平台数据库配置信息样例
2021-11-25
@平台部署@O2OA@开源办公系统@数据库连接配置@数据库连接串@数据库配置O2OA开发平台支持大多数主流的数据库以及国产数据库,用户可以进行相应的第三方数据库
开发知识-人大金仓数据安装
2021-02-07
一、安装程序  1、在安装前要创建一个帐号,不能用root帐号安装。  2、安装执行./setup.sh -iconsole    3、接受“此许可协议条款”,
办公中心
2021-02-19
O2OA办公中心用于查阅您您待办或已办事项,发起新的流程任务等,您也可以在系统首页完成相关的操作。
开发知识-Vue篇:在Vue应用中集成O2OA
2021-12-01
  在前面的章节中,我们介绍了两种在O2OA中使用Vue开发应用的方式,已经可以满足绝大多数的情况了。如果您考虑完全脱离O2的web服务器,自己搭建web服务器
流程设计-流程表单的创建与设计
2021-02-26
本文主要介绍如何在O2OA中进行审批流程表单或者工作流表单设计,O2OA主要采用拖拽可视化开发的方式完成流程表单的设计和配置,不需要过多的代码编写,业务人员可以
系统安全-加密登录-登录密码RSA加密
2021-08-31
@系统安全@O2OA@登录密码@密码加密@RSA加密为增加系统和用户的安全性,平台支持对用户的登录密码进行RSA加密。本篇主要介绍如何将在O2OA中开启登录密码
平台维护-流转中工作数据的查询、操作和管理
2021-02-26
O2OA提供平台数据维护应用,用于对平台应用类数据的维护操作,用户可以在应用市场选择安装平台维护应用。本篇主要简单介绍流转中工作数据的查询、操作和管理功能。
信息栏目-新建信息发布流程
2022-03-01
@信息管理@内容管理@信息发布@信息流程@信息发布流程O2OA提供的信息管理功能可以帮助用户快速地配置信息发布栏目,如通知公告,公司动态,规章制度等。用户可以高
移动办公-将O2OA接入到微信公众号
2022-02-21
@移动办公@O2OA微信办公@微信公众号办公@微信办公@手机办公O2OA平台拥有配套的原生开发的安卓和IOS移动APP,目前O2OA已经支持微信公众号的集成,用

results matching ""

    No results matching ""