如何实现第三方系统远程下载苍穹系统内单据附件字段的附件原创
金蝶云社区-陈来珍
陈来珍
2人赞赏了该文章 1333次浏览 未经作者许可,禁止转载编辑于2022年10月14日 14:28:50

关键词:OpenAPI2.0、附件字段、第三方系统、下载


一、需求

    苍穹平台内有一业务单据,业务单据中存在一个附件字段。需要实现第三方系统下载指定单据的附件字段的附件。

二、思路与方案

     第三方系统需要访问苍穹的信息,首先通过开放平台开放一个API接口,把单据的附件信息提供给第三方访问。然后通过登录苍穹系统,然后重定向到附件的下载地址,第三方系统下载苍穹附件的附件地址格式:

http://localhost:8080/ierp/accessTokenLogin.do?access_token=xxx&redirect=http://localhost:8080/ierp/attachment/download.do?path=xxxxx.pdf

读取到文件流下载附件到第三方系统。

三、实现过程

1、配置API查询接口,提供附件字段url的查询

image.png

2、模拟第三方系统下载苍穹附件的过程,创建main函数

public static void main(String[] args) {
		ThirdSysRemoteOperateAttachmentWithCosmic remoteOperateAtta = new ThirdSysRemoteOperateAttachmentWithCosmic();
		// 第一步:获取应用令牌,需在方法体内修改配置信息
		String appToken = AppLoginService.getService().getAppToken(URL_COSMICHOST);
		// 第二步:获取用户令牌,需在方法体内修改配置信息
		String accessToken = UserLoginService.getService().getAccessToken(URL_COSMICHOST, appToken);
		try {
			// 远程上传单据&附件
//			remoteOperateAtta.remoteSaveAttasToCosmic(accessToken);
			// 查询苍穹系统中指定单据上的所有附件信息
//			remoteOperateAtta.remoteGetAttasFromCosmic(accessToken);
			//第三步 调用苍穹API接口远程下载附件字段附件
			remoteOperateAtta.remoteDownloadAttFieldFromCosmic(accessToken);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

3、调用苍穹API接口查询并下载苍穹附件

private void remoteDownloadAttFieldFromCosmic(String accessToken) throws Exception {
		// 下载指定附件
		JSONArray allAttachments = this.remoteGetAttasFromCosmic(accessToken);
		for(int i=0;i<allAttachments.size();i++) {
			JSONObject jsonObj = allAttachments.getJSONObject(i);
			JSONArray attCol = jsonObj.getJSONArray("kded_attachmentfield");
			for (int j = 0; j < attCol.size(); j++) {
				JSONObject attfieldinfo = attCol.getJSONObject(j);
				 String url=attfieldinfo.getString("url");
				InputStream is = null;
				// 创建默认http客户端
				CloseableHttpClient httpClient = HttpClients.createDefault();
				// 采用默认请求配置
				RequestConfig requestConfig = RequestConfig.DEFAULT;
				
				//URL解密
				url = URLDecoder.decode(url, "utf-8");
				
				
				/**拼接的下载地址:先登录再重定向下载苍穹附件
				 * http://localhost:8080/ierp/accessTokenLogin.do?access_token=xxx&redirect=
				 * http://localhost:8080/ierp/attachment/download.do?path=xxxxx.pdf
				 */
				String redirectUrl="";
				if (url.contains("download.do?path=")) {
					redirectUrl=new StringBuilder().append(URL_COSMICHOST).append("accessTokenLogin.do?access_token=").append(accessToken).
							append("&encode=true&redirect=").append(url).toString();
				}else {//拼接下载地址
				 redirectUrl=new StringBuilder().append(URL_COSMICHOST).append("accessTokenLogin.do?access_token=").append(accessToken).
						append("&encode=true&redirect=").append(URL_COSMICHOST).append("attachment/download.do?path=").append(url).toString();
				}
				// 通过get方法下载文件流(url加密参数)
				String[] split = redirectUrl.split("path=");
				if (split.length>1) {
					String path = URLEncoder.encode(split[1], "utf-8");
					
					redirectUrl = new StringBuilder().append(split[0]).append("path=").append(path).toString();
				}
				/**
				 * 地址中涉及了特殊字符,如‘|’‘&’等。所以不能直接用String代替URI来访问。必须采用%0xXX方式来替代特殊字符。但这种办法不直观。所以只能先把String转成URL,
				 * 再通过URL生成URI的方法来解决问题,如下
				 */
                                URL uRL = new URL(redirectUrl);
				URI uri = new URI(uRL.getProtocol(),uRL.getHost(),uRL.getPath(),uRL.getQuery(),null);
				HttpGet request = new HttpGet(uri);
				// 设置请头求配置  
				request.setConfig(requestConfig);
				try {
					// 执行请求,接收返回信息
					CloseableHttpResponse httpResponse = httpClient.execute(request);
					// 获取执行状态
					int statusCode = httpResponse.getStatusLine().getStatusCode();
					if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_CREATED) {
						request.abort();
					} else {
						HttpEntity entity = httpResponse.getEntity();
						if (null != entity) {
							// 获取返回内容
							is = entity.getContent();
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
					request.abort();
				}
				// 本地存放位置
				StringBuffer path = new StringBuffer();
				//D:\lczdata
				path.append("D:\\lczdata\\").append(attfieldinfo.getString("name"));
				File file = new File(path.toString());
				if (!file.getParentFile().exists()) {
					file.getParentFile().mkdirs();
				}
				if (!file.exists()) {
					try {
						file.createNewFile();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				FileOutputStream fos = null;
				try {
					fos = new FileOutputStream(file);
					int bytes = 0;
					byte[] buffer = new byte[1024];
					while ((bytes = is.read(buffer)) != -1) {
						fos.write(buffer, 0, bytes);
					}
					System.out.println("文件下载成功!");
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					this.close(is);
					this.close(fos);
				}
			}
		}
		
	}

四、效果图

在方法att.thirdsys.ThirdSysRemoteOperateAttachmentWithCosmic.main(String[])中右健Debug As ->Java Application运行下载程序

image.png

五、开发环境版本

V5.0.002

六、注意事项

1. 如需复现样例效果,请注意按实际系统配置信息修改代码中相关变量参数。

2. 文章附件包含案例元数据补丁包、Java代码源码。解压之后请在MC中以更新补丁的形式将元数据压缩包导入平台里,Java代码放到本地开发工具(Eclipse/Idea)中,重启服务,运行代码即可查看效果,实际操作请查阅附件内的文档《操作步骤.doc》。

七、参考资料

开发平台

学习成长中心

如何实现第三方系统远程下载苍穹系统内指定单据附件面板的附件


赞 2