第三方系统上传单据&附件到苍穹原创
金蝶云社区-技术支持与赋能部_ZH
技术支持与赋能部_ZH
4人赞赏了该文章 2,582次浏览 未经作者许可,禁止转载编辑于2021年07月05日 15:23:19
summary-icon摘要由AI智能服务提供

本文档描述了一个Java类`RemoteOperationWithAttachment`,用于实现第三方系统远程上传单据及附件到苍穹系统的功能。类中定义了苍穹系统的访问地址、单据标识、应用标识等常量,并提供了主方法`main`用于测试上传流程。上传流程包括获取应用令牌(`appToken`)和用户访问令牌(`accessToken`),然后调用`remoteSaveWithAttachments`方法上传文件及单据数据。该方法中,首先上传文件到苍穹系统,然后封装单据数据并调用业务保存接口。上传结果通过解析返回的JSON字符串来判断是否成功,并输出相应信息。此外,还提供了`AppLoginService`和`UserLoginService`类用于获取应用和用户令牌。

标签:第三方系统,文件上传

实现方案:


/**

 * 第三方系统远程上传单据&附件到苍穹系统

 * 

 */

public class RemoteOperationWithAttachment {

     // 苍穹系统访问地址,需修改

     private static final String REMOTEHOST = "http://127.0.0.1:8080/ierp";

    

     // 苍穹系统中,对应单据的标识,需修改

     private static final String FORMID = "kded_document";

    

     // 苍穹系统中,对应单据所属应用的标识,需修改

     private static final String APPID = "kded_apps";

    

     /**

     * 测试入口

     *

     */

     public static void main(String[] args) {

         RemoteOperationWithAttachment remoteOperation = new RemoteOperationWithAttachment();

         // 获取连接信息,需修改(在方法体内)

         String appToken = AppLoginService.getService().getAppToken(REMOTEHOST);

         String accessToken = UserLoginService.getService().getAccessToken(REMOTEHOST, appToken);

         // 远程上传单据&附件

        // try {

                remoteOperation.remoteSaveWithAttachments (accessToken);

        // } catch (Exception e) {

                  e.printStackTrace();

        // }

        

     }

    

     /**

     * 远程上传单据&附件到苍穹系统

     * 参考资料:https://www.cnblogs.com/zwqh/p/9635176.html

     *        https://blog.csdn.net/zzq900503/article/details/72920914/

    

     */

     private void remoteSaveWithAttachments(String accessToken) throws Exception {

                 // 第三方系统中待上传到苍穹系统的文件,需修改

                 File file = new File("E:\\test.txt");

                 // 上传可能需要传的参数

                        Map<String, Object> param = new HashMap<String, Object>();      

                        String responseStr = null;

                        JSONObject responseJson = null;

                 String url = REMOTEHOST + "/attachment/uploadFile.do";

                 // 上传文件

                 responseStr = FileUploadService.getService().postFile(url, param, file, accessToken);

                 // 封装第三方系统中待上传到苍穹系统的单据数据

                 Map<String, Object> formData = new HashMap<String, Object>();

                 // 单据标识符,需修改(苍穹系统中需要该参数,如第三方系统没有该参数,可自行新建,格式:开发商标识符+单据名称,英文或者数字,附:开发商标识符可在苍穹系统中查询到)

                 formData.put("formId", FORMID);

                 formData.put("appId", APPID);

                 formData.put("fileName", file.getName());

                 formData.put("fileSize", file.length());

                 formData.put("description", "");

                 formData.put("bizType", "upload");

                 // 单据数据,按实际业务自行修改

                 formData.put("billno", "test20210705");

                 formData.put("billstatus", "B");

                 formData.put("desc", "测试");

                 formData.put("qtyfield1", "12");

                 responseStr = BizOperateService.getService().BizSave(REMOTEHOST, accessToken, formData, responseStr, null);

                 responseJson = JSONObject.parseObject(responseStr);

                 Boolean success = Boolean.valueOf(responseJson.getString("success"));

                 if (success) {

                         System.out.println("上传成功!");

                 } else {

                         String message = responseJson.getJSONObject("data").getString("message");

                         throw new Exception(message);

                 }

         }

}





/*

 * 获取APPTOKEN

 */

public class AppLoginService {

     private static final String path  = "/api/getAppToken.do";

     private static final AppLoginService service = new AppLoginService();

     private AppLoginService() {}

    

     //静态工厂方法   

        public static AppLoginService getService() {  

            return service;

        }

        

        public String getAppToken(String REMOTEHOST) {

                //获取APPTOKEN

             String url = REMOTEHOST + path;

             // appId & appSecuret & tenantid & accountId 需修改

             String data = "{\"appId\": \"EAS\""

             + ",\"appSecuret\": \"123456\""

             + ",\"tenantid\": \"ierp\""

             + ",\"accountId\": \"1557233840063393244\""

             + ",\"language\": \"zh_CN\"}";

             String responseStr = null;

             try {

                 responseStr = HttpService.getService().doPostByHttpClient(url, data);

             } catch (Exception e) {

                 e.printStackTrace();

             }

             JSONObject json  = JSONObject.parseObject(responseStr);

             String appToken  = json.getJSONObject("data").getString("app_token");

             return appToken;

        }   

}




public class UserLoginService {

    

     private static final String path = "/api/login.do";

     private UserLoginService() {}

    

        private static final UserLoginService service = new UserLoginService();

        

        //静态工厂方法   

        public static UserLoginService getService()  {  

            return service;  

        }

        

     public String getAccessToken(String REMOTEHOST, String appToken) {

             //获取用户token

             String url = REMOTEHOST + path;

             // user & tenantid & accountId 需修改

             String data = "{\"user\": \"17299999999\""

             + ",\"apptoken\": \""+appToken+"\""

             + ",\"tenantid\": \"ierp\""

             + ",\"accountId\": \"1557233840063393244\""

             + ",\"usertype\": \"Mobile\"}";

             String responseStr = null;

             try {

                 responseStr = HttpService.getService().doPostByHttpClient(url, data);

             } catch (Exception e) {

                 e.printStackTrace();

             }

             JSONObject json  = JSONObject.parseObject(responseStr);

             String accessToken  = json.getJSONObject("data").getString("access_token");

             return accessToken;

     }

}




public class FileUploadService {

     private static final FileUploadService service = new FileUploadService();

    

     private static final String BOUNDARY = "----WebKitFormBoundaryBHp47SjGMxpHX0X6--";

    

     private FileUploadService() {}

    

     //静态工厂方法

     public static FileUploadService getService() {

     return service;

     }

    

     public String postFile(String url, Map<String, Object> param, File file, String accessToken) throws Exception {

             HttpPost httppost = new HttpPost(url);

             httppost.addHeader("api", "true");

             httppost.addHeader("accessToken", accessToken);

             //设置boundary,文件解析用

             httppost.addHeader("Content-Type",  "multipart/form-data; boundary="+BOUNDARY);

             MultipartEntity entry = this.getMutipartEntry(param, file);

             httppost.setEntity(entry);

             return HttpService.getService().doExecuteByHttpClient(httppost, new ResponseHandler<String>() {

                         @Override

                         public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {

                                 HttpEntity entity = response.getEntity();

                                 String  rtn =  EntityUtils.toString(entity, "UTF-8");

                                 JSONObject json  = JSONObject.parseObject(rtn);

                                 String url  = json.getString("url");

                                 return url;

                         }

                });

     }

        

        private MultipartEntity getMutipartEntry(Map<String, Object> param, File file) 

     throws UnsupportedEncodingException, FileNotFoundException {

                if (file == null) {

                            throw new IllegalArgumentException("文件不能为空");

                    }

                    MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, BOUNDARY, Charset.forName("UTF-8"));

                    multipartEntity.addPart("file", new InputStreamBody(new FileInputStream(file), file.getName()));

                    if (param != null) {

                            Iterator<String> iterator = param.keySet().iterator();

                            while (iterator.hasNext()) {

                                    String key = iterator.next();

                                    FormBodyPart field = new FormBodyPart(key, new StringBody((String) param.get(key)));

                                    multipartEntity.addPart(field);

                            }

                    }

                    return multipartEntity;

        }

}




public class BizOperateService {

         private static final BizOperateService service = new BizOperateService();

         private static final String relativePath = "/kapi/app/sys/BizCustomSave";

         private BizOperateService() {}

        

            //静态工厂方法   

            public static BizOperateService getService() {  

                return service;  

            } 

            

            /**

             * 远程上传单据数据 & 附件文件到苍穹系统

             * @param remotehost 苍穹系统访问地址

             * @param accessToken

             * @param formData 单据数据

             * @param attchmentsUrl 附件在苍穹系统中的保存地址

             * @param attchmentpanles 第三方系统中附件面板的标识,如无可传null

             * @return

             * @throws URISyntaxException

             */

            public String BizSave(String remotehost, String accessToken, Map<String, Object> formData, String attchmentsUrl, List<String> attchmentpanles) 

            throws URISyntaxException {

                         List<String> attchmentsUrlList = new ArrayList<String>();

                         attchmentsUrlList.add(attchmentsUrl);

                         // 默认一个附件面板

                            attchmentpanles = (attchmentpanles == null) ? new ArrayList<String>() : attchmentpanles;

                            if (attchmentpanles.size() == 0) {

                                    attchmentpanles.add("attachmentpanel");

                            }

                            // 自定义开放平台接口路径

                            String url = remotehost + relativePath;

                            // 附件信息

                            Map<String, Object> attachmentInfo = new HashMap<String, Object>();

                            List<Map<String, Object>> attachments = null;

                            Map<String, Object> attachment = null;

                            StringBuffer uid = new StringBuffer("rc-upload-");

                            uid.append(new Date().getTime());

                             uid.append("-");

                             int index = (int) (1 + Math.random()*10);

                            // 多个附件面板

                            for (String tempattchmentpanle : attchmentpanles) {

                                    attachments = new ArrayList<Map<String, Object>>();

                                    // 多个附件

                                    for (String attchmentUrl : attchmentsUrlList) {

                                                attachment = new HashMap<String, Object>();

                                                attachment.put("name", formData.get("fileName"));

                                                attachment.put("url", attchmentUrl);

                                                uid.append(index);

                                                attachment.put("uid", uid);

                                                index++;

                                                attachment.put("size", formData.get("fileSize"));

                                                attachment.put("description", formData.get("description"));

                                                attachments.add(attachment);

                                    }

                                    attachmentInfo.put(tempattchmentpanle, attachments);

                            }

                            // 封装数据

                            JSONObject body = new JSONObject();

                            body.put("accessToken", accessToken);

                            body.put("bizObject", formData);

                            body.put("attachmentInfo", attachmentInfo);

                             String responseStr = null;

                             try {

                                     responseStr = HttpService.getService().doGetByHttpClient(url, body);

                             } catch (Exception e) {

                                     e.printStackTrace();

                             }

                             return responseStr;

            }

}

    





public class HttpService {

         private static final HttpService service = new HttpService();

        

         private HttpService() {}

        

         // 静态工厂方法

         public static HttpService getService() {

             return service;

         }

        

         /**

         * POST方式发送请求

         * @param url

         * @param data

         * @return

         * @throws Exception

         */

         public String doPostByHttpClient(String url, String data) throws Exception {

                 StringEntity se = new StringEntity(data, "UTF-8");

                 se.setContentType("text/json");

                 se.setContentEncoding(new BasicHeader("Content-Type", "application/json; charset=UTF-8"));

                 HttpPost httpPost = new HttpPost(url);

                 httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");

                 httpPost.setEntity(se);

                 return doExecuteByHttpClient(httpPost,new ResponseHandler<String>() {

                 @Override

                 public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {

                 int statusCode = response.getStatusLine().getStatusCode();

                 if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_CREATED) {

                 try {

                 throw new Exception("连接服务器发生错误!");

                 } catch (Exception e) {

                 e.printStackTrace();

                 }

                 }

                 return EntityUtils.toString(response.getEntity());

                 }

                 });

         }

        

         public <T> T doExecuteByHttpClient(HttpUriRequest httpPost, ResponseHandler<? extends T> responseHandler) throws Exception {

                 try {

                 CloseableHttpClient httpClient = HttpClientFactory.getHttpClient();

                 T rtn = httpClient.execute(httpPost, responseHandler);

                 return rtn;

                 } catch (Exception e) {

                 e.printStackTrace();

                 System.out.println(" ===== doPostByHttpClient() ERROR ===== ");

                 throw new Exception(e.getMessage());

                 } finally {

                 System.clearProperty("javax.net.debug");

                 }

         }

        

         /**

         * GET方式发送请求

         * @param url

         * @param param

         * @return

         * @throws Exception

         */

         public String doGetByHttpClient(String url, JSONObject param) throws Exception {

                 URIBuilder builder = new URIBuilder(url);

                 if (param != null) {

                 builder.addParameter("body", param.toJSONString());

                 }

                 URI uri = builder.build();

                 HttpGet httpGet = new HttpGet(uri);

                 return doExecuteByHttpClient(httpGet, new ResponseHandler<String>() {

                 @Override

                 public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {

                 int statusCode = response.getStatusLine().getStatusCode();

                 if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_CREATED) {

                 try {

                 throw new Exception("连接服务器发生错误!");

                 } catch (Exception e) {

                 e.printStackTrace();

                 }

                 }

                 return EntityUtils.toString(response.getEntity());

                 }

                 });

         }

}





/*

 * 高并发HttpClient

 */

public class HttpClientFactory {


         private static CloseableHttpClient httpClient ;

        

         public static CloseableHttpClient getHttpClient() throws InstantiationException, IllegalAccessException 

         {

                 if(httpClient == null ) {

                 synchronized (HttpClientFactory.class) 

                 {

                 if(httpClient == null) {

                 httpClient = create();

                 }

                 }

                 }

                 return httpClient;

         }

        

         private static CloseableHttpClient create() {

             ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {

                 @Override

                 public long getKeepAliveDuration(HttpResponse response, HttpContext context) {

                     HeaderElementIterator it = new BasicHeaderElementIterator

                         (response.headerIterator(HTTP.CONN_KEEP_ALIVE));

                     while (it.hasNext()) {

                         HeaderElement he = it.nextElement();

                         String param = he.getName();

                         String value = he.getValue();

                         if (value != null && param.equalsIgnoreCase

                            ("timeout")) {

                             return Long.parseLong(value) * 1000;

                         }

                     }

                     return 60 * 1000;//如果没有约定,则默认定义时长为60s

                 }

             };

             // 配置一个PoolingHttpClientConnectionManager

             PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();

             connectionManager.setMaxTotal(500);

             connectionManager.setDefaultMaxPerRoute(50);//例如默认每路由最高50并发,具体依据业务来定

            

             //设置一个线程隔一段时间关闭超时连接

             IdleConnectionMonitorThread thread  = new IdleConnectionMonitorThread(connectionManager);

             thread.start();

             CloseableHttpClient httpClient = HttpClients.custom()

                            .setConnectionManager(connectionManager)

                            .setKeepAliveStrategy(myStrategy)

                            .setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true).build())

                            .build();

             HttpParams params = new BasicHttpParams();

             //设置连接超时时间

             Integer CONNECTION_TIMEOUT = 2 * 1000; //设置请求超时2秒钟 根据业务调整

             Integer SO_TIMEOUT = 2 * 1000; //设置等待数据超时时间2秒钟 根据业务调整

            

             //定义了当从ClientConnectionManager中检索ManagedClientConnection实例时使用的毫秒级的超时时间

             //这个参数期望得到一个java.lang.Long类型的值。如果这个参数没有被设置,默认等于CONNECTION_TIMEOUT,因此一定要设置。

             Long CONN_MANAGER_TIMEOUT = 500L; //在httpclient4.2.3中我记得它被改成了一个对象导致直接用long会报错,后来又改回来了

              

             params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIMEOUT);

             params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SO_TIMEOUT);

             params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, CONN_MANAGER_TIMEOUT);

             //在提交请求之前 测试连接是否可用

             params.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, true);

              

             //另外设置http client的重试次数,默认是3次;当前是禁用掉(如果项目量不到,这个默认即可)

            // httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false));

             return httpClient;

         }

        

         public static class IdleConnectionMonitorThread extends Thread {     

                 private final HttpClientConnectionManager connMgr;

                 private volatile boolean shutdown;

                 

                 public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {

                     super();

                     this.connMgr = connMgr;

                 }

                 @Override

                 public void run() {

                     try {

                         while (!shutdown) {

                             synchronized (this) {

                                 wait(5000);

                                 // Close expired connections

                                 connMgr.closeExpiredConnections();

                                 // Optionally, close connections

                                 // that have been idle longer than 30 sec

                                 connMgr.closeIdleConnections(30, TimeUnit.SECONDS);

                             }

                         }

                     } catch (InterruptedException ex) {

                         // terminate

                     }

                 }

                 

                 public void shutdown() {

                     shutdown = true;

                     synchronized (this) {

                         notifyAll();

                     }

                 }

                 

         }

}


图标赞 4
4人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!